Error catalogue
Every code the API returns is on this page — there is no second list anywhere else. The fastest way in is Ctrl+F on the code, or on the text you see in your own log.
EARH-1xxx — on your side — the key or the address
| Code | HTTP | What it means | What to do | Text from the API |
|---|---|---|---|---|
| 401 | The request arrived without an API key, or with a key we do not know. Most often the header is missing, or the key was copied with a stray space or cut short. | Check the key you are sending character by character and try again. If it is exactly the key you were issued, get in touch — it may have been issued for another environment (demo versus production). | API key is missing or unknown. |
| 401 | The key exists, but its validity period has passed. Keys are issued with an expiry date and stop working on their own once it is reached. | Request a new key and replace it in your configuration. Nothing is lost — once the key is new, the same requests go through unchanged. | API key has expired. |
| 401 | The key was withdrawn before its expiry date — usually because it was replaced with a new one, or because it was reported as compromised. | Do not retry the same key; it will not come back to life. Ask us for a new key, and check whether someone on your team already received the replacement. | API key has been revoked. |
| 403 | The key is valid, but the request comes from an address that is not on the allowed list for that key. | Send us the address your requests actually leave from so we can add it. Watch out if your traffic goes through a proxy or a cloud provider — the address we see is theirs, not yours. | Request origin is not on the allowed list. |
| 403 | The key is valid, but it was not issued for the Integration API. The scope is part of the key itself and cannot be changed from your side. | Ask us to issue a key with the IntegrationApi scope. Do not try the same key on another address — the outcome will be the same. | API key does not have the IntegrationApi scope. |
| 429 | Your key has reached the traffic limit for the current window. This is not an error in the request — the request itself is correct. | Wait for as long as the Retry-After header in the response says, then send the same request again. If you hit the limit regularly, spread the calls out or get in touch so we can look at it. | Rate limit exceeded. |
| 400 | The request body carries a field that names a tenant. Which tenant is involved is decided by the key, so such a field must not arrive from outside. | Remove that field from the body and send again. If your library adds it on its own, turn that behaviour off — the key already carries the information. | Request body must not contain a tenant-identifying field. |
| 400 | The X-Software-Id header is missing. We recognise which software is calling by it, and we need that when we look for a problem together with you. | Add the header with your software's identifier to every request and send again. | X-Software-Id header is missing. |
| 404 | The address does not exist in the version you are calling. Usually the path is mistyped, or it belongs to an older or newer version than the one in the address. | Compare the path with the list of addresses in this documentation, including the version segment. If the address exists only in a newer version, move to it deliberately — do not change a single call. | This endpoint does not exist in this version. |
| 403 | The key is valid, but the organization's plan does not include integration access. This is not a temporary state and it does not depend on traffic — every call with this key gets the same answer until the plan changes. | You cannot resolve this from your side. Tell the organization that owns the key that their plan does not include integration; they change the subscription. ⛔ Do not retry in a loop — the response deliberately carries no Retry-After, because waiting changes nothing. | The subscription plan for this organization does not include integration access. |
| 403 | The organization's plan does include integration access, but this key has been switched off by its owner — its traffic limit is set to zero. Other keys of the same organization can keep working normally. | Ask the key's owner inside the organization to restore the traffic limit or to issue you another key. ⛔ This is not the same state as EARH-1010: there the plan is the problem, here the key is. The response carries no Retry-After — waiting changes nothing. | This API key is currently disabled for integration traffic. |
EARH-2xxx — on your side — the content of the submitted document
| Code | HTTP | What it means | What to do | Text from the API |
|---|---|---|---|---|
| 400 | The body cannot be read as XML at all — an unclosed tag, a stray character, or content cut short in transit. | Check the document with an XML reader before sending and try again. Check as well that the body is not truncated in transit (length, encoding, compression). | Request body is not well-formed XML. |
| 400 | The body is valid XML, but not a UBL 2.1 document — the root element or the namespaces are not the ones we expect. | Export the document as UBL 2.1 from your software and send it again. No other e-invoice format is accepted on this address. | Document is not UBL 2.1. |
| 400 | The document carries no recipient. Without it we do not know who the invoice is for. | Fill in the recipient part of the document and send it again. The idempotency key may stay the same — the content changes, so the new request will not count as a duplicate. | Document has no recipient. |
| 400 | The recipient's tax number in the document is not in a shape we recognise — usually it carries spaces, dashes, or fewer digits than a tax number has. | Correct the tax number in the document and send it again. The idempotency key may stay the same — the content changes, so the new request will not count as a duplicate. | Recipient tax number (EDB) is malformed. |
| 400 | The document does not say what it is — an invoice, a credit note, or a debit note. That value decides how it is processed further. | Set the document type according to UBL 2.1 and send it again. | Document has no type. |
| 400 | The payable amount is missing from the document. A document without an amount cannot be submitted further. | Check the amounts in the document — the payable total must be there — and send it again. | Document has no amount. |
| 400 | The document carries an issuer tax number (cac:AccountingSupplierParty) that is not the organization this key belongs to. One key sends documents for its own organization only. | Check the seller tax number in the document, or use the key of that organization. If you leave the field out entirely the document is accepted — the sender is resolved from the key. The form with and without the MK prefix counts as the same taxpayer. | The issuer is not the organization this key belongs to. |
| 409 | The same idempotency key has already been used, but with different content. Either a new document was sent with an old key, or the document changed after the first submission. | If you are sending a new document, give it a new idempotency key. If you are resending the same document, send its content unchanged — then the answer is the same as the first time. | This idempotency key was already used with different content. |
| 400 | One request carries more than one document. This address accepts exactly one document per call. | Split the documents and send each one with its own call and its own idempotency key. | Request contains more than one document. |
| 413 | The document is larger than the allowed size. The limit that applies is named in the response itself. | Bring the document under that limit — the excess usually comes from embedded attachments or images — and send it again. | Document exceeds the configured size limit. |
| 400 | The X-Idempotency-Key header is missing. Without it we cannot tell a repeated request apart from a new document. | Add an idempotency key — the same one for a retry of the same document, a new one for every new document — and send again. | X-Idempotency-Key header is missing. |
| 400 | A parameter in the request cannot be read: a required one is missing, a date is not a date, or a value is outside the allowed set. The detail field names the parameter, and for statuses it also lists the allowed values. | Fix the parameter that detail names and call again. Repeating it unchanged returns the same answer. | A parameter cannot be read as submitted. |
| 400 | The requested code list type does not exist. The response names the types we support. | Take one of the types listed in the response and call again. | Unknown codelist type. |
| 400 | The body of the decision is not usable. A rejection needs both a reason code and a comment; an acceptance carries neither. The reason must be active in the reject-reasons code list at the moment of the call. | Read detail for what is missing and send the decision again. The active reasons are on GET codelists/reject-reasons — the list changes, so do not hard-code it. | Decision cannot be read as submitted. |
| 400 | The body of the call to sandbox/inbound is not usable — a required field is missing, or pdfBase64 is not valid base64. The only required field is documentNumber; everything else has a sensible default. | Read detail for what is missing and send the request again. This code exists only on the sandbox server — there where the endpoint itself exists. | The request body is not usable. |
EARH-3xxx — on your side — the identifier or the state
| Code | HTTP | What it means | What to do | Text from the API |
|---|---|---|---|---|
| 404 | There is no document with that identifier for your tenant. Either the identifier is wrong, or the document belongs to another tenant. | Check the identifier from the answer you received when submitting. Do not look the document up by anything else — here everything works by the identifier we returned. | Document not found. |
| 404 | The document exists, but not in the format you asked for. Some formats only come into being after a certain step of the processing. | Check which status the document is in and ask for a format that exists for it. If the format is expected later, wait for the status it comes with and call again. | This format does not exist for the document. |
| 409 | The document is in a state from which cancellation is not allowed — processing has gone further than the point it can be withdrawn from. | Check the document's status. If the cancellation is still needed, it is settled with the recipient as a business matter, not through this call. | Current status does not allow cancellation. |
| 409 | The document is already cancelled — usually because the same call was sent twice. | Nothing needs to be done. The state is the one you wanted; treat this answer as a confirmation, not as a failure. | Document is already cancelled. |
| 400 | The requested page size is larger than the allowed one. The maximum that applies is named in the response. | Lower the page size below that value and call again, then take the remaining records with the following pages. | Requested page size exceeds the allowed maximum. |
| 409 | The state of the document does not allow a decision: the deadline has passed and the tax authority accepted the document on its own, a decision is already confirmed, or one is being reported right now. detail says which of the three it is. | Retrying will not help — the state changed. Read the document and see what it says. If the deadline passed, the acceptance already happened without you; read decisionDeadline before deciding, not after a refused call. | Current state does not allow a decision. |
EARH-4xxx — on neither side — the outcome of the processing
| Code | HTTP | What it means | What to do | Text from the API |
|---|---|---|---|---|
| — | The document did not pass validation before submission. This code does not come back as a rejected request — the submission itself went through, and the code appears later on the document, in the failureCode field. | Read the accompanying description on the document, correct what it reports, and send a new document with a new idempotency key. | The document failed pre-submission validation. |
| — | UJP rejected the document. This code does not come back as a rejected request — it appears later on the document, in the failureCode field, while UJP's own code sits in the ujp block. | Read the code and the description from the ujp block — the real reason is there. Correct the document accordingly and send a new one with a new idempotency key. | The document was rejected by UJP. See the ujp block for their code. |
| — | The recipient rejected the document. This code does not come back as a rejected request — it appears later on the document, in the failureCode field. | The reason is with the recipient, not with the technology. Settle it with them and, if needed, send a corrected document with a new idempotency key. | The recipient rejected the document. |
| — | Processing stopped on a technical failure — not on a content check. This code does not come back as a rejected request; it appears later on the document, in the failureCode field. ⛔ It does not always mean the cause is on our side: if the step that failed is ConvertFormat, the document could not be converted and the cause is in your body — most often part of the structure is missing (for example there is no cac:InvoiceLine at all). ⚠️ The issuer's details are NOT such a case: the tax number, the VAT number and the address of the seller are filled in from your organization, so their absence is not a cause of this code. | Do not resend the document right away. First look at which step failed — in the failedStep field, on the document screen or through the history: if it is ConvertFormat, fix the body (check that it carries lines, amounts and the three required paths from the Formats page). If the failure is in another step, get in touch with us and quote the document identifier. | A technical error occurred during processing or delivery. |
| — | The recipient can neither be resolved nor registered. ⛔ Since 13.09.2026 this is a rare outcome: a recipient that is not a registered partner is REGISTERED from the document itself — from the name, tax number and address it carries — and the processing goes on. The code is left for the case where even that is not possible: a malformed tax number that acceptance let through, or a partner that was deleted in the organization (a deleted record is not brought back to life automatically). It appears on the document, in the failureCode field, not as a rejected request. | Look at validationErrors — it carries EARH-5020 with the specific reason. Check the recipient's tax number in the body; if the partner was deleted in the organization, restore it or register it again (Partners in the web application), then send a new document with a new idempotency key. | The recipient could not be resolved. |
| — | The decision is recorded on our side, but the tax authority did not accept it. This code does not come back as a rejected request — it stands in the successful answer of POST decision, in the failureCode field. | The usual cause is a rejection reason the tax authority no longer recognises. Pull the active ones from GET codelists/reject-reasons and send a corrected decision — it replaces the previous one while the deadline still runs. | The tax authority did not accept the decision. |
EARH-5xxx — on your side — a single field in the UJP message
| Code | HTTP | What it means | What to do | Text from the API |
|---|---|---|---|---|
| — | A required field is missing or empty in the composed UJP message. | Look at the entry's path to find the field, fill it in in your document and send a new one with a new idempotency key. | A required field is missing or empty. |
| — | The value of the field is longer than the length the tax authority allows. | Shorten the value of the field named by path and send a new document with a new idempotency key. | The value is longer than allowed. |
| — | The value of the field is shorter than the smallest allowed length. | Complete the value of the field named by path and send a new document with a new idempotency key. | The value is shorter than required. |
| — | The value does not match the required format — usually a date, a tax number or a code with a prescribed shape. | Check the shape of the field named by path and send a new document with a new idempotency key. | The value does not match the required format. |
| — | The list named by path is empty, but it must carry at least one item — typically the invoice lines. | Add at least one item and send a new document with a new idempotency key. | The list must carry at least one item. |
| — | The message we compose for the tax authority is not valid JSON. This is a fault on our side, not in the document you sent. | Retrying will not help. Tell us, with the document's docUid and the time — that is how we find the exact case. | The composed UJP message is not valid JSON. This is a fault on our side, not in your request. |
| — | The field is required when the other party is foreign, and it is missing in this document. | Fill in the field named by path and send a new document with a new idempotency key. | The field is required when the party is foreign. |
| — | The field is required when the other party is a resident, and it is missing in this document. | Fill in the field named by path and send a new document with a new idempotency key. | The field is required when the party is a resident. |
| — | At least one field out of a group must be filled in, and in this document none is. | Fill in one of the fields of the group named by path and send a new document with a new idempotency key. | At least one field of the group must be filled in. |
| — | The field is required when the seller is registered for VAT, and it is missing in this document. | Fill in the field named by path and send a new document with a new idempotency key. | The field is required when the seller is registered for VAT. |
| — | The reference to a related document is incomplete — it must carry all four of its fields. | Complete the reference named by path and send a new document with a new idempotency key. | A reference to a related document must carry all four of its fields. |
| — | The totals of the document do not add up within the allowed rounding tolerance. | Recalculate the totals and send a new document with a new idempotency key. | The totals do not add up within the allowed rounding tolerance. |
| — | The recipient is not a registered partner, and could not be registered from the document. ⛔ This code appears in validationErrors alongside the outcome EARH-4005, not EARH-4001: it is not a rule of the pre-submission check but the reason recorded by the step that resolves the recipient. ⚠️ Since 13.09.2026 an unknown recipient is registered automatically, so the code is left only for a tax number that fails the shape check and for a partner that was deleted in the organization. | Check the recipient's tax number in the body. If the partner was deleted, restore it or register it again in the organization, and send a new document with a new idempotency key. | The recipient is not registered as a partner in this organization. |
EARH-9xxx — on our side
| Code | HTTP | What it means | What to do | Text from the API |
|---|---|---|---|---|
| 500 | An unexpected error on our side. The request you sent is not the cause. The answer carries an event identifier (eventId). | Try again after a short while with the same idempotency key. If it happens again, get in touch and quote the eventId — that is how we find the exact event. | Unexpected error. |
| 409 | Submitting documents through the API is not enabled for this tenant. The key and the document are both fine — what is missing is the approval of the direction itself. | Get in touch with us to enable the outbound direction for your tenant. Repeating the call will not change the outcome until that is done. | Outbound delivery via API is not enabled for this tenant. |
| 409 | The decision cannot be handed on to the tax authority because of a state on OUR side — the document has no identifier there, the signer is not set up, or the tax authority's address is not resolved. It is not an error in your request. | Retrying will not help and there is nothing to change in the call. Tell us, with the document identifier and the time of the call. | The decision cannot be reported to the tax authority. |
| 409 | The document exists and its record says the content was stored, but the content is gone — neither locally nor in cloud storage. ⛔ This is NOT the same as EARH-3002: that code means the document never arrived in that representation, which is an orderly state. This one means the representation existed and its content was lost. | Repeating will not help and there is nothing to change in the call. Get in touch with us, quoting the document identifier, the format you asked for and the time of the call. Everything else about the document — status, amounts, history — still reads normally. | The stored content of this document is not retrievable. |