Formats
The document is sent as UBL 2.1 XML in the body of POST /api/integration/v1/outbound. This page
says which profile is expected, which fields are required for the document to be accepted at all,
and where the schema and the working sample are.
1. Profile
Section titled “1. Profile”UBL 2.1 is a broad standard and allows far more than any real environment actually reads. A profile is the narrowing that applies here: which root is accepted, in which namespaces, and which fields the document must carry to be accepted at all. Anything the standard allows and the profile does not require may be present — but it is neither checked nor expected.
UBL 2.1 is accepted, in the original OASIS namespaces, with an Invoice or CreditNote root:
| Kind | Root | Namespace |
|---|---|---|
| Invoice | Invoice | urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 |
| Credit note | CreditNote | urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2 |
The two accompanying namespaces are the standard ones:
cbc urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2cac urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2One request carries exactly one document. An envelope with several Invoice elements is
rejected with EARH-2011.
Required fields
Section titled “Required fields”These are all the checks that acceptance performs. Each one has its own code, and that code comes back in the same call — not later.
| What is required | Path in the document | Code when it is missing |
|---|---|---|
| the recipient’s tax number (EDB) | cac:AccountingCustomerParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID | EARH-2003 |
| that tax number in a valid shape | the same path | EARH-2004 |
| the document type | cbc:InvoiceTypeCode · on CreditNote: cbc:CreditNoteTypeCode | EARH-2005 |
| the payable amount | cac:LegalMonetaryTotal/cbc:PayableAmount | EARH-2006 |
The issuer is not required for acceptance — the sender is resolved from the key, so
cac:AccountingSupplierParty may carry nothing but a name, as in the sample below. ⛔ But if you do
write a tax number there, it must be the tax number of the organization this key belongs to; another
organization’s is refused with EARH-2007 in the same call.
⚠️ That holds through the whole processing, not only on acceptance. Whatever the document does not carry for the issuer — tax number, VAT number, address — is filled in from your organization before the invoice leaves for the tax authority. So a block with nothing but a name is enough.
📌 The issuer’s master data is settled by the tax authority’s registry: even when the document does carry them, the name and address are aligned with the registered ones before submission. That prevents an invoice whose details do not match the registry.
| What is judged | Path in the document | Code when it does not match |
|---|---|---|
| the issuer’s tax number, when present | cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID | EARH-2007 |
Before those, the shape of the body itself is checked — EARH-2001 when the
XML is not well-formed, and EARH-2002 when the root is neither Invoice
nor CreditNote in the namespaces above.
A tax number is thirteen digits, with or without a two-letter country prefix — 4030000000000 and
MK4030000000000 are both valid, and a recipient from another country with its own prefix passes
as well.
What UJP requires and acceptance does not check
Section titled “What UJP requires and acceptance does not check”Before the invoice goes to UJP, it is checked against the fields UJP requires. A document missing
any of them is accepted (201), but stops before UJP with status 250 and
EARH-4001, and the cause is in validationErrors.
| What is required | Path in the document |
|---|---|
| the recipient’s address — street, city, postal code | cac:AccountingCustomerParty/cac:Party/cac:PostalAddress — cbc:StreetName, cbc:CityName, cbc:PostalZone |
| the VAT rate of every line, in percent | cac:InvoiceLine/cac:Item/cac:ClassifiedTaxCategory/cbc:Percent |
The tax group and indicator for UJP are derived from the rate. The VAT total over the lines must
match cac:TaxTotal/cbc:TaxAmount.
2. Schema
Section titled “2. Schema”The schema describes the profile above — the root, the required paths and the shape of the amounts.
| File | What it is |
|---|---|
ubl21-earhiva.xsd | the main schema — the Invoice root |
ubl21-earhiva-cbc.xsd | Common Basic Components |
ubl21-earhiva-cac.xsd | Common Aggregate Components |
The main schema imports the other two by relative path, so all three are downloaded into the same folder. Otherwise validation fails on an unresolved import rather than on a finding in the document.
3. Working samples
Section titled “3. Working samples”invoice-ubl21-en.xml is an invoice that is accepted exactly as it is on the
sandbox server — 201 with a docUid. It is the same file step 3 of the
Quick Start asks for — save it as invoice.xml in the folder you run the
command from.
It also goes on to the tax authority, where it stops with
EARH-4002 — the recipient in it is made up. The one thing that opens the path
all the way is below.
The document content is in English. If the organisation you are testing in has Macedonian as its
default language, take invoice-ubl21.xml instead — same structure, Macedonian content.
Replace this with your own:
| What | Where |
|---|---|
| the sender’s details — the company you send on behalf of | cac:AccountingSupplierParty |
| the document number | cbc:ID |
| the dates | cbc:IssueDate (required) and cbc:DueDate (optional — the sample carries it, you may remove it) |
| the amounts and the line | cac:TaxTotal, cac:LegalMonetaryTotal, cac:InvoiceLine |
Do not change this:
- the three
xmlnsdeclarations on the root, and theInvoiceroot itself - the names and the order of the elements
cbc:InvoiceTypeCode—380is an invoice- the path to the recipient’s tax number, and
cbc:PayableAmountwith itscurrencyID
A PDF attachment is not required. When there is one, it goes as base64 in
cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject with
mimeCode="application/pdf"; an attachment of any other type is skipped without an error.