Saudi Arabia: request and response examples
Send Saudi standard, simplified and export invoices in GETS and read each response up to ZATCA's result. Start with a sandbox API key and a Saudi company's onboarded source.
Save the request
Save this body as saudi-invoice.json. It is a standard tax invoice from one VAT-registered business to another, with one line at the 15% standard rate. ZATCA clears a standard invoice; see clearance and reporting.
{
"country": "SA",
"environment": "sandbox",
"purpose": "invoicing",
"source": "acme-erp:1.0.0",
"documentType": { "base": "tax_invoice", "modifiers": [] },
"payload": {
"header": {
"documentType": { "base": "tax_invoice" },
"documentNumber": "SA-2026-00309",
"uuid": "3f6c2a9e-8b41-4d7a-9c25-6e1f0b7d4a83",
"issueDate": "2026-09-30",
"issueTime": "10:15:00",
"currency": "SAR",
"taxCurrency": "SAR"
},
"parties": {
"seller": {
"name": "Najd Supplies Co.",
"address": {
"addressLine1": "King Fahd Road",
"city": "Riyadh",
"postalCode": "12345",
"country": "SA",
"additionalAddressData": {
"buildingNumber": "1234",
"district": "Al Olaya"
}
},
"taxIds": [{ "type": "VAT", "value": "310123456700003" }],
"registrationNumbers": [{ "type": "CRN", "value": "1010123456" }]
},
"buyer": {
"name": "Riyadh Foods LLC",
"address": {
"addressLine1": "Prince Sultan Street",
"city": "Jeddah",
"postalCode": "23456",
"country": "SA",
"additionalAddressData": {
"buildingNumber": "4321",
"district": "Al Rawdah"
}
},
"taxIds": [{ "type": "VAT", "value": "300987654300003" }],
"registrationNumbers": [{ "type": "CRN", "value": "4030123456" }]
},
"delivery": { "deliveries": [{ "actualDeliveryDate": "2026-09-30" }] }
},
"lineItems": [
{
"id": "1",
"name": "Office chairs",
"quantity": 20,
"unitCode": "PCE",
"price": { "amount": 250 },
"lineTaxableValue": 5000,
"taxCategory": "S",
"taxRate": 15,
"taxAmount": 750,
"lineTotal": 5000,
"extensions": { "sa_lineRoundingAmount": 5750 }
}
],
"taxTotals": [
{
"taxAmount": 750,
"taxSubtotals": [
{
"taxableAmount": 5000,
"taxAmount": 750,
"taxCategory": "S",
"percent": 15
}
]
}
],
"totals": {
"totalLineTaxableAmount": 5000,
"totalAmountExcludingTax": 5000,
"totalTaxAmount": 750,
"totalAmountIncludingTax": 5750,
"amountDue": 5750
},
"extensions": { "sa_icv": "27" }
}
}Replace source with the Saudi company’s own name:version, and use an unused documentNumber. Keep environment: "sandbox" with a sandbox key. These values are specific to Saudi Arabia:
- Document type. The envelope’s
documentTypedecides which rules apply and which ZATCA invoice type is produced. Complyance copies it intopayload.header.documentType, replacing any value there, so the two never disagree. An ordinary B2B invoice takes no modifier, somodifiersstays empty. - Invoice identity.
header.uuidis the invoice’s unique identifier (ZATCA field KSA-1); use a new UUID for every invoice.extensions.sa_icvis the invoice counter value (KSA-16), digits only (BR-KSA-33, BR-KSA-34): the number of the invoice in the sequence your system issues. - Issue time.
issueTimeishh:mm:ssin Saudi local time, such as10:15:00, orhh:mm:ssZin UTC, such as07:15:00Z(ZATCA rule BR-KSA-70). - Currencies. Set
taxCurrencytoSAR, even whencurrencyis another currency. - VAT numbers. A Saudi VAT number has 15 digits and starts and ends with
3(ZATCA rules BR-KSA-40 and BR-KSA-44). The seller also needs one registration number, such as aCRN(commercial registration number). - Addresses. A Saudi address needs a street (
addressLine1), a four-digitbuildingNumber, a five-digitpostalCode, the city, thedistrictand the country. - Supply date.
parties.delivery.deliveries[].actualDeliveryDateis the date the goods or services were supplied. - Line amounts.
lineTotalis the line amount before VAT (BT-131).sa_lineRoundingAmountis the line amount including VAT (KSA-12). A standard-rated line uses tax categoryS; ZATCA rule BR-KSA-84 accepts only 15 or 5 as its rate. - What you leave out. Do not send
sa_pih,sa_qrCodeorsa_digitalSignature. Complyance adds the previous invoice hash, signs the invoice with the company’s cryptographic stamp and adds the QR code; see what is added for you.
The field reference lists the fields for every document type.
Send the request
Sandbox and production use the same host, https://prod.gets.complyance.io. The "environment": "sandbox" field in the request body is what sends this invoice to sandbox.
curl --request POST 'https://prod.gets.complyance.io/api/v3/unify' \
--header "Authorization: Bearer ${COMPLYANCE_API_KEY}" \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'new-api: true' \
--data @saudi-invoice.jsonRead the response
HTTP 200 means the invoice passed validation and was stored. This illustrative response includes a short Base64-encoded XML fragment to show the shape; the actual Base64XML contains the generated invoice, not this fragment.
{
"documentId": "01K6EXAMPLE00000000000309",
"documentNumber": "SA-2026-00309",
"message": "Your invoice was validated and is ready for submission.",
"Base64XML": "PEludm9pY2U+PElEPlNBLTIwMjYtMDAzMDk8L0lEPjwvSW52b2ljZT4="
}If the request returns HTTP 422, inspect every entry in errors. This sample shows the response for a request sent without the buyer’s building number. BR-KSA-* codes are ZATCA’s published rule identifiers; the messages in your response can differ.
{
"documentId": "01K6EXAMPLE00000000000310",
"documentNumber": "SA-2026-00309",
"message": "Your invoice could not be validated. Review the errors and try again.",
"validationStage": "gets",
"errors": [
{
"code": "BR-KSA-63",
"getsPath": "parties.buyer.address",
"payloadPath": "parties.buyer.address",
"message": "If buyer country code is SA, buyer address must contain street, building number, postal code, city, district, and country code.",
"severity": "error",
"ruleSet": "sa:tax_invoice"
}
]
}Correct the field named by getsPath, then send the request again. The Saudi Arabia validation rules list every rule. For 404, confirm your source name and version; for 403, check that the key’s environment matches environment. See Unify errors for other statuses.
Check ZATCA’s result
A 200 is not ZATCA’s answer. Follow the document by documentId, as described in Submit and retrieve, until isTerminal is true. This response is shortened: artifacts and the rest of ZATCA’s answer in government are left out.
{
"success": true,
"data": {
"documentId": "01K6EXAMPLE00000000000309",
"documentNumber": "SA-2026-00309",
"country": "SA",
"environment": "sandbox",
"state": "final_valid",
"isTerminal": true,
"lastUpdatedAt": "2026-09-30T07:15:09.000Z",
"errors": [],
"government": { "status": "CLEARED" },
"validationResults": {
"status": "Valid",
"validationSteps": [
{ "name": "Validation Passed", "status": "Valid", "error": null },
{ "name": "Queue Admitted", "status": "Valid", "error": null },
{
"name": "Delivery Processing Started",
"status": "Valid",
"error": null
},
{ "name": "Final Valid", "status": "Valid", "error": null }
]
}
}
}state final_valid with government.status CLEARED means ZATCA cleared the standard invoice. WARNED means ZATCA accepted it with warnings, which government lists. REJECTED, with state final_invalid, means ZATCA refused it; read its reasons in government, then correct the invoice and send it as a new document.
Other document types
Each request below is complete and passes Unify’s validation as written. Send it the same way and follow it to its final status.
Simplified invoice (B2C)
A simplified tax invoice is a sale to a consumer. ZATCA does not clear it: Complyance reports it to ZATCA after you send it. ZATCA rule BR-KSA-98 asks for the report within 24 hours of the issue date and time, so send each simplified invoice as soon as you issue it.
{
"country": "SA",
"environment": "sandbox",
"purpose": "invoicing",
"source": "acme-erp:1.0.0",
"documentType": { "base": "simplified_invoice", "modifiers": [] },
"payload": {
"header": {
"documentType": { "base": "simplified_invoice" },
"documentNumber": "SA-2026-S-01187",
"uuid": "8d1f6c3a-2b7e-4f95-a0c4-5e9b3d72f1a6",
"issueDate": "2026-09-30",
"issueTime": "16:42:10",
"currency": "SAR",
"taxCurrency": "SAR"
},
"parties": {
"seller": {
"name": "Najd Supplies Co.",
"address": {
"addressLine1": "King Fahd Road",
"city": "Riyadh",
"postalCode": "12345",
"country": "SA",
"additionalAddressData": {
"buildingNumber": "1234",
"district": "Al Olaya"
}
},
"taxIds": [{ "type": "VAT", "value": "310123456700003" }],
"registrationNumbers": [{ "type": "CRN", "value": "1010123456" }]
},
"buyer": {
"name": "Retail customer",
"registrationNumbers": [{ "type": "OTH", "value": "CUST-55021" }]
}
},
"lineItems": [
{
"id": "1",
"name": "Desk lamp",
"quantity": 2,
"unitCode": "PCE",
"price": { "amount": 120 },
"lineTaxableValue": 240,
"taxCategory": "S",
"taxRate": 15,
"taxAmount": 36,
"lineTotal": 240,
"extensions": { "sa_lineRoundingAmount": 276 }
}
],
"taxTotals": [
{
"taxAmount": 36,
"taxSubtotals": [
{
"taxableAmount": 240,
"taxAmount": 36,
"taxCategory": "S",
"percent": 15
}
]
}
],
"totals": {
"totalLineTaxableAmount": 240,
"totalAmountExcludingTax": 240,
"totalTaxAmount": 36,
"totalAmountIncludingTax": 276,
"amountDue": 276
},
"extensions": { "sa_icv": "1187" }
}
}documentType.baseissimplified_invoice.- The buyer needs no VAT number, but Unify asks for a buyer identifier (BR-KSA-14). Send the customer’s identifier in
registrationNumberswith one of the schemes the rule lists, such asOTH. - Unify’s response can carry warnings for the QR code (BR-KSA-27) and the cryptographic stamp (BR-KSA-60). Complyance adds both before the invoice reaches ZATCA, so you do not need to act on them.
When ZATCA has received the report, the document’s government.status is REPORTED and state is final_valid.
Export invoice
An export invoice is a zero-rated sale to a buyer outside Saudi Arabia. Add the export modifier, use tax category Z at 0, and give the exemption reason code and text in the tax breakdown. The buyer has no Saudi VAT number, so send another buyer identifier (BR-KSA-81). An export invoice also needs header.exchangeRate; when the invoice is in SAR, the rate is 1.
{
"country": "SA",
"environment": "sandbox",
"purpose": "invoicing",
"source": "acme-erp:1.0.0",
"documentType": { "base": "tax_invoice", "modifiers": ["export"] },
"payload": {
"header": {
"documentType": { "base": "tax_invoice", "modifiers": ["export"] },
"documentNumber": "SA-2026-E-00072",
"uuid": "5b9e0d47-1c6a-4e2f-8b3d-7a4c9f12e608",
"issueDate": "2026-09-30",
"issueTime": "10:15:00",
"currency": "SAR",
"taxCurrency": "SAR",
"exchangeRate": { "rate": 1, "sourceCurrency": "SAR", "targetCurrency": "SAR" }
},
"parties": {
"seller": {
"name": "Najd Supplies Co.",
"address": {
"addressLine1": "King Fahd Road",
"city": "Riyadh",
"postalCode": "12345",
"country": "SA",
"additionalAddressData": {
"buildingNumber": "1234",
"district": "Al Olaya"
}
},
"taxIds": [{ "type": "VAT", "value": "310123456700003" }],
"registrationNumbers": [{ "type": "CRN", "value": "1010123456" }]
},
"buyer": {
"name": "Gulf Retail FZE",
"address": {
"addressLine1": "Sheikh Zayed Road",
"city": "Dubai",
"postalCode": "00000",
"country": "AE"
},
"registrationNumbers": [{ "type": "OTH", "value": "DXB-CL-884213" }]
},
"delivery": { "deliveries": [{ "actualDeliveryDate": "2026-09-30" }] }
},
"lineItems": [
{
"id": "1",
"name": "Office chairs",
"quantity": 20,
"unitCode": "PCE",
"price": { "amount": 250 },
"lineTaxableValue": 5000,
"taxCategory": "Z",
"taxRate": 0,
"taxAmount": 0,
"lineTotal": 5000,
"extensions": { "sa_lineRoundingAmount": 5000 }
}
],
"taxTotals": [
{
"taxAmount": 0,
"taxSubtotals": [
{
"taxableAmount": 5000,
"taxAmount": 0,
"taxCategory": "Z",
"percent": 0,
"taxExemptionReasonCode": "VATEX-SA-32",
"taxExemptionReason": "Export of goods"
}
]
}
],
"totals": {
"totalLineTaxableAmount": 5000,
"totalAmountExcludingTax": 5000,
"totalTaxAmount": 0,
"totalAmountIncludingTax": 5000,
"amountDue": 5000
},
"extensions": { "sa_icv": "28" }
}
}ZATCA clears an export invoice like any standard invoice: government.status is CLEARED when it is accepted.
Last updated