Imports and customs data
Imports โ the customs data is requiredโ
An import you record yourself (om_invoice_kind import_goods or import_services_rcm, through
the API, a CSV or Excel import or the portal) must carry the data the Tax Authority requires.
Supply every value below yourself. Do not leave one out and assume GoRoute will either reject
the document or work the value out โ check, as described under the table.
om_invoice_kind | Required | Field |
|---|---|---|
import_goods | Import date (BTOM-030) | import_date |
import_goods | Customs declaration (bayan) number (BTOM-021) | customs_declaration_number |
import_goods | Incoterms (BTOM-022), as on the declaration | incoterms |
import_goods | Your Importer Customs ID (IBR-153-OM) | buyer.identifier, with buyer.identifier_scheme ICID |
import_goods | Each line's country of origin (IBR-084-OM) | lines[n].origin_country |
import_goods | Whether each line is goods or services (BTOM-019): G with its HS code, or S. A line with an HS code and no item_type is goods | lines[n].item_type (and lines[n].hs_code for goods) |
| both | The foreign supplier's country | seller.address.country |
An import of services under reverse charge (import_services_rcm) needs only the supplier's
country from this list. Everything else in the table applies to an import of goods.
Check before you rely on it. Send the import to POST /api/v1/invoices/validate. A value that
is missing comes back as validation error BUS_031 โ one error per missing value, with field
set to the field named in the table and a message that says which value it is. The same
validation runs on every path that sends: POST /api/v1/invoices, /preview-xml, a CSV or Excel
import row, and sending a draft (refused with HTTP 400, carrying the same sentences). So what
/validate tells you is what the other paths will do with the same document.
If /validate accepts an import that leaves these fields empty, they are being filled in for
you, and you should not file it. The values used are NA as the customs declaration (bayan)
number, CIF as the Incoterms, the issue date as the import date, NA as each line's country of
origin, your own VAT number (or your Peppol identifier) as the Importer Customs ID under scheme
ICID, and Oman as the foreign supplier's country; a line with neither an item_type nor an HS
code is taken as services. Two of those are worse than blank rather than merely wrong: NA is
Namibia's ISO 3166-1 country code, so a line reads as originating in Namibia, and an Importer
Customs ID that is really your VAT number identifies you to the Tax Authority under the wrong
scheme. Supply the values either way.
On a CSV or Excel import, check the supplier columns the same way. The seller of an import is the
foreign supplier, not you. If a row with the seller_* columns left blank is accepted, the
supplier is being merged from your own company profile โ your Omani country, your VAT number and
your Peppol identifier โ and a supplier address with no country is written as US. Fill
seller_name, seller_country and seller_identifier on every import row.
Name the foreign invoice the import recordsโ
This is separate from the table above, and it is important that you read it that way. The table lists what the Oman Tax Authority requires. The three fields below are GoRoute's own requirement, not the Authority's: nothing in an Oman Tax Authority publication asks for them. We ask for them so that one foreign invoice is recorded once. Your organisation, the foreign supplier's identifier, and the foreign invoice's own number and date together identify a single foreign invoice, which is how we can tell a genuine second import from the same import keyed twice.
They apply to both import kinds โ import_goods and import_services_rcm.
| Field | What to put in it |
|---|---|
foreign_invoice_number | The foreign supplier's own invoice number for the invoice this import records. Up to 150 characters. |
foreign_invoice_date | The issue date of that foreign supplier's invoice. |
supplier_identifier | The foreign supplier's identifier as its own invoice states it โ for example its tax number or its company registration number. Up to 100 characters. |
Today a missing value is accepted, not refused. If you leave one of the three out, the document goes through exactly as it did before and GoRoute logs a line on our side naming what was missing. You will see nothing in the API response, so do not treat a successful send as evidence that you supplied them.
That is planned to change. When enforcement is switched on, an import that leaves any of the
three empty is refused with validation error BUS_032 โ one error per missing field, with
field set to the field's own name and a message saying which value is missing. Supplying all
three now is what stops that change from breaking your integration later. GoRoute will tell
integrators that post imports before the switch is made.
Nothing is written into the XML from them yet. They are a reference we hold against the record; they do not appear in the UBL document that goes to the Tax Authority, so adding them changes nothing about the document you are already sending.
On a CSV or Excel import, the columns are foreign_invoice_number (also accepted as
foreign_invoice_no or supplier_invoice_number), foreign_invoice_date (also
supplier_invoice_date) and supplier_identifier (also foreign_supplier_identifier).
supplier_identifier is not the seller_identifier columnThey are different things and both belong on an import row. seller_identifier โ named at the end
of the section above โ identifies the foreign supplier as a party on the document: it is
required by rule IBR-007-OM, it is paired with seller_identifier_scheme from the Oman code list
CL-06-OM, and it is written into the UBL. supplier_identifier is the identifier that supplier
prints on the invoice you are recording, copied as it appears there; it stays with the record
and is not written into the UBL. Filling one does not fill the other.
An import that reaches you over Peppolโ
The Tax Authority's rule is in the Solution Architecture v1.0.3, section 6.5 and Table 3 row 12. A foreign supplier's invoice that reaches an Omani buyer over Peppol cannot itself be used to produce the tax data document (TDD). Instead, the buyer's service provider, as the receiving access point (C3), builds a separate self-billed PINT OM invoice from it. It never sends that invoice to the supplier, and reports the TDD of the self-billed invoice to the Tax Authority. The foreign invoice itself is never reported. This applies to an import of goods and to an import of services under reverse charge alike.
The self-billed invoice needs data the foreign invoice does not carry: for an import of goods,
the customs data in the table above. A received import therefore
waits for that data before anything is filed โ its status is awaiting_buyer_data โ and you
supply the missing data through the imports API below.
If you both receive imports over Peppol and record them yourself, you do not need to contact support to avoid a double report. One foreign invoice is filed once: your organisation together with the foreign supplier's identifier and that invoice's own number and date identifies a single foreign invoice, and a second record of the same one is given the first one's Tax Data Document. The three fields that make that work are described under Name the foreign invoice the import records.
The imports API โ see your imports and complete the ones that are waitingโ
Three calls drive the whole path. Every one of them needs your API key.
| Call | What it does |
|---|---|
POST /api/v1/oman/imports | Records a foreign supplier's invoice you received as a PDF or by email, so GoRoute files it as a self-billed import |
GET /api/v1/oman/imports | Lists your imports, newest first โ the ones received over Peppol and the ones you recorded โ each with its status, the reason it is waiting and what is missing |
PATCH /api/v1/oman/imports/{transaction_id} | Supplies the data an import is waiting for, after which GoRoute files it |
Check whether the path is open for you, in one callโ
Call GET /api/v1/oman/imports and read the status code. It answers the question for the exact
GoRoute platform you are calling, which is the only answer worth having:
| Status | What it means |
|---|---|
200 | Oman imports are switched on for you. The body lists your imports; an empty items list simply means you have none yet |
409 with error_code IMPORT_SB_NOT_LIVE | GoRoute has built the path but it is not switched on for your platform yet. Nothing you send is recorded and nothing is filed |
404 | The Oman pack is not enabled on the host you called at all. Check the base URL |
Treat that check as authoritative over anything this page says about availability.
Recording a foreign invoice yourselfโ
POST /api/v1/oman/imports does not take a bare invoice. The body is a wrapper: the invoice
goes under invoice, and the foreign invoice's PDF goes beside it under pdf. Both are required.
{
"invoice": { "om_invoice_kind": "import_goods", "number": "SB-2026-0041" },
"pdf": { "filename": "supplier-inv-4471.pdf", "content_base64": "JVBERi0xLjQK..." },
"rate": 0.385,
"rate_date": "2026-09-28"
}
invoice(required) โ the import as an ordinary invoice body, whoseom_invoice_kindisimport_goodsorimport_services_rcm. It carriesforeign_invoice_number,foreign_invoice_dateandsupplier_identifierโ the three fields described above โ and the customs data from the table above.pdf(required) โ the foreign invoice as you received it, as an object withfilenameandcontent_base64(the PDF, base64 encoded). GoRoute attaches it to the record for you and sends it to no one: the self-billed PINT OM document GoRoute files carries no attachments. Do not put the PDF in the invoice's ownattachmentsinstead โpdfis a field of the request, not of the invoice, and a body without it is refused.rateandrate_dateโ for an invoice not in OMR:rateis OMR per one unit of the invoice's currency. Both sit besideinvoice, not inside it. GoRoute looks no rate up. Without one the import is refused.
A successful call answers 202. The record is issued and its one job is the tax report โ
nothing is transmitted to the foreign supplier.
Anything the Tax Authority would refuse comes back as 422 with every finding named, and
nothing is recorded. That is deliberate: a recorded import never sits waiting for data this API
cannot take.
Completing an import that is waitingโ
GET /api/v1/oman/imports?status=awaiting_buyer_data lists only the imports waiting for you.
limit (1โ200, default 50) and offset page the list. Each entry gives you transaction_id,
source (received over Peppol, or recorded by you), status, reason_code, reason, the
findings it is waiting on, the three foreign-invoice fields, tdd_transaction_id once a report
exists, deadline_at, and before_reporting_cutoff.
Send the missing data to PATCH /api/v1/oman/imports/{transaction_id}. Only the fields you give
are changed. For an import received over Peppol you can supply the customs data, your Importer
Customs ID, the VAT due (per line where it differs), the exchange rate for a document not in OMR,
your own self-billing number and the self-billed import a credit note corrects. For an import you
recorded yourself, the call takes the customs data, each line's origin, HS code and goods/services
marker, and the exchange rate โ the other fields belong to a received invoice only and are
refused with 422.
Both kinds also take what the Tax Authority requires and the foreign invoice may not give, which GoRoute does not make up: the supplier's telephone and address as its invoice states them, and your own street, city and postal code. Only the fields you give change.
{
"customs_declaration_number": "MCT-2026-0101010",
"seller": { "phone": "+49 40 3000 0000", "address": { "postal_code": "20457" } },
"importer": { "identifier": "IC-2026-004455", "identifier_scheme": "ICID",
"address": { "street": "Way 3021", "city": "Muscat", "postal_code": "112" } }
}
A successful call answers 202 and GoRoute files the import: one Tax Data Document per
foreign invoice. Two refusals are worth handling explicitly:
422โ the data would still be refused by the Tax Authority. Every finding is named and nothing is changed.409witherror_codeIMPORT_BEFORE_REPORTING_CUTOFFโ the import was created before your platform's reporting cut-off date, so it is never filed. Nothing is changed.
Where the outcome arrivesโ
There are no import-specific webhook events. The import's reporting leg sends the ordinary
tax-authority events โ authority.held while it waits for you, carrying the wait's reason code,
then authority.submitted, authority.acknowledged or authority.rejected โ which are the same
events described under Configure Webhooks. The report itself is
readable through the ordinary reporting call described under
Reporting status for one transaction: a sent import
record's import Tax Data Document is its TDD.
Every address, field, status code and error code above was read from the GoRoute source that implements them and from the test service's own published interface. It was not produced by calling these three endpoints โ this office holds no API key. The one-call check under Check whether the path is open for you is therefore also your protection against this page being wrong.