ZATCA Integration API — Documentation

What is this app?

This API lets you integrate with ZATCA (Zakat, Tax and Customs Authority) in Saudi Arabia. You can:

All protected endpoints require the Authorization: Bearer <your_token> header. Use the token returned from POST /api/auth/login or POST /api/auth/register.

Base URL

Replace https://zatca-api.idafh.com with your actual app URL. All API routes are under /api.

https://zatca-api.idafh.com/api

1. Authentication

POST /api/auth/register

Create a new user and get a Bearer token.

Request body (JSON):

Field Type Required Description
name string Yes Max 255 characters.
email string Yes Valid email, must be unique.
password string Yes Min 8 chars, letters (upper+lower), numbers, symbols. Must send password_confirmation as well.
password_confirmation string Yes Must match password.

Example:

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "MyP@ssw0rd!",
  "password_confirmation": "MyP@ssw0rd!"
}

Success (201): Returns success, message, and data with user, token, token_type: "Bearer".

POST /api/auth/login

Log in and get a Bearer token.

Request body (JSON):

Field Type Required Description
email string Yes Valid email.
password string Yes User password.

Example:

{
  "email": "john@example.com",
  "password": "MyP@ssw0rd!"
}

Success (200): Returns success, message, and data with user, token, token_type: "Bearer".

Error (422): Invalid credentials — errors object with field messages.

For the following endpoints, send the header: Authorization: Bearer <token>

POST /api/auth/logout

Revoke the current token (log out this device). No body required.

Success (200): success: true, message.

POST /api/auth/logout-all

Revoke all tokens for the user (log out from all devices). No body required.

Success (200): success: true, message.

GET /api/auth/me

Get the currently authenticated user. No body required.

Success (200): success: true, data.user (id, name, email, timestamps).

2. ZATCA configurations

All configuration endpoints require Authorization: Bearer <token>.

GET /api/zatca/configurations

List your ZATCA configurations.

Query (optional): active_only — boolean; if true, returns only active configurations.

Success (200): success: true, data = array of configuration objects.

GET /api/zatca/configurations/active

Get the active ZATCA configuration for the given environment.

Query: environment — one of developer-portal, simulation, core.

Success (200): success: true, data = configuration object. 404 if no active configuration.

POST /api/zatca/configurations

Create a new ZATCA configuration and run onboarding (certificate request to ZATCA).

Request body (JSON):

Field Type Required Description
environment string Yes One of: developer-portal, simulation, core. Must be unique per user.
email_address string Yes Valid email, max 255.
common_name string Yes Max 255.
country_code string No ISO 2-letter (e.g. SA). Default: SA.
organization_unit_name string Yes Max 255.
organization_name string Yes Max 255.
egs_serial_number string Yes Max 255.
vat_number string Yes Max 50.
invoice_type string Yes One of: 1100, 0100, 1000.
registered_address string Yes Max 1000.
business_category string Yes Max 255.
auth_otp string No OTP if required by ZATCA for the environment.
language string No e.g. en. Default: en.
is_active boolean No Default: true.

Success (201): success: true, message, data = created configuration (with certificate data if returned by ZATCA).

Error (400): Onboarding failed — message, errors from ZATCA if any.

GET /api/zatca/configurations/{id}

Get one ZATCA configuration by ID. You can only access your own configurations.

Success (200): success: true, data = configuration. 403 if not owner.

PUT /api/zatca/configurations/{id}

Update a ZATCA configuration. Send only the fields you want to change (all configuration fields are optional on update).

Success (200): success: true, message, data = updated configuration. 403 if not owner.

DELETE /api/zatca/configurations/{id}

Soft-delete a ZATCA configuration. 403 if not owner.

Success (200): success: true, message.

POST /api/zatca/configurations/{id}/revoke

Revoke (deactivate) the configuration. 403 if not owner.

Success (200): success: true, message.

3. ZATCA invoices

