Skip to main content

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_kindRequiredField
import_goodsImport date (BTOM-030)import_date
import_goodsCustoms declaration (bayan) number (BTOM-021)customs_declaration_number
import_goodsIncoterms (BTOM-022), as on the declarationincoterms
import_goodsYour Importer Customs ID (IBR-153-OM)buyer.identifier, with buyer.identifier_scheme ICID
import_goodsEach line's country of origin (IBR-084-OM)lines[n].origin_country
import_goodsWhether 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 goodslines[n].item_type (and lines[n].hs_code for goods)
bothThe foreign supplier's countryseller.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.

FieldWhat to put in it
foreign_invoice_numberThe foreign supplier's own invoice number for the invoice this import records. Up to 150 characters.
foreign_invoice_dateThe issue date of that foreign supplier's invoice.
supplier_identifierThe 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 column

They 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.

CallWhat it does
POST /api/v1/oman/importsRecords 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/importsLists 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:

StatusWhat it means
200Oman 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_LIVEGoRoute has built the path but it is not switched on for your platform yet. Nothing you send is recorded and nothing is filed
404The 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, whose om_invoice_kind is import_goods or import_services_rcm. It carries foreign_invoice_number, foreign_invoice_date and supplier_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 with filename and content_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 own attachments instead โ€” pdf is a field of the request, not of the invoice, and a body without it is refused.
  • rate and rate_date โ€” for an invoice not in OMR: rate is OMR per one unit of the invoice's currency. Both sit beside invoice, 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.
  • 409 with error_code IMPORT_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.

How this section was verified

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.