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.
Replace https://zatca-api.idafh.com with your
actual app URL. All API routes are under /api.
https://zatca-api.idafh.com/api
Create a new user and get a Bearer token.
Request body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Max 255 characters. |
| 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".
Log in and get a Bearer token.
Request body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
| 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.
Authorization: Bearer <token>
Revoke the current token (log out this device). No body required.
Success (200): success: true,
message.
Revoke all tokens for the user (log out from all devices). No body required.
Success (200): success: true,
message.
Get the currently authenticated user. No body required.
Success (200): success: true,
data.user (id, name, email, timestamps).
All configuration endpoints require
Authorization: Bearer <token>.
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 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.
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 one ZATCA configuration by ID. You can only access your own configurations.
Success (200): success: true,
data = configuration. 403 if
not owner.
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.
Soft-delete a ZATCA configuration. 403 if not owner.
Success (200): success: true,
message.
Revoke (deactivate) the configuration. 403 if not owner.
Success (200): success: true,
message.
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.
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 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.
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.
POST /api/auth/register (or login with
POST /api/auth/login).
Authorization: Bearer <token> header for
all subsequent requests.
POST /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.
POST /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.
GET /api/zatca/invoices and
GET /api/zatca/invoices/{id} to see status, QR
code, and ZATCA response.