Create an invoice
The main endpoint — structured JSON in, compliant PINT OM UBL out.
The main endpoint. You send structured JSON; SUMU builds compliant PINT OM UBL, validates it against the Oman rule sets, transmits it to the buyer, and reports it to the Tax Authority. Use this unless you have a specific reason to build UBL yourself — see Send raw UBL.
Check the receiver first
buyer.peppol_id is derived from the VAT number if you don't supply it, but derivation isn't the
same as confirmation — it doesn't tell you the buyer is actually registered on Peppol yet. Call
Participant lookup before sending if you haven't recently; a 404
or unpublished capability here fails after the invoice number is already committed, not before.
/v1/api/invoicesTop-level fields
| Field | Type | Description | |
|---|---|---|---|
| sender_id | uuid | required | The taxpayer issuing this document |
| buyer | object | conditional | The customer. Required for 380, 381, 383, 386 |
| seller | object | conditional | The supplier. Required instead of buyer for self-billed 389, 261 |
| invoice_type_code | enum | required | Document kind — see the table below |
| invoice_transaction_type | string | optional | 20 binary flags. Defaults to a full tax invoice — see below |
| invoice_number | string | optional | Your reference. Generated sequentially if omitted. Must be unique per taxpayer |
| issue_date | date | required | YYYY-MM-DD |
| issue_time | time | required | HH:MM:SS |
| invoice_currency_code | string | required | 3-letter ISO 4217 |
| tax_currency_code | string | conditional | Required when the invoice currency isn't OMR |
| exchange_rate | string | conditional | Required when currency isn't OMR; rejected when it is. Up to 7 decimals |
| vat_point_date | date | optional | When the supply occurred for VAT purposes, if not the issue date |
| payment_due_date | date | conditional | Not permitted on credit notes (381, 261) |
| previous_invoice_reference | string | conditional | Required for corrections — 381, 383, 261 |
| previous_invoice_issue_date | date | conditional | Required with the above |
| previous_invoice_uuid | uuid | conditional | Required with the above — take it from the original transaction |
| reason_for_issuance | string | conditional | Required for corrections. Code from the issuance-reason list, e.g. CAN |
| amount_paid | number | optional | Already paid against this invoice |
| prepayment_invoice_number | string | conditional | Required when amount_paid is present |
| prepayment_invoice_uuid | uuid | conditional | Required when amount_paid is present |
| buyer_reference | string | optional | Purchase order or cost-centre reference |
| invoice_note | string | optional | Free text shown on the document |
| billing_period_start_date | date | optional | For periodic billing |
| billing_period_end_date | date | optional | For periodic billing |
| payment | object | optional | How to pay — see Payment object below |
| items | array | required | At least one line |
| save_as_draft | boolean | optional | true stores and validates without sending. Default false |
Document kinds — invoice_type_code
| Code | Document | Counterparty | Extra requirements |
|---|---|---|---|
380 | Commercial invoice | buyer | — |
381 | Credit note | buyer | Correction fields; no due date |
383 | Debit note | buyer | Correction fields |
386 | Prepayment invoice | buyer | Prepayment flag in the transaction type |
389 | Self-billed invoice | seller | Supplier VAT id mandatory |
261 | Self-billed credit note | seller | Correction fields; supplier VAT id |
Transaction type — invoice_transaction_type (20 binary flags)
A 20-character string of 0 and 1. Position 1 marks a full tax invoice (B2B), position 2 a
simplified one (B2C) — exactly one of the two must be set. Other positions qualify the invoice
further.
| Flag | Meaning | Notes |
|---|---|---|
1 | Full tax invoice (B2B) | Buyer must have a complete address |
2 | Simplified invoice (B2C) | Cannot combine with 3, 5 or 7 |
3 | Self-billed | Required for 389 and 261 |
4 | Third party | |
5 | Summary invoice | |
6 | Continuous supply | |
7 | Export | Typically zero-rated |
8 | Deemed supply | |
15 | Prepayment | Use with 386 |
Example: 10000000000000000000 is an ordinary B2B invoice; 01000000000000000000 is B2C;
10100000000000000000 is a self-billed B2B invoice.
Counterparty object — buyer / seller
| Field | Type | Description | |
|---|---|---|---|
| name | string | required | Legal name of the party |
| vat_number | string | conditional | Mandatory on self-billed documents; strongly recommended on B2B |
| peppol_id | string | optional | Network address, e.g. 0248:OM1100449002. Derived from the VAT number if omitted |
| cr_number | string | optional | Commercial Registration number |
| legal_registration_id | string | optional | Alternative legal identifier |
| buyer_id_scheme | enum | optional | Scheme the legal identifier was issued under |
| contact_name | string | optional | Person or department |
| phone | string | optional | |
| string | optional | ||
| address | object | required | See Address object below |
Address object
| Field | Type | Description | |
|---|---|---|---|
| street | string | required | Street or building |
| address_line_2 | string | conditional | Required on everything except a purely B2C invoice |
| address_line_3 | string | conditional | Required on everything except a purely B2C invoice |
| city | string | required | |
| postal_code | string | conditional | Required on everything except a purely B2C invoice |
| state | string | optional | Governorate |
| country | string | required | 2-letter ISO 3166-1 code |
Address completeness is stricter than base Peppol
On any invoice that isn't purely B2C, all five of street, line 2, line 3, city and postal code must be present. Base Peppol treats the last three as optional, so a payload that's valid elsewhere is rejected here.
Line item object — items[]
| Field | Type | Description | |
|---|---|---|---|
| item_name | string | conditional | Required unless product_id is given |
| product_id | uuid | optional | Pulls name, price and classification from your product catalogue. Any field you also send overrides it |
| description | string | optional | Longer detail shown under the name |
| quantity | number | required | Must be positive |
| unit_code | string | conditional | UN/ECE unit, e.g. H87 piece, HUR hour. Required unless sourced from a product |
| unit_price | number | conditional | Price per unit, before tax. Required unless sourced from a product |
| item_type | enum | optional | GS goods or SV services. Determines which classification applies |
| item_classification_code | string | conditional | 12-digit Oman HS code. Required on goods lines except B2C |
| service_type_code | string | optional | 8-digit service category. Use 00000000 on goods lines |
| industrial_classification_code | string | optional | 6-digit ISIC code for the activity |
| country_of_origin | string | optional | 2-letter code |
| tax_category_code | enum | required | S standard, Z zero, E exempt, O out of scope |
| tax_percent | number | conditional | 5 for standard-rated, 0 for zero-rated, omitted otherwise |
| tax_exemption_reason_code | string | conditional | Required for Z and E. Different code list per category |
| tax_exemption_reason_text | string | optional | Free-text explanation |
| line_allowance_amount | number | optional | Discount on this line |
| line_allowance_percentage | number | optional | Must reconcile with the amount if both are sent |
| line_allowance_reason | string | optional | Why the discount applies |
| line_allowance_reason_code | string | optional | Coded reason |
| gross_price | number | optional | List price before discount |
| price_discount | number | optional | Discount off the list price. gross_price − price_discount must equal unit_price |
| base_quantity | number | optional | Quantity the unit price refers to, when not 1 |
| seller_item_id | string | optional | Your SKU |
| buyer_item_id | string | optional | The customer's item reference |
| line_note | string | optional | Free text on the line |
Payment object
| Field | Type | Description | |
|---|---|---|---|
| means_code | string | required | UN/ECE 4461 code, e.g. 30 credit transfer, 48 card |
| account_id | string | optional | IBAN or account number |
| account_name | string | optional | Account holder |
| bic | string | optional | Bank identifier |
| reference | string | optional | Remittance reference for the payer to quote |
Response fields
| Field | Type | Description | |
|---|---|---|---|
| transaction_id | uuid | — | Track delivery and tax reporting with this |
| document_id | uuid | — | The stored invoice. Use it to fetch the XML or PDF |
| invoice_uuid | uuid | — | The document's own identifier inside the UBL. Quote this as previous_invoice_uuid when crediting it later |
| status | enum | — | Always queued on success — delivery hasn't happened yet |
| totals | object | — | Computed by SUMU from the lines. Compare against your own figures |
202 means accepted, not delivered. The document has passed Oman validation and is queued. Delivery
to the buyer and reporting to the Tax Authority happen within seconds — watch the transaction or
subscribe to webhooks.
Failure · 422
If the document can't be built to a compliant state, nothing is queued and the issues are returned in the same shape as Validate.
{
"statusCode": 422,
"error": {
"code": "SCHEMATRON_INVALID",
"message": "Document failed Oman PINT validation",
"issues": [
{
"severity": "error",
"code": "IBR-019-OM",
"message": "Buyer address line 1, line 2, line 3, city and post code MUST be present...",
"location": "/Invoice/cac:AccountingCustomerParty/cac:Party/cac:PostalAddress"
}
]
}
}Track what happens next in Get a transaction.