Skip to content

Error taxonomy

Every 4xx and 5xx has the same body. code is the stable, machine-readable identifier — branch on it, never on message.

{
"error": {
"type": "validation_error",
"code": "hr.device_missing_isu",
"message": "Device VM-0043 has no ISU number assigned. Register the premises in ePorezna and add the ISU number before fiscalizing.",
"param": "device_id",
"upstream": null,
"doc_url": "https://docs.fiskhub.com/errors/hr.device_missing_isu"
}
}
FieldNotes
typeThe broad category. A closed set — useful for handling a code you do not recognise.
codeStable forever. Never renamed, never repurposed. New codes may be added.
messageHuman-readable and actionable. Not part of the contract — reworded freely.
paramThe offending request field or header, when there is one.
upstreamRaw detail from the Tax Administration, for debugging. Not part of the contract.
doc_urlThe page for this exact code. Always resolves.

Types

typeHTTPMeaning
validation_error400The request is wrong. Retrying it unchanged cannot help.
authentication_error401The key is missing, unknown or revoked.
authorization_error403The key is valid but not allowed to do this.
not_found404No such resource is visible to this key.
conflict409The request conflicts with existing state.
rate_limit_error429Too many requests. Back off and retry with the same key.
fiscal_errorCarried inside a 200 invoice body, not as an HTTP error.
upstream_errorReported through the invoice’s fiscal_error, not as an HTTP error.
internal_error500Our fault. Retry with the same Idempotency-Key.

Handle an unrecognised code by falling back to its type:

switch (error.code) {
case "hr.device_missing_isu":
return alertOperator(error);
case "upstream_unavailable":
return keepSelling();
default:
return error.type === "validation_error" ? alertOperator(error) : retryLater(error);
}

All codes

Request shape

CodeHTTPRetry?
invalid_request400, 404, 409No — fix the request
missing_idempotency_key400No — add the header
idempotency_key_reused409No — use a new key
invoice_already_exists409No — the receipt number is already filed

Authentication and authorization

CodeHTTPRetry?
invalid_api_key401No
api_key_revoked401No — issue a new key
mode_mismatch403No — use the right key
insufficient_scope403No — use a key with the scope

Fleet and configuration

The caller’s setup is incomplete. Each of these blocks fiscalization until someone changes something.

CodeHTTPRetry?
hr.device_missing_isu400No — get the ISU number from ePorezna
device_inactive400No — reactivate the device
company_missing_certificate400No — upload a certificate
certificate_expired400No — upload a current certificate
hr.certificate_oib_mismatch400No — upload the right certificate

Croatian restrictive errors

Validated locally, before anything leaves our network, so you get a precise error in milliseconds instead of a round trip and an opaque upstream code.

CodeHTTPUpstream rule
hr.sale_older_than_30_days400176
hr.date_in_future400177
hr.invalid_receipt_number400178
hr.invalid_oib400179, and 180 on an attended receipt
hr.invalid_vat_rate400182
hr.invalid_pnp_rate400183, 184
hr.invalid_payment_method400§2.2.1, §2.1.1, and 181 on an attended receipt
hr.amount_out_of_range400v185
hr.tax_line_inconsistent400none — ours
hr.total_mismatch400none — ours

hr.tax_line_inconsistent and hr.total_mismatch are the two entries with no upstream rule behind them, and they are a pair: one asks whether a tax line fits its own base, the other whether those figures describe the receipt at all. The Tax Administration verifies no arithmetic at all — a receipt whose VAT line reads 25% of 10.00 = 5.50 is well-formed, gets a JIR, and is wrong only in your books, where it can no longer be amended. We refuse it rather than file it.

Restrictive errors 180 and 181 judge OibPrimateljaRacuna, which is not part of the unattended message at all. They are dormant for unattended sales and live for attended receipts.

Upstream

These appear inside a 200 invoice body as fiscal_error, not as HTTP errors. The sale is valid in every case.

CodeWhereRetried automatically
upstream_unavailablefiscal_error on a 200Yes
upstream_rejectedfiscal_error on a 200No — needs correction
upstream_signature_invalidfiscal_error on a 200No — contact support

Rate limiting

CodeHTTPRetry?
rate_limited429Yes — after Retry-After, with the same Idempotency-Key

Internal

CodeHTTPRetry?
internal_error500Yes — with the same Idempotency-Key