Оди на содржината

Праќање документ

POST
/api/integration/v1/outbound

Submits one UBL 2.1 document for delivery.

By default the response does not wait for processing: status 210 means “received by us”.

Send Prefer: wait=N (seconds, at most 30) to wait for the outcome of our processing up to the submission to UJP. The answer then carries the status reached and, once UJP accepted the document, its identifier in ujp.euid. If the time runs out first, the answer carries status 210 or 220 and ujp is null — follow the document with GET outbound/{docUid}. Later changes on UJP’s side (the recipient accepting or refusing) are not waited for. The answer names the wait that was applied in the Preference-Applied header.

Repeating the call with the same X-Idempotency-Key and the same body within one hour returns the same docUid with HTTP 200 instead of creating a second document.

Примерот важи само за demo околината.

Request

curl -i -X POST "https://sandbox.api.earhiva.mk/api/integration/v1/outbound" \
  -H "X-Api-Key: <ВАШИОТ КЛУЧ>" \
  -H "X-Software-Id: <ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>" \
  -H "X-Idempotency-Key: <X-Idempotency-Key>" \
  -H "Prefer: <Prefer>" \
  -H "Content-Type: application/xml" \
  --data-binary @invoice.xml

Секој повик носи X-Api-Key со клуч што го има опфатот IntegrationApi, и X-Software-Id со името и верзијата на твојот софтвер. Како се бара клуч стои во Автентикација.

Parameters

Сите параметри (3)
ParameterInTypePresenceDescription
X-Software-IdheaderstringalwaysIdentifier of the calling software, e.g. SSBFocus/4.2.1. Free text, recorded in the audit trail. Required on every call; missing means EARH-1008.
X-Idempotency-KeyheaderstringalwaysClient-chosen key that makes the submission repeatable. The same key with the same body within one hour returns the same docUid instead of creating a second document; the same key with a different body is rejected with EARH-2010. Missing means EARH-2013.
PreferheaderstringoptionalOptional. wait=N makes the answer wait up to N seconds (at most 30) for the outcome of our processing up to the submission to UJP, and return the status reached together with ujp.euid. Omit it and the answer returns at once with status 210.

Request Body

One UBL 2.1 document as raw XML. Exactly one document per request — a payload carrying more is rejected with EARH-2011. The bytes are stored as received and are returned unchanged by GET outbound/{docUid}/file?format=ubl.

Тип: application/xml. Работен пример што поминува таков каков е: invoice-ubl21.xml — што содржи и што смееш да замениш стои на Формати.

Error codes

EARH-1001 · EARH-1002 · EARH-1003 · EARH-1004 · EARH-1005 · EARH-1006 · EARH-1007 · EARH-1010 · EARH-1011 · EARH-2001 · EARH-2002 · EARH-2003 · EARH-2004 · EARH-2005 · EARH-2006 · EARH-2007 · EARH-2010 · EARH-2011 · EARH-2012 · EARH-2013 · EARH-9001

Целосниот список шифри, со што значат и што да се направи, е во Каталог на грешки.

The same key and body were already submitted; the original docUid is returned and alreadyExisted is true.

{
  "docUid": "eah_o_01M0ZZB88FT117S27PM8ZEK9RY",
  "status": 210,
  "receivedAt": "2026-08-26T23:24:26+02:00",
  "alreadyExisted": true
}
Сите полиња во телото (6)
FieldTypePresenceDescription
docUidstringalwaysIdentifier of the document. Every later call about this document uses it.
statusinteger · int32alwaysStatus of the document at the moment of the answer. Without Prefer: wait it is 210 (Received). With it, it is the status our processing reached — 210 or 220 when the time ran out first; then follow the document with GET outbound/{docUid}.
receivedAtstring · date-timealwaysTime the document was taken over.
alreadyExistedbooleanalwaystrue when the same idempotency key and the same body were already submitted, so this call returned the original document instead of creating a second one. Then the answer carries HTTP 200; a newly created document carries 201.
failureCodestringnullableThe EARH-4xxx code when processing has already failed — the same field as on the document detail; null otherwise.
ujp—nullableThe answer received from UJP, with the identifier UJP assigned (euid). null while the document has not been forwarded to UJP — always the case without Prefer: wait.

The document was accepted and now carries a docUid.

