Saudi Arabia: request and response examples
Send a Saudi standard tax invoice in GETS and read the validation response. 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. An ordinary B2B invoice takes no modifier, so documentType.modifiers stays empty. For a sale to a consumer, use the simplified_invoice document type instead.
{
"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:
- 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. - Currencies. Set
taxCurrencytoSAR, even whencurrencyis another currency. - VAT numbers. A Saudi VAT number has 15 digits and starts and ends with
3. 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.sa_lineRoundingAmountis the line amount including VAT (KSA-12). The standard rate is 15%, with tax categoryS.
Read the Saudi Arabia field reference for other document types and conditional fields.
Send the request
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 explain where to look up a ZATCA 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. A 200 is not a delivery receipt: follow the document by documentId to check whether ZATCA accepted it.
Last updated