Invoices
Create and send invoices to the UAE Peppol network. The invoice is built from structured data, validated, converted to XML and dispatched. Requires an access token.
/oauth/invoicesAccess tokenPush invoice
Create an invoice for one of your entities. Totals are computed from line items when omitted. Conditional rules: payment_account_id (IBAN) is required while payment_means_code is "30" (credit transfer); for registration type "TL" the issuing/authority name is required, for "PAS" the passport country is required instead.
{
"entity_id": "REPLACE_WITH_ENTITY_ID",
"invoice_number": "INV-1001",
"date": "2026-06-15",
"currency": "AED",
"invoice_type": "Tax Invoice",
"payment_means_code": "30",
"payment_account_id": "AE070331234567890123456",
"seller": {
"registration_type": "TL",
"issuing_authority": "Department of Economic Development - Dubai"
},
"buyer": {
"name": "Buyer LLC",
"trn": "987654321098765",
"country": "United Arab Emirates",
"city": "Dubai",
"email": "ap@buyer.com",
"legal_registration_type": "TL",
"legal_registration_id": "CN-1234567",
"authority_name": "Department of Economic Development - Dubai"
},
"line_items": [
{
"description": "Consulting service",
"quantity": 10,
"unit_amount": 100,
"tax_amount": 50,
"tax_rate": 5,
"tax_category": "S",
"unit": "EA"
}
]
}Body parameters
entity_id | string | required | ID of the seller entity to invoice from. Must belong to your app — get it from GET /oauth/entities. |
invoice_number | string | required | Your unique invoice number. A duplicate number for the same entity is rejected with 409. |
date | string | required | Invoice issue date, formatted YYYY-MM-DD. |
currency | string | optional | ISO 4217 currency code. Defaults to "AED". |
invoice_type | string | optional | Document type: "Tax Invoice" (default), "Credit Note", or "Commercial Invoice". |
due_date | string | optional | Payment due date, YYYY-MM-DD. |
reference | string | optional | Free-text note shown on the invoice. |
payment_means_code | string | optional | UNCL 4461 payment-means code. Defaults to "30". "30" = credit transfer, "10" = cash, "20" = cheque, "48" = bank card, "49" = direct debit. |
payment_account_id | string | conditional | Seller IBAN. Required (IBT-084) when payment_means_code is "30" (credit transfer); otherwise optional. |
payment_method | string | optional | Legacy human-readable label (e.g. "Credit Transfer"). Used only when payment_means_code is empty. |
exchange_rate | number | optional | Exchange rate to AED. Provide when currency is not AED. |
transaction_type_code | string | optional | UAE transaction type code. Defaults to "00000000". |
sub_total | number | optional | Taxable amount (sum of line net amounts). Computed from line_items when omitted. |
total_tax | number | optional | Total VAT (sum of line tax amounts). Computed from line_items when omitted. |
total | number | optional | Grand total (sub_total + total_tax). Computed when omitted. |
seller | object | conditional | Seller legal-registration details (BTUAE-15). Required when the seller electronic-ID scheme is "0235". Not stored on the entity, so passed per-invoice. |
seller.registration_type | string | conditional | "TL" = trade license, "PAS" = passport. |
seller.issuing_authority | string | conditional | Authority that issued the trade license. Required when seller.registration_type is "TL". |
seller.passport_country | string | conditional | Passport-issuing country. Required when seller.registration_type is "PAS". |
buyer | object | required | Buyer (customer) details. |
buyer.name | string | required | Buyer legal name. |
buyer.trn | string | required | Buyer Tax Registration Number (15 digits). |
buyer.country | string | required | Buyer country — name or ISO 3166-1 alpha-2 (e.g. "AE"). |
buyer.address_line1 | string | optional | Buyer street address. |
buyer.city | string | optional | Buyer city. |
buyer.region | string | optional | Buyer emirate / state. |
buyer.email | string | optional | Buyer accounts-payable email. |
buyer.phone | string | optional | Buyer phone number. |
buyer.electronic_address | string | optional | Buyer Peppol electronic address. |
buyer.legal_registration_id | string | optional | Buyer legal registration ID (IBT-047), e.g. trade-license number. |
buyer.legal_registration_type | string | optional | "TL" = trade license, "PAS" = passport (BTUAE-16). |
buyer.authority_name | string | conditional | Authority that issued the registration. Required when buyer.legal_registration_type is "TL". |
buyer.passport_country_code | string | conditional | Passport-issuing country code. Required when buyer.legal_registration_type is "PAS". |
line_items | array | required | Invoice line items. At least one is required. |
line_items[].description | string | required | Line description. |
line_items[].quantity | number | required | Quantity. |
line_items[].unit_amount | number | required | Net unit price (must be > 0). |
line_items[].tax_amount | number | required | VAT amount for this line. |
line_items[].line_amount | number | optional | Net line amount. Computed as quantity × unit_amount when omitted. |
line_items[].tax_rate | number | optional | VAT percentage, e.g. 5. |
line_items[].tax_category | string | optional | Tax category code: S (standard), Z (zero), E (exempt), O (out of scope), AE (reverse charge). Defaults to "S". |
line_items[].unit | string | optional | Unit of measure (UN/ECE Rec 20 code or label). Defaults to "EA". |
line_items[].discount_percent | number | optional | Line discount percentage. |
line_items[].account_code | string | optional | Accounting code. Defaults to "200". |
line_items[].item_name | string | optional | Item name. |
line_items[].item_type | string | optional | Item type. |
line_items[].hs_code | string | optional | HS commodity code (for goods). |
line_items[].service_code | string | optional | Service classification code (for services). |
/oauth/invoices/bulkAccess tokenPush multiple invoices
Send multiple invoices in a single request. Each invoice is processed independently — one failure does not block the others. Returns HTTP 207 Multi-Status with a per-item results array containing the invoice_number, status_code, and the same fields as the single-invoice response.
{
"invoices": [
{
"entity_id": "REPLACE_WITH_ENTITY_ID",
"invoice_number": "INV-1001",
"date": "2026-06-15",
"currency": "AED",
"invoice_type": "Tax Invoice",
"payment_means_code": "30",
"payment_account_id": "AE070331234567890123456",
"seller": {
"registration_type": "TL",
"issuing_authority": "Department of Economic Development - Dubai"
},
"buyer": {
"name": "Buyer LLC",
"trn": "987654321098765",
"country": "United Arab Emirates",
"city": "Dubai",
"email": "ap@buyer.com",
"legal_registration_type": "TL",
"legal_registration_id": "CN-1234567",
"authority_name": "Department of Economic Development - Dubai"
},
"line_items": [
{
"description": "Consulting service",
"quantity": 10,
"unit_amount": 100,
"tax_amount": 50,
"tax_rate": 5,
"tax_category": "S",
"unit": "EA"
}
]
}
]
}Body parameters
invoices | array | required | List of invoices to send. At least one is required. Each item follows the same schema as POST /oauth/invoices — see Push invoice for the full field reference. |
invoices[].entity_id | string | required | ID of the seller entity. Must belong to your app. |
invoices[].invoice_number | string | required | Unique invoice number per entity. A duplicate is rejected with status_code 409 in the results. |
invoices[].date | string | required | Invoice issue date, YYYY-MM-DD. |
invoices[].buyer | object | required | Buyer details. See Push invoice for the full buyer field list. |
invoices[].line_items | array | required | Invoice line items. At least one required per invoice. |
/oauth/invoices/{invoice_id}Access tokenUpdate & resend an invoice
Update the data of an invoice and re-queue it for processing (validate → XML → deliver to Peppol). Only allowed while the invoice has NOT been delivered to the Peppol network — i.e. it is still queued or it failed at validation, XML conversion or dispatch. An invoice that was already sent to Peppol is immutable and returns 409. The body uses the SAME schema as Push invoice (a full invoice payload, not a partial patch) and is validated with the same rules. The identifying fields entity_id and invoice_number cannot be changed — they must match the values the invoice was created with, otherwise the request is rejected with 400. On success the invoice status becomes PROCESSING and it is queued again for sending.
Path parameters
invoice_id | Invoice id (the `_id` returned by Push invoice / List sent invoices). |
{
"entity_id": "SAME_ENTITY_ID_AS_CREATED",
"invoice_number": "INV-1001",
"date": "2026-06-15",
"currency": "AED",
"invoice_type": "Tax Invoice",
"payment_means_code": "30",
"payment_account_id": "AE070331234567890123456",
"seller": {
"registration_type": "TL",
"issuing_authority": "Department of Economic Development - Dubai"
},
"buyer": {
"name": "Buyer LLC",
"trn": "987654321098765",
"country": "United Arab Emirates",
"city": "Dubai",
"email": "ap@buyer.com",
"legal_registration_type": "TL",
"legal_registration_id": "CN-1234567",
"authority_name": "Department of Economic Development - Dubai"
},
"line_items": [
{
"description": "Consulting service",
"quantity": 10,
"unit_amount": 100,
"tax_amount": 50,
"tax_rate": 5,
"tax_category": "S",
"unit": "EA"
}
]
}Body parameters
entity_id | string | required | Immutable — must be the same entity_id the invoice was created with. Sending a different value returns 400. |
invoice_number | string | required | Immutable — must be the same invoice_number the invoice was created with. Sending a different value returns 400. |
date | string | required | Invoice issue date, YYYY-MM-DD. |
buyer | object | required | Buyer details. Same schema as Push invoice — see Push invoice for the full buyer field list. |
line_items | array | required | Invoice line items. At least one is required. Same schema as Push invoice — see Push invoice for the full line-item field list. |
(all other fields) | — | optional | Every other field (currency, seller, payment_means_code, totals, …) follows exactly the same schema, defaults and conditional rules as POST /oauth/invoices — see Push invoice for the full field reference. |
/oauth/invoices/sentAccess tokenList sent invoices
Return invoices SENT by your application. An app can own many users and entities, so narrow the results with entity_id and/or user_id.
Query parameters
entity_id | Filter to invoices sent from a single entity (its id from GET /oauth/entities). |
user_id | Filter to invoices owned by a single user (its id from GET /oauth/users). |
page | Page number. Defaults to 1. |
limit | Page size, 1–100. Defaults to 20. |
/oauth/invoices/sent/{invoice_id}Access tokenGet a sent invoice
Fetch a single sent invoice (including its full status history).
/oauth/invoices/receivedAccess tokenList received invoices
Return invoices RECEIVED over the Peppol network for your entities (delivered via Billberry). Read-only. An app can own many users and entities, so narrow the results with entity_id and/or user_id.
Query parameters
entity_id | Filter to invoices received by a single entity (its id from GET /oauth/entities). |
user_id | Filter to entities owned by a single user (its id from GET /oauth/users). |
page | Page number. Defaults to 1. |
limit | Page size, 1–100. Defaults to 20. |
/oauth/invoices/received/{invoice_id}Access tokenGet a received invoice
Fetch a single received invoice (including its full status history) by its Billberry id.
Path parameters
invoice_id | Billberry invoice id (the `id` field from the received-invoices list). |