Austria Quickstart
This quickstart walks you through the essential steps to sign your first RKSV-compliant receipt with fiskaly SIGN AT.
Prerequisites
Section titled “Prerequisites”- A fiskaly account with an Austrian organization (sign up at HUB)
- An API Key and Secret generated in the TEST environment
- FinanzOnline “Cash Register Webservice User” credentials from your taxpayer
Your API Secret is shown only once. Store it immediately in a secure location.
Authenticate
curl -X POST https://rksv.fiskaly.com/api/v1/auth \ -H "Content-Type: application/json" \ -d '{ "api_key": "YOUR_API_KEY", "api_secret": "YOUR_API_SECRET" }'const response = await fetch("https://rksv.fiskaly.com/api/v1/auth", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ api_key: "YOUR_API_KEY", api_secret: "YOUR_API_SECRET", }), }); const { access_token } = await response.json();import requests response = requests.post( "https://rksv.fiskaly.com/api/v1/auth", json={"api_key": "YOUR_API_KEY", "api_secret": "YOUR_API_SECRET"}, ) access_token = response.json()["access_token"]HttpClient client = HttpClient.newHttpClient(); String body = """{"api_key":"YOUR_API_KEY","api_secret":"YOUR_API_SECRET"}"""; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://rksv.fiskaly.com/api/v1/auth")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());using var client = new HttpClient(); var response = await client.PostAsJsonAsync( "https://rksv.fiskaly.com/api/v1/auth", new { api_key = "YOUR_API_KEY", api_secret = "YOUR_API_SECRET" }); var result = await response.Content.ReadFromJsonAsync<JsonElement>(); var accessToken = result.GetProperty("access_token").GetString();Authenticate with FinanzOnline
Before creating resources, authenticate the taxpayer’s FinanzOnline credentials:
curl -X POST https://rksv.fiskaly.com/api/v1/fon/auth \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "fon_participant_id": "YOUR_FON_PARTICIPANT_ID", "fon_user_id": "YOUR_FON_USER_ID", "fon_user_pin": "YOUR_FON_USER_PIN" }'await fetch("https://rksv.fiskaly.com/api/v1/fon/auth", { method: "POST", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ fon_participant_id: "YOUR_FON_PARTICIPANT_ID", fon_user_id: "YOUR_FON_USER_ID", fon_user_pin: "YOUR_FON_USER_PIN", }), });requests.post( "https://rksv.fiskaly.com/api/v1/fon/auth", headers={"Authorization": f"Bearer {access_token}"}, json={ "fon_participant_id": "YOUR_FON_PARTICIPANT_ID", "fon_user_id": "YOUR_FON_USER_ID", "fon_user_pin": "YOUR_FON_USER_PIN", }, )// POST /api/v1/fon/auth // Body: {"fon_participant_id":"...","fon_user_id":"...","fon_user_pin":"..."} // Header: Authorization: Bearer <access_token>client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); await client.PostAsJsonAsync( "https://rksv.fiskaly.com/api/v1/fon/auth", new { fon_participant_id = "YOUR_FON_PARTICIPANT_ID", fon_user_id = "YOUR_FON_USER_ID", fon_user_pin = "YOUR_FON_USER_PIN", });📘NoteThese are the credentials for the dedicated “Cash Register Webservice User” created by the taxpayer in FinanzOnline — not the general FinanzOnline login.
Create and initialize an SCU
SCU_ID=$(uuidgen) # Create SCU curl -X PUT "https://rksv.fiskaly.com/api/v1/signature-creation-unit/${SCU_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"legal_entity_id": {"vat_id": "ATU12345678"}}' # Initialize SCU (registers with FinanzOnline) curl -X PATCH "https://rksv.fiskaly.com/api/v1/signature-creation-unit/${SCU_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "INITIALIZED"}'const scuId = crypto.randomUUID(); const BASE = "https://rksv.fiskaly.com/api/v1"; const headers = { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }; // Create SCU await fetch(`${BASE}/signature-creation-unit/${scuId}`, { method: "PUT", headers, body: JSON.stringify({ legal_entity_id: { vat_id: "ATU12345678" }, }), }); // Initialize SCU await fetch(`${BASE}/signature-creation-unit/${scuId}`, { method: "PATCH", headers, body: JSON.stringify({ state: "INITIALIZED" }), });import uuid scu_id = str(uuid.uuid4()) BASE = "https://rksv.fiskaly.com/api/v1" hdrs = {"Authorization": f"Bearer {access_token}"} # Create SCU requests.put(f"{BASE}/signature-creation-unit/{scu_id}", headers=hdrs, json={"legal_entity_id": {"vat_id": "ATU12345678"}}) # Initialize SCU requests.patch(f"{BASE}/signature-creation-unit/{scu_id}", headers=hdrs, json={"state": "INITIALIZED"})// PUT /signature-creation-unit/{scuId} // Body: {"legal_entity_id":{"vat_id":"ATU12345678"}} // PATCH /signature-creation-unit/{scuId} // Body: {"state":"INITIALIZED"}var scuId = Guid.NewGuid().ToString(); await client.PutAsJsonAsync( $"https://rksv.fiskaly.com/api/v1/signature-creation-unit/{scuId}", new { legal_entity_id = new { vat_id = "ATU12345678" } }); await client.PatchAsJsonAsync( $"https://rksv.fiskaly.com/api/v1/signature-creation-unit/{scuId}", new { state = "INITIALIZED" });Initializing the SCU automatically registers it with FinanzOnline.
Create and initialize a Cash Register
CR_ID=$(uuidgen) # Create Cash Register curl -X PUT "https://rksv.fiskaly.com/api/v1/cash-register/${CR_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"description": "POS Terminal 1"}' # Register with FinanzOnline curl -X PATCH "https://rksv.fiskaly.com/api/v1/cash-register/${CR_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "REGISTERED"}' # Initialize (creates and validates the initial receipt) curl -X PATCH "https://rksv.fiskaly.com/api/v1/cash-register/${CR_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"state": "INITIALIZED"}'const crId = crypto.randomUUID(); // Create Cash Register await fetch(`${BASE}/cash-register/${crId}`, { method: "PUT", headers, body: JSON.stringify({ description: "POS Terminal 1" }), }); // Register with FinanzOnline await fetch(`${BASE}/cash-register/${crId}`, { method: "PATCH", headers, body: JSON.stringify({ state: "REGISTERED" }), }); // Initialize await fetch(`${BASE}/cash-register/${crId}`, { method: "PATCH", headers, body: JSON.stringify({ state: "INITIALIZED" }), });cr_id = str(uuid.uuid4()) requests.put(f"{BASE}/cash-register/{cr_id}", headers=hdrs, json={"description": "POS Terminal 1"}) requests.patch(f"{BASE}/cash-register/{cr_id}", headers=hdrs, json={"state": "REGISTERED"}) requests.patch(f"{BASE}/cash-register/{cr_id}", headers=hdrs, json={"state": "INITIALIZED"})// PUT /cash-register/{crId} → {"description":"POS Terminal 1"} // PATCH /cash-register/{crId} → {"state":"REGISTERED"} // PATCH /cash-register/{crId} → {"state":"INITIALIZED"}var crId = Guid.NewGuid().ToString(); await client.PutAsJsonAsync( $"{BASE}/cash-register/{crId}", new { description = "POS Terminal 1" }); await client.PatchAsJsonAsync( $"{BASE}/cash-register/{crId}", new { state = "REGISTERED" }); await client.PatchAsJsonAsync( $"{BASE}/cash-register/{crId}", new { state = "INITIALIZED" });📘NoteCash Registers require two state transitions: first to
REGISTERED(which registers with FinanzOnline), then toINITIALIZED(which creates and validates the initial receipt).Sign your first receipt
RECEIPT_ID=$(uuidgen) curl -X PUT "https://rksv.fiskaly.com/api/v1/cash-register/${CR_ID}/receipt/${RECEIPT_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "receipt_type": "NORMAL", "schema": { "standard_v1": { "receipt": { "amounts_per_vat_rate": [ {"vat_rate": "STANDARD", "amount": "12.00"} ], "amounts_per_payment_type": [ {"payment_type": "CASH", "amount": "12.00"} ] } } } }'const receiptId = crypto.randomUUID(); const receipt = await fetch( `${BASE}/cash-register/${crId}/receipt/${receiptId}`, { method: "PUT", headers, body: JSON.stringify({ receipt_type: "NORMAL", schema: { standard_v1: { receipt: { amounts_per_vat_rate: [ { vat_rate: "STANDARD", amount: "12.00" }, ], amounts_per_payment_type: [ { payment_type: "CASH", amount: "12.00" }, ], }, }, }, }), } ).then(r => r.json()); console.log("QR Code Data:", receipt.qr_code_data); console.log("Receipt Number:", receipt.receipt_number);receipt_id = str(uuid.uuid4()) receipt = requests.put( f"{BASE}/cash-register/{cr_id}/receipt/{receipt_id}", headers=hdrs, json={ "receipt_type": "NORMAL", "schema": { "standard_v1": { "receipt": { "amounts_per_vat_rate": [ {"vat_rate": "STANDARD", "amount": "12.00"} ], "amounts_per_payment_type": [ {"payment_type": "CASH", "amount": "12.00"} ], } } }, }, ).json() print("QR Code:", receipt["qr_code_data"])// PUT /cash-register/{crId}/receipt/{receiptId} // Body: {"receipt_type":"NORMAL","schema":{"standard_v1":{...}}} // Response contains qr_code_data, receipt_number, time_signaturevar receiptId = Guid.NewGuid().ToString(); var receiptResp = await client.PutAsJsonAsync( $"{BASE}/cash-register/{crId}/receipt/{receiptId}", new { receipt_type = "NORMAL", schema = new { standard_v1 = new { receipt = new { amounts_per_vat_rate = new[] { new { vat_rate = "STANDARD", amount = "12.00" } }, amounts_per_payment_type = new[] { new { payment_type = "CASH", amount = "12.00" } }, }}}});The response contains everything needed for an RKSV-compliant receipt:
qr_code_data(data for the mandatory RKSV QR code),receipt_number,time_signature, andcash_register_serial_number(required text fields).
Run the Script
Section titled “Run the Script”Want to run through all the steps automatically? Download and run our quickstart script:
# Download and run
curl -O https://workspace.fiskaly.com/scripts/sign-at-quickstart.sh
export API_KEY="your_api_key"
export API_SECRET="your_api_secret"
export FON_PARTICIPANT_ID="your_fon_participant_id"
export FON_USER_ID="your_fon_user_id"
export FON_USER_PIN="your_fon_user_pin"
export VAT_ID="ATU12345678"
bash sign-at-quickstart.sh# Download and run
curl -O https://workspace.fiskaly.com/scripts/sign-at-quickstart.mjs
API_KEY="your_key" API_SECRET="your_secret" FON_PARTICIPANT_ID="id" FON_USER_ID="id" FON_USER_PIN="pin" VAT_ID="ATU12345678" node sign-at-quickstart.mjsNext Steps
Section titled “Next Steps”Was this page helpful?