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

> **Before you start**
>
> You need a [sandbox API key](https://docs.complyance.io/api-reference/authentication/) and a Saudi company with a source that is ready to send invoices. Replace the example source and all sample names, VAT numbers, registration numbers and addresses with the real values for your company and buyer. The identifiers below are illustrative.

## 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](https://docs.complyance.io/countries/sa/#clearance-and-reporting).

```json title="saudi-invoice.json"
{
  "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 `documentType` decides which rules apply and which ZATCA invoice type is produced. Complyance copies it into `payload.header.documentType`, replacing any value there, so the two never disagree. An ordinary B2B invoice takes no modifier, so `modifiers` stays empty.
- **Invoice identity.** `header.uuid` is the invoice’s unique identifier (ZATCA field KSA-1); use a new UUID for every invoice. `extensions.sa_icv` is the invoice counter value (KSA-16), digits only ([BR-KSA-33](https://docs.complyance.io/countries/sa/validation-rules/), [BR-KSA-34](https://docs.complyance.io/countries/sa/validation-rules/)): the number of the invoice in the sequence your system issues.
- **Issue time.** `issueTime` is `hh:mm:ss` in Saudi local time, such as `10:15:00`, or `hh:mm:ssZ` in UTC, such as `07:15:00Z` (ZATCA rule BR-KSA-70).
- **Currencies.** Set `taxCurrency` to `SAR`, even when `currency` is 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 a `CRN` (commercial registration number).
- **Addresses.** A Saudi address needs a street (`addressLine1`), a four-digit `buildingNumber`, a five-digit `postalCode`, the city, the `district` and the country.
- **Supply date.** `parties.delivery.deliveries[].actualDeliveryDate` is the date the goods or services were supplied.
- **Line amounts.** `lineTotal` is the line amount before VAT (BT-131). `sa_lineRoundingAmount` is the line amount including VAT (KSA-12). A standard-rated line uses tax category `S`; ZATCA rule BR-KSA-84 accepts only 15 or 5 as its rate.
- **What you leave out.** Do not send `sa_pih`, `sa_qrCode` or `sa_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](https://docs.complyance.io/countries/sa/#what-you-send-and-what-is-added-for-you).

The [field reference](https://docs.complyance.io/countries/sa/fields/) 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.

```bash title="Submit a Saudi invoice in 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.json
```

## Read 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.

```json title="Validated invoice — HTTP 200"
{
  "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.

```json title="Incomplete buyer address — HTTP 422"
{
  "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](https://docs.complyance.io/countries/sa/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](https://docs.complyance.io/api-reference/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](https://docs.complyance.io/api-reference/unify/submit-and-retrieve/#follow-the-document), until `isTerminal` is `true`. This response is shortened: `artifacts` and the rest of ZATCA’s answer in `government` are left out.

```json title="Cleared by ZATCA — HTTP 200"
{
  "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.

```json title="saudi-simplified-invoice.json"
{
  "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.base` is `simplified_invoice`.
- The buyer needs no VAT number, but Unify asks for a buyer identifier (BR-KSA-14). Send the customer’s identifier in `registrationNumbers` with one of the schemes the rule lists, such as `OTH`.
- 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`.

```json title="saudi-export-invoice.json"
{
  "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 16 October 2026

Source: https://docs.complyance.io/countries/sa/examples/