All invoice endpoints require Authorization: Bearer <token>. You must have an onboarded ZATCA configuration for the environment you use (e.g. developer-portal) before creating invoices.

GET /api/zatca/invoices

List invoices for the authenticated user (paginated).

Query (optional):

Parameter Type Description
status string Filter: success or failed (ZATCA submission status).
per_page integer Items per page (default 15, max 100).

Success (200): success: true, data = array of invoices, meta with current_page, last_page, per_page, total.

Each invoice includes: id, user_id, order_id, uuid, data (invoice_number, total, tax, vat_number, tenant_name), status, qr_code, is_sent_to_zatca, zatca_status, created_at, updated_at, and last_zatca_document when loaded.

GET /api/zatca/invoices/{id}

Get one invoice by ID. You can only access your own invoices.

Success (200): success: true, data = invoice object. 404 if not found or not yours.

POST /api/zatca/invoices

Create a ZATCA e-invoice: build the XML, sign it, and submit to ZATCA. Uses your active configuration for the given environment.

Request body (JSON):

Field Type Required Description
environment string No Default: developer-portal. Must match an onboarded configuration.
language string No e.g. en. Default: en.
order_id string/number No Your internal order reference.
invoice_type_code string No Default: 0200000.
invoice_type_category string No Default: 388.
currency string No Default: SAR.
tax_currency string No Default: SAR.
tax_category string No Default: S.
tax_percentage number No Default: 15.
payment_type string No e.g. 10 (Cash). Default: 10.
prepaid_amount number No Default: 0.
client object No See below.
supplier object No See below (overrides defaults).
delivery object No date (Y-m-d). Default: today.
invoice_lines array No Line items. If empty, a default test line is used. See below.

client (all optional): name (default "Customer"), country (default "SA"), vat_number, street_name, building_number, plot_identification, sub_division_name, city_name, postal_number.

supplier (all optional): crn, street_name, building_number, plot_identification, sub_division_name, city_name, postal_number, country. VAT number and name come from your ZATCA configuration.

invoice_lines — each item can have:

Field Type Required Description
id string No Line ID (default: index + 1).
name string No Product name. Default: "Product".
currency string No Default: SAR.
price number No Unit price.
quantity number No Default: 1.
subtotal number No Line subtotal (before tax).
tax_total number No Tax for this line.
net_total number No Line total including tax.
tax_category string No Default: S.
tax_percentage number No Default: 15.
discount_reason string No Optional.
discount_amount number No Default: 0.

Minimal example (uses default test line):

{
  "environment": "developer-portal",
  "client": { "name": "Acme Corp", "country": "SA" }
}

Example with invoice lines:

{
  "environment": "developer-portal",
  "client": { "name": "Acme Corp", "country": "SA" },
  "invoice_lines": [
    {
      "id": "1",
      "name": "Product A",
      "price": 100,
      "quantity": 2,
      "subtotal": 200,
      "tax_total": 30,
      "net_total": 230
    }
  ]
}

Success (200): success: true/false, message, data with invoice_number, invoice_uuid, invoice_hash, qr_code, vat_number, zatca_response (ZATCA reporting status etc.).

Error (400): Missing or invalid configuration (e.g. "ZATCA configuration not found", "not onboarded", "certificate not found", "Production certificate is not ready").

Error (500): Server or ZATCA error — error message.

Quick flow for clients

  1. RegisterPOST /api/auth/register (or login with POST /api/auth/login).
  2. Use the returned token in the Authorization: Bearer <token> header for all subsequent requests.
  3. Create a ZATCA configurationPOST /api/zatca/configurations with your business and ZATCA details (one per environment). Complete ZATCA onboarding so the configuration is “onboarded” and has a production certificate if needed.
  4. Create invoicesPOST /api/zatca/invoices with at least environment and optionally client and invoice_lines. The app uses your active configuration for that environment, generates the e-invoice, and submits it to ZATCA.
  5. List or view invoicesGET /api/zatca/invoices and GET /api/zatca/invoices/{id} to see status, QR code, and ZATCA response.