Step-by-Step Integration
To begin the integration process, please refer to the detailed step-by-step instructions provided here.
The accompanying diagram illustrates the workflow and highlights the essential steps necessary to successfully complete your integration.
For the integration, you will need to utilize the fiskaly HUB, the Management API, and the SIGN AT API.
Before diving into the setup, here is what you will configure:
Organization
Your top-level entity in fiskaly. Managed organizations represent individual merchants.
API Key & Secret
Credentials generated in HUB, used to authenticate all subsequent SIGN AT API requests.
FON Authentication
FinanzOnline credentials provided by the taxpayer to enable synchronization with the Austrian tax authority.
SCU (Signature Creation Unit)
The core signing component. One SCU per managed organization handles cryptographic signing of receipts.
Cash Register
Represents a physical or virtual cash register. Must be registered with FinanzOnline and initialized.
Receipt
A signed RKSV-compliant fiscal record containing QR code data and receipt metadata.
Prerequisites
Section titled “Prerequisites”You need a fiskaly account and access to the fiskaly HUB. If you do not have an account yet, sign up here.
You will also need a tool to make HTTP requests — for example cURL (command line), Postman, or your own application code. You may download our Postman collection, which can facilitate your integration.
Integration Workflow
Section titled “Integration Workflow”The diagram below illustrates the workflow and highlights the essential steps necessary to successfully complete your integration. Each tile links directly to the matching setup step below.
Step-by-Step Setup
Section titled “Step-by-Step Setup”Register on Dashboard
Begin by registering on the fiskaly HUB. Creating an account is the first step, after which you can proceed with setting up the organizational structure for your business within our system.
💡Get started quicklyHUB provides a guided onboarding flow that walks you through account creation and initial setup.
Create First Organization
Continue with creating your first organization using HUB. This organization will represent the POS provider or retailer with its own POS system. It is necessary to include the billing address at this stage. This address will only be used for fiskaly’s billing purposes.
💡Not ready for production?For testing purposes, you do not need to fill in all fields. You can leave the billing address empty and complete it later.
Create Managed Organizations
After establishing your first organization, you will proceed to create managed organizations. Each managed organization represents a merchant, enabling you to manage them separately. If you are considering automating your process, we recommend using the createOrganization endpoint of the Management API.
💡Automate at scaleIf you manage many merchants, use the Management API to create managed organizations programmatically instead of doing it manually through HUB.
Create API Key
The next step is to generate an API key within each managed organization. This can be done via HUB or the createApiKey endpoint of the Management API. This API key and secret pair is required for generating an access token, which is used for all subsequent API calls.
⚠️Store your credentials safelyThe API Secret is only shown once. Make sure to copy and store it in a secure location before closing the dialog.
📘TEST vs. LIVEAPI keys generated in the TEST environment will create TEST resources, while those from the LIVE environment will create LIVE resources. For further details, refer to our article on TEST and LIVE environments.
Starting from the next step, you will be utilizing the SIGN AT API.
Authenticate with the API
Use your API key and secret to obtain an access token. This token is required for all subsequent requests.
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();The response contains an
access_tokenthat you must include as a Bearer token in theAuthorizationheader of all following requests.Authenticate FON
After authenticating with the previously generated API key and secret pair, it is necessary to call the authenticateFon endpoint once per taxpayer.
In order to enable the synchronization with FinanzOnline, the taxpayer first needs to create the “Cash Register Webservice User” directly in FinanzOnline and provide you with the credentials of this user.
📘FON credentials are separateThe credentials do not correspond to the general FinanzOnline credentials. They correspond to the credentials of the dedicated Cash Register Webservice User created by the taxpayer.
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" }'const fonResponse = 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", }), } );Create SCU
Now, continue with creating an SCU via the createSignatureCreationUnit endpoint. Per managed organization, only one SCU needs to be created. Once created, the state of an SCU will be
CREATED.SCU_ID=$(uuidgen) 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" } }'const scuId = crypto.randomUUID(); const scuResponse = await fetch( `https://rksv.fiskaly.com/api/v1/signature-creation-unit/${scuId}`, { method: "PUT", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ legal_entity_id: { vat_id: "ATU12345678", }, }), } );📘NoteReplaceATU12345678with the actual VAT ID of the taxpayer.Create Cash Register(s)
Continue with creating at least one Cash Register via the createCashRegister endpoint. The number of cash registers should correspond to the number of cash registers used in a particular shop or store. Creating a Cash Register renders the state
CREATED.CASH_REGISTER_ID=$(uuidgen) curl -X PUT "https://rksv.fiskaly.com/api/v1/cash-register/${CASH_REGISTER_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "description": "Main POS Terminal" }'const cashRegisterId = crypto.randomUUID(); const crResponse = await fetch( `https://rksv.fiskaly.com/api/v1/cash-register/${cashRegisterId}`, { method: "PUT", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ description: "Main POS Terminal", }), } );Update SCU to INITIALIZED
For signing receipts, both the SCU and Cash Register(s) need to be updated to
INITIALIZED. Call the updateSignatureCreationUnit endpoint and transition it to stateINITIALIZED. This state transition automatically registers the SCU in the FinanzOnline portal.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" }'await fetch( `https://rksv.fiskaly.com/api/v1/signature-creation-unit/${scuId}`, { method: "PATCH", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ state: "INITIALIZED", }), } );Update Cash Register(s)
In contrast to updating the SCU, Cash Register(s) need to be updated twice via updateCashRegister:
a) Register the Cash Register
First, change the Cash Register state to
REGISTERED. This state transition automatically registers the Cash Register in the FinanzOnline portal.curl -X PATCH "https://rksv.fiskaly.com/api/v1/cash-register/${CASH_REGISTER_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "state": "REGISTERED" }'await fetch( `https://rksv.fiskaly.com/api/v1/cash-register/${cashRegisterId}`, { method: "PATCH", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ state: "REGISTERED", }), } );b) Initialize the Cash Register
Then, in a second call, change the state to
INITIALIZED. This state transition triggers the creation and validation of the initial receipt in the FinanzOnline portal.curl -X PATCH "https://rksv.fiskaly.com/api/v1/cash-register/${CASH_REGISTER_ID}" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "state": "INITIALIZED" }'await fetch( `https://rksv.fiskaly.com/api/v1/cash-register/${cashRegisterId}`, { method: "PATCH", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ state: "INITIALIZED", }), } );Both SCU and Cash Register are now ready to sign receipts.
Sign Receipts
With all previous steps completed, you are now ready to sign receipts via the signReceipt endpoint.
RECEIPT_ID=$(uuidgen) curl -X PUT "https://rksv.fiskaly.com/api/v1/cash-register/${CASH_REGISTER_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 receiptResponse = await fetch( `https://rksv.fiskaly.com/api/v1/cash-register/${cashRegisterId}/receipt/${receiptId}`, { method: "PUT", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json", }, 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" }, ], }, }, }, }), } ); const signedReceipt = await receiptResponse.json();SIGN AT ensures that all receipts are RKSV compliant. The response contains all information required for augmenting the final receipt handed out to the customer:
qr_code_data— contains the data for the RKSV QR code to be displayed in graphical formreceipt_number,time_signature, andcash_register_serial_number— information to display in textual form- All raw gross amounts
💡Automate the setupThis entire sequence of requests can be integrated into a “one-click” provisioning solution that requires no manual user interaction. The implementation details are up to you.
Next Steps
Section titled “Next Steps”SIGN AT API Documentation
Full API documentation for the RKSV v1 endpoint — all resources, parameters, and responses.
Receipt Data
Detailed reference for receipt fields, VAT rates, and payment types supported by SIGN AT.
Glossary
Key terms and definitions for the Austrian RKSV fiscal compliance system.
HUB Guide
Learn how to manage organizations, API keys, and resources through fiskaly HUB.
Was this page helpful?