{
  "docUid": "eah_o_01M0ZZB88FT117S27PM8ZEK9RY",
  "status": 210,
  "receivedAt": "2026-08-26T23:24:17+02:00",
  "alreadyExisted": false
}
Сите полиња во телото (6)
FieldTypePresenceDescription
docUidstringalwaysIdentifier of the document. Every later call about this document uses it.
statusinteger · int32alwaysStatus of the document at the moment of the answer. Without Prefer: wait it is 210 (Received). With it, it is the status our processing reached — 210 or 220 when the time ran out first; then follow the document with GET outbound/{docUid}.
receivedAtstring · date-timealwaysTime the document was taken over.
alreadyExistedbooleanalwaystrue when the same idempotency key and the same body were already submitted, so this call returned the original document instead of creating a second one. Then the answer carries HTTP 200; a newly created document carries 201.
failureCodestringnullableThe EARH-4xxx code when processing has already failed — the same field as on the document detail; null otherwise.
ujp—nullableThe answer received from UJP, with the identifier UJP assigned (euid). null while the document has not been forwarded to UJP — always the case without Prefer: wait.

The submission cannot be processed — EARH-1007 (a tenant value in the body), EARH-2001 (not well-formed XML), EARH-2002 (not UBL 2.1), EARH-2003 (no recipient), EARH-2004 (malformed recipient tax number), EARH-2005 (no document type), EARH-2006 (no amount), EARH-2007 (the issuer is not the organization this key belongs to), EARH-2011 (more than one document), EARH-2013 (the X-Idempotency-Key header is missing).

{
  "type": "https://earhiva.mk/errors/EARH-1007",
  "title": "Request body must not contain a tenant-identifying field.",
  "status": 400,
  "code": "EARH-1007"
}
Сите полиња во телото (6)
FieldTypePresenceDescription
typestringalwaysAddress of this code in the error catalogue (RFC 7807).
titlestringalwaysShort, stable English summary of the error — the same string that appears in your log.
statusinteger · int32alwaysHTTP status code, repeated in the body (RFC 7807).
detailstringnullableWhat went wrong in this particular call, when there is more to say than the title. Absent when the title already says everything.
codestringalwaysThe EARH-xxxx code. This is the contract: match on it, not on the text.
eventIdstringnullableOnly on EARH-9000. Quote it when reporting the problem — it is the same reference we record in our log, so one number identifies the event on both sides.

The API key is missing, unknown, expired or revoked — EARH-1001, EARH-1002, EARH-1003. Телото е стандардното тело на грешка — исто кај сите повици. Што да се направи со секоја шифра стои во Каталог на грешки.

The caller’s address is outside the allowed list, the key does not carry the IntegrationApi scope, the organization’s plan does not include integration access, or the key has been switched off by its owner — EARH-1004, EARH-1005, EARH-1010, EARH-1011. The last two are returned on every call and carry no Retry-After: waiting does not change the state. Телото е стандардното тело на грешка — исто кај сите повици. Што да се направи со секоја шифра стои во Каталог на грешки.

EARH-2010 — the same idempotency key was already used with different content; EARH-9001 — outbound over the API is not enabled for this tenant.

{
  "type": "https://earhiva.mk/errors/EARH-2010",
  "title": "This idempotency key was already used with different content.",
  "status": 409,
  "code": "EARH-2010"
}
Сите полиња во телото (6)
FieldTypePresenceDescription
typestringalwaysAddress of this code in the error catalogue (RFC 7807).
titlestringalwaysShort, stable English summary of the error — the same string that appears in your log.
statusinteger · int32alwaysHTTP status code, repeated in the body (RFC 7807).
detailstringnullableWhat went wrong in this particular call, when there is more to say than the title. Absent when the title already says everything.
codestringalwaysThe EARH-xxxx code. This is the contract: match on it, not on the text.
eventIdstringnullableOnly on EARH-9000. Quote it when reporting the problem — it is the same reference we record in our log, so one number identifies the event on both sides.

EARH-2012 — the document exceeds the working size limit; the response names the allowed one.

{
  "type": "https://earhiva.mk/errors/EARH-2012",
  "title": "Document exceeds the configured size limit.",
  "status": 413,
  "code": "EARH-2012"
}
Сите полиња во телото (6)
FieldTypePresenceDescription
typestringalwaysAddress of this code in the error catalogue (RFC 7807).
titlestringalwaysShort, stable English summary of the error — the same string that appears in your log.
statusinteger · int32alwaysHTTP status code, repeated in the body (RFC 7807).
detailstringnullableWhat went wrong in this particular call, when there is more to say than the title. Absent when the title already says everything.
codestringalwaysThe EARH-xxxx code. This is the contract: match on it, not on the text.
eventIdstringnullableOnly on EARH-9000. Quote it when reporting the problem — it is the same reference we record in our log, so one number identifies the event on both sides.

The traffic limit for this key has been reached — EARH-1006. The response carries Retry-After. The limit is counted per key, and its size comes from the organization’s plan. Телото е стандардното тело на грешка — исто кај сите повици. Што да се направи со секоја шифра стои во Каталог на грешки.

Unexpected error on our side — EARH-9000. The body carries eventId; quote it when reporting the problem. Телото е стандардното тело на грешка — исто кај сите повици. Што да се направи со секоја шифра стои во Каталог на грешки.