SDC API Reference
The SDC exposes a local REST API that your POS system calls to fiscalize invoices. This is the complete endpoint reference: every request and response model, every property, and every error code.
If you are new to the SDC, start with the SDC Overview and make sure the device is installed, initialized, and licensed first — most endpoints refuse to work until it is.
Base URL
The API listens on port 8888 by default. You can change the port from the SDC window (Change Port), and the user interface always shows the address the API is currently running on.
A few things worth knowing before you write any code:
HTTP only, no TLS. The API is not served over HTTPS.
No authentication. Any client that can reach the port can fiscalize invoices with your certificate.
It listens on all network interfaces, not just the loopback address. A POS running on another machine on the same network can reach the SDC at
http://{sdc-machine-ip}:8888. That also means anything else on the network can reach it, so keep the SDC on a trusted local network and restrict port 8888 in your firewall to the machines that actually need it.Interactive documentation is built in at
http://127.0.0.1:8888/swagger— you can try every endpoint from the browser while the SDC is running.

Before Your Requests Will Succeed
Most endpoints call ValidSE() first, which checks the Secure Element in this order and rejects the request with 400 Bad Request and a response code as soon as one check fails:
Check | Response code |
|---|---|
Smart card inserted |
|
Card not locked |
|
PIN verified this session |
|
Device initialized |
|
Certificate not expired |
|
These endpoints enforce it: create invoice, get signed invoice, all Reports endpoints, all Advanced endpoints. GET /api/v3/status, GET /api/v3/environment-parameters, GET /api/v3/attention, GET /api/v3/invoices/pdf/{invoiceNumber} and POST /api/v3/pin do not — they are the endpoints you use to diagnose a device that is not ready.
Reports and Advanced endpoints additionally require a Pro licence and return 2008 on a Lite licence. Fiscalizing with an unlicensed (free) SDC against a production card is rejected with 2007 — see Applying a License.
Endpoints
Method | Endpoint | Purpose | Pro only |
|---|---|---|---|
|
| Fiscalize an invoice | no |
|
| Re-read a recently signed invoice | no |
|
| Render a fiscal receipt as PDF | no |
|
| Verify the smart card PIN | no |
|
| Device status and current tax rates | no |
|
| Organization and environment details | no |
|
| Health check | no |
|
| Daily totals for a period | yes |
|
| Totals per payment type | yes |
|
| Totals per tax label | yes |
|
| Items sold in a period | yes |
|
| All advance-invoice collections | yes |
|
| Open advance-invoice collections | yes |
|
| One advance collection in full | yes |
|
| Calculated totals for a collection | yes |
Paths are matched case-insensitively, so /api/reports/getdailyreport also works.
Conventions
JSON in, JSON out. Response property names are camelCase.
Request fields are permissive. Every field on the invoice request accepts either a native JSON type or its string form —
"quantity": 2and"quantity": "2"are both fine, as are"invoiceType": "Normal"and"invoiceType": 0. Enum names are matched case-insensitively.Dates are parsed with
DateTime.Parse; ISO 8601 (2026-08-13T10:15:00) is the safe format.sdcDateTimein responses is UTC.RequestIdis a header, not a body field. Send it as an HTTP header on the create call (max 32 characters). It is echoed back in theRequestIdresponse header and lets you re-read the invoice afterwards.Accept-Languageselects the language of the printed journal text. The value is matched against the languages the tax authority environment supports (seesupportedLanguageson the status endpoint); an unmatched or missing header falls back to the environment's default.
RequestIdis not an idempotency key. Re-sending a create request with the sameRequestIdsigns a second fiscal invoice. Build your own duplicate protection before retrying.
Create an Invoice
POST /api/v3/invoices
Request properties
Property | Type | Required | Rules |
|---|---|---|---|
| enum | yes | See Enums. Invalid or missing → |
| enum | yes |
|
| array | yes | At least one entry |
| array | yes | At least one entry |
| string | no | Max 50 characters → |
| string | no | Max 20 characters → |
| string | no | Max 50 characters → |
| datetime | no | Unparseable → |
| string | no | Your own reference, max 60 characters → |
| string | no | Required when |
| datetime | no | The |
| object | no | String-to-string map, see Options |
payment[]
Property | Type | Required | Rules |
|---|---|---|---|
| decimal | yes | Unparseable → |
| enum | yes | See Enums. Invalid → |
When an invoice carries more than one payment, the invoice's own payment type is recorded as Other.
items[]
Property | Type | Required | Rules |
|---|---|---|---|
| string | yes | 1–2048 characters. Missing → |
| decimal | yes | 0.001 – 99,999,999,999.9999. Missing → |
| decimal | yes | Max 2 decimal places and non-negative → |
| decimal | yes | Max 2 decimal places and non-negative → |
| array of characters | yes | At least one tax label. Missing → |
| string | no | 8–14 characters → |
labels accepts a JSON array (["A"]) or a plain string ("A"). Read the valid labels for your certificate from GET /api/v3/status rather than hardcoding them — rates and labels change over time.
Options
options is a map of string keys to the string values "0" or "1". Any other value → 2805.
Key | Effect when set to |
|---|---|
|
|
|
|
Response
200 OK with the signed invoice:
Property | Type | Meaning |
|---|---|---|
| string | UID of the certificate that requested the invoice |
| datetime | Signing time in UTC — this is the legally binding timestamp |
| string | Composed as |
| string | Two-character counter suffix identifying the invoice/transaction type combination |
| string | The fiscal invoice number, composed as |
| array | Calculated tax per label — see below |
| string | Public tax authority verification link; this is what the QR code encodes |
| string | The QR code as a base64-encoded PNG, ready to print on the receipt |
| string | The plain-text fiscal receipt, formatted for the printer |
| string |
|
| string | UID of the Secure Element that signed |
| string | Base64 internal data block required on the printed receipt |
| string | Base64 digital signature |
| integer | Running count of all invoices signed by this Secure Element |
| integer | Running count for this transaction type |
| decimal | Invoice total, rounded to 4 decimal places |
| integer | Revision of the tax rate group used |
| string | Taxpayer details taken from the certificate, for the receipt header |
taxItems[]
Property | Type | Meaning |
|---|---|---|
| character | Tax label the amount was calculated for |
| decimal | Rate applied |
| decimal | Tax amount, rounded to 4 decimal places |
| string | Tax category name, printed on the receipt |
| integer | See |
taxItems[] also carries taxItemId, invoiceId, categoryId and categoryOrderId. These are internal bookkeeping values — ignore them.
Validation errors
Any validation failure returns 400 Bad Request with a ModelErrors body listing every problem at once:
property is the JSON path of the offending field, and errors holds four-digit response codes. Secure Element and licence problems use the check name as the property instead — Warning, Error or license.
Get a Signed Invoice
GET /api/v3/invoices/{requestId}
Returns the same InvoiceResult body as the create call, for an invoice you sent with that RequestId header.
Only the five most recent invoices per certificate are kept. The SDC stores signed invoices in a small rolling cache and prunes older entries, so this endpoint is a short-term safety net for a POS that lost the create response — not an invoice archive. Store the response when you receive it. Older invoices are still available as PDFs.
Returns 204 No Content when no cached invoice matches the request ID.
Get an Invoice PDF
GET /api/v3/invoices/pdf/{invoiceNumber}
Renders a previously fiscalized invoice — journal text plus verification QR code — as a printable PDF. {invoiceNumber} is the fiscal invoice number from the create response (URL-encode it; it contains hyphens but no slashes).
200 OK —
application/pdf, delivered asfiscal-{invoiceNumber}.pdf404 Not Found — unknown invoice number, or the invoice has no stored journal text (for example, it was created with
omitTextualRepresentation)
Unlike the request-ID lookup, this endpoint reads the SDC's full local invoice database, so it works for older invoices too.
Verify the PIN
POST /api/v3/pin
Unlocks the Secure Element for the session. Send the PIN as the raw request body — any non-digit characters are stripped, so 1234, "1234" and {"pin":"1234"} all resolve to 1234.
The response is always 200 OK with a four-character response code as the body — check the code, not the status:
Body | Meaning |
|---|---|
| PIN accepted, Secure Element unlocked |
| Wrong PIN, or not exactly 4 digits |
| Card locked after repeated wrong PINs |
| No smart card in the reader |
Never retry a rejected PIN automatically. Each failed attempt burns one try on the card's PIN counter, and the card locks permanently once it runs out. Prompt a human instead.
Device Status
GET /api/v3/status
The endpoint your POS should poll. It reports device health and — importantly — the authoritative tax labels and rates for the current certificate.
Property | Type | Meaning |
|---|---|---|
| boolean | The Secure Element needs a PIN before it can sign |
| boolean | The Secure Element has used ¾ of its audit storage and must submit an audit |
| datetime | Current SDC time |
| string | Fiscal number of the most recent invoice, or empty |
| string | POS-to-SDC protocol version |
| string | Smart card applet version |
| string | SDC versions |
| string | Device serial with the certificate UID appended |
| string | Device make and model |
| array of strings | Manufacturer-specific status codes |
| array of strings | General status codes — |
| string | Tax authority API the device is registered against |
| object | Tax rate group in force now — see below |
| array | All known tax rate groups, past and future |
| array of strings | Languages accepted in |
| string | Unique identifier of the certificate |
TaxRateGroup
Property | Type | Meaning |
|---|---|---|
| datetime | When the group takes effect |
| integer | Group revision identifier |
| array | Categories in the group |
TaxCategory
Property | Type | Meaning |
|---|---|---|
| string | Category name printed on the receipt |
| enum | How tax is calculated — see Enums |
| integer | Display/calculation order |
| array | Rates in the category |
TaxRate
Property | Type | Meaning |
|---|---|---|
| character | The label you put in |
| decimal | Percentage, or a fixed amount for |
Environment Parameters
GET /api/v3/environment-parameters
Organization and environment details, used for receipt headers and for linking to the taxpayer portal. Returns an object with empty fields if the device is not initialized yet.
Property | Type | Meaning |
|---|---|---|
| string | Registered taxpayer name |
| string | Tax authority server time zone |
| string | Registered address |
| string | Environment label, for example the sandbox or production name |
| string | Tax authority logo |
| string | Time source the SDC synchronizes against |
| array of strings | Languages available for journal text |
| object | Environment URLs |
endpoints
Property | Type | Meaning |
|---|---|---|
| string | Taxpayer admin portal URL |
| string | Tax authority API URL |
| string | Virtual SDC URL |
| string | Environment root URL |
Health Check
GET /api/v3/attention
Returns 200 OK with an empty body whenever the SDC's API is running. Use it as a liveness probe — it performs no Secure Element checks, so a 200 here means "the SDC is reachable", not "the SDC is ready to sign". Poll GET /api/v3/status for readiness.
Reports
All four report endpoints require a Pro licence and take the same query parameters:
Parameter | Type | Required | Meaning |
|---|---|---|---|
| datetime | yes | Start of the period, inclusive |
| datetime | yes | End of the period, inclusive |
| string | no | Restrict to one certificate UID; omit for all |
Reports count Normal and Advance invoices only — proforma, copy and training invoices are excluded. Refund amounts are subtracted from the totals. If report generation fails, the endpoint returns an empty report object rather than an error.
GET /api/Reports/GetDailyReport
Property | Type | Meaning |
|---|---|---|
| string | The UID filter that was applied, or |
| integer | Number of invoices counted |
| decimal | Sum of sale invoices |
| decimal | Sum of refund invoices |
| decimal |
|
| decimal | Sum of |
| array |
|
| array |
|
GET /api/Reports/GetPaymentTypes
Property | Type | Meaning |
|---|---|---|
| enum | Payment type |
| decimal | Net total for that type |
| decimal | Sum across all types |
GET /api/Reports/GetTaxAmounts
Property | Type | Meaning |
|---|---|---|
| character | Tax label |
| decimal | Net tax collected for that label |
| decimal | Sum across all labels |
GET /api/Reports/GetListOfItems
Items sold in the period, grouped by name and GTIN.
Property | Type | Meaning |
|---|---|---|
| string | Item name |
| string | GTIN, empty if none |
| decimal | Unit price |
| decimal | Net quantity sold |
| decimal | Net amount |
Advanced
Advance-invoice collections: chains of Advance invoices that eventually close with a final Normal invoice. All four endpoints require a Pro licence and operate on the certificate currently in the reader.
GET /api/Advanced/GetAllCollections
Every collection, open and closed. Returns an array of:
Property | Type | Meaning |
|---|---|---|
| datetime | When the collection was opened |
| string | Fiscal number of the first invoice in the chain — the collection's identifier |
| boolean | A final invoice has been issued |
GET /api/Advanced/GetOpenedCollections
The same shape, filtered to collections that are still open.
POST /api/Advanced/GetCollectionById
Returns the full chain, oldest first:
Property | Type | Meaning |
|---|---|---|
| datetime | Invoice timestamp |
| string | Fiscal number |
| string | Fiscal number of the previous invoice in the chain, |
| boolean | Whether the collection is closed |
| string | Certificate UID |
| enum | See Enums |
| enum |
|
| decimal | Invoice amount |
POST /api/Advanced/GetCalculatedAdvancedReportById
Same request body; returns the collection's totals:
Property | Type | Meaning |
|---|---|---|
| datetime | Timestamp of the first invoice |
| datetime | Timestamp of the last invoice |
| string | Fiscal number of the first invoice |
| string | Fiscal number of the last invoice |
| boolean | Whether the collection is closed |
| string | Certificate UID |
| decimal | Sum of advance sales |
| decimal | Sum of advance refunds |
| decimal | Final invoice amount, |
Advance chains are validated when you fiscalize them. A final Normal invoice must reference the last Advance refund in its chain, and a new Advance invoice must reference the most recent link — see codes 2009, 2010 and 2011.
Enums
Enum fields accept the name ("Cash", case-insensitive) or the number (1).
invoiceType
Value | Name | Meaning |
|---|---|---|
0 |
| Standard fiscal invoice |
1 |
| Not a fiscal invoice — quote or pre-bill |
2 |
| Fiscal copy of a previous document; requires |
3 |
| Test invoice, marked as not a fiscal invoice |
4 |
| Advance payment |
transactionType
Value | Name |
|---|---|
0 |
|
1 |
|
paymentType
Value | Name |
|---|---|
0 |
|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
categoryType
Value | Name | Meaning |
|---|---|---|
0 |
| Percentage of the net amount |
1 |
| Percentage of the total amount |
2 |
| Fixed amount per unit sold |
HTTP Status Codes
Status | When |
|---|---|
| Success. Note that |
|
|
| Validation failure, Secure Element not ready, or licence restriction. Body is |
| PDF requested for an unknown invoice, or one with no journal text |
| Unhandled error. The body is empty — check the SDC logs, and see Exporting Logs |
There is no retry-after or rate limiting. A device that is not ready answers 400, not 503, so treat 400 with a Secure Element code as "retry once the operator fixes the device" rather than a permanent failure.
Response Codes
Every code is four digits. The first digit gives the severity: 0xxx informational, 1xxx warning, 2xxx error.
Informational
Code | Meaning |
|---|---|
| All OK |
| PIN verified |
| Internet available |
| Internet unavailable |
Warnings
Code | Meaning |
|---|---|
| Secure Element storage 90% full |
| No smart card in the reader |
| Audit required |
| PIN required before signing |
| Undefined warning |
Device and licence errors
Code | Meaning |
|---|---|
| Maximum number of tax categories exceeded |
| A Secure Element counter reached its limit — the card must be replaced |
| End Audit sent with no active audit |
| Audit data must be 256 bytes |
| Proof of Audit does not match the expected Start Audit |
| Payload is not a valid Proof of Audit |
| Unlicensed SDC cannot fiscalize with a production card — only |
| This endpoint requires a Pro licence |
| Referenced invoice is not the correct one in the advance chain |
| Referenced advance invoice is not a refund |
| Referenced invoice is not an advance invoice |
| Wrong PIN |
| Card locked after repeated wrong PINs |
| Secure Element locked |
| Secure Element communication failed |
| Secure Element protocol mismatch |
| Tax label is not valid for this certificate |
| Device not configured — initialize it first |
| Certificate expired |
Field validation errors
Code | Meaning |
|---|---|
| Required field missing |
| Field length exceeded |
| Field too short |
| Field length invalid |
| Field out of range — including more than 2 decimal places on an amount |
| Field value invalid |
| Invalid data format |
| List shorter than expected |
| List longer than expected |
Next Steps
Initialize the SDC — get the device to a state where the API will sign
Applying a License — Lite versus Pro, and what Pro unlocks
Exporting Logs — what to collect when a request fails unexpectedly