لم تُترجم هذه الصفحة بعد
تعرض هذه الصفحة النص الإنجليزي حتى تصدر ترجمتها.
Codes and constants¶
Every value below is read from the backend's own enumerations and validators on 2026-09-29, not from memory. Where the API refuses anything outside a list, the list here is the complete one.
Invoice body¶
type_code, what document this is¶
| Value | Document | When |
|---|---|---|
388 |
Tax invoice | A sale. |
381 |
Credit note | Reduces an issued invoice. Needs reason_id and original_invoice_reference. |
383 |
Debit note | Increases an issued invoice. Same two fields. |
386 |
Advance payment invoice | Money received before supply. Referenced later from the sale through prepaid_invoices. |
An integer, not a string. All four go through POST /api/invoices/. POST /api/invoices/{invoice_id}/notes/ is something else: it adds a comment with a title and details to an invoice.
transaction_code, standard or simplified, and which special case¶
A seven-character string. ZATCA calls it the invoice type "name". The first two characters say who the buyer is; the last five are flags.
0 1 0 0 0 0 0
└┬┘ │ │ │ │ └─ self-billed
│ │ │ │ └─── summary
│ │ │ └───── export
│ │ └─────── nominal
│ └───────── third party
└───────────── 01 standard (business buyer, clearance)
02 simplified (consumer, reporting)
Accepted at creation, the complete list:
| Value | Meaning |
|---|---|
0100000 |
Standard tax invoice to a business. Cleared by ZATCA before it is valid. |
0200000 |
Simplified tax invoice to a consumer. Reported to ZATCA within 24 hours. |
0100100 |
Standard export invoice to a non-resident buyer. Zero-rated lines with an export reason. |
Anything else, including export on a simplified invoice, third party, nominal, summary and self-billed, is refused with 400 Invalid transaction_code. The device must allow the type: see invoice_type under Devices below.
payment_means_type_code, how the buyer pays¶
A string. Subset of UN/CEFACT code list 4461. Each carries an English and an Arabic label that print on the invoice.
| Value | Meaning | Arabic |
|---|---|---|
"10" |
In cash | نقدا |
"20" |
Cheque | شيك |
"23" |
Bank cheque, issued by a bank | شيك بنكي |
"25" |
Certified cheque | شيك مصدق |
"26" |
Local cheque | شيك محلي |
"30" |
Credit transfer | تحويل الائتمان |
"31" |
Debit transfer | تحويل الخصم |
"46" |
Interbank debit transfer | تحويل خصم بين البنوك |
"48" |
Bank card | بطاقة بنكية |
"49" |
Direct debit | الخصم المباشر |
"54" |
Credit card | بطاقة ائتمان |
"55" |
Debit card | بطاقة الخصم |
"30" credit transfer requires payment terms, or the create is refused with Payment terms are required for credit payment. Payment terms are not a body field: Clix copies them from the description of the reason named in reason_id, so a "30" invoice needs a reason_id. The other codes need nothing more. GET /api/invoices/payment-means-types/ returns the same list.
currency and exchange_rate¶
currency is an ISO 4217 code; SAR for a domestic sale. exchange_rate is required, a number. With SAR it must be exactly 1. With any other currency it must be greater than zero and must not be 1: send that currency's rate to SAR. VAT is always reported to ZATCA in SAR.
issue_date and issue_time, set by the server¶
YYYY-MM-DD and HH:MM:SS, in Riyadh time, and written by Clix, not by you. The server stamps both from its own clock at the moment it accepts the invoice and discards whatever you send. The worked example shows it: the request carried 10:00:00 and the invoice came back 13:27:38.
Send both keys anyway on backend release 0.108.7, which demands them. The release after it makes them optional, so they can be dropped once your environment is past 0.108.7.
supply_date and supply_end_date¶
YYYY-MM-DD, in Riyadh time, and yours to set. supply_date is when the goods or service were delivered; for a single delivery set supply_end_date to the same day.
notes[]¶
Free text printed on the invoice. language_id is en or ar; note is the text and must not be empty. The key is required; send [] for no notes.
Fields Clix sets¶
is_sample_invoice, document_level_charges and payment_terms are not input fields. Clix sets them and ignores any value you send. Sample invoices are the ones Clix itself sends to ZATCA during device onboarding; an invoice created through the API is never one.
add_prepaid_amount and prepaid_invoices[]¶
false and [] unless the sale was paid in advance through a 386 advance payment invoice. Then set true and list the uuids of the advance invoices being applied; Clix deducts their amount from what is payable.
reason_id and original_invoice_reference[]¶
Required on credit and debit notes. reason_id is the uuid of an active reason the organisation configured under Invoices → Adjust Reasons; its description becomes the invoice's payment terms, which ZATCA reads as the reason for the note. The Integration API has no endpoint that lists reasons. original_invoice_reference lists the uuids of the invoices being corrected.
On a tax invoice send [] for original_invoice_reference; a tax invoice that names one is refused. Send null for reason_id, unless the invoice pays by "30" credit transfer and needs payment terms.
form_lines[] and lines¶
Two ways to send lines. Both keys are required; exactly one of them has entries, the other is [].
form_lines writes each line out in full. Per line:
| Field | Type | Values |
|---|---|---|
item_name |
string | 4 to 50 characters; printed |
item_net_price |
decimal as a string | unit price before VAT, "100" or "100.00"; greater than zero, at most two decimals, below 1,000,000,000 |
invoiced_quantity |
number | 1 or 2.5 |
invoiced_quantity_unit_of_measure |
string | one of the unit codes below |
vat_category_code |
S, Z, E, O |
see the table below |
vat_rate |
number | must match the category |
vat_exemption_reason_code |
string | required, non-empty, for Z, E and O; "" for S |
vat_exemption_reason_text |
string | required, non-empty, for Z, E and O; "" for S |
invoice_line_id |
uuid | credit and debit notes only, the original line being corrected |
Price times quantity must stay below 10,000,000,000,000.
lines bills items from your catalogue: {"item_id": "<uuid from GET /api/items/>", "quantity": 1}, plus invoice_line_id on a note. The item's name, price, unit and VAT apply, and an item with limited stock refuses a quantity above what is in stock.
vat_category_code and the vat_rate it allows¶
| Code | Category | Accepted vat_rate |
Needs |
|---|---|---|---|
S |
Standard rated | 15.0 or 5.0 |
no reason code or text |
Z |
Zero rated | 0.0 |
a VATEX-SA-… code of category Z, and a text |
E |
Exempt from VAT | 0.0 |
a VATEX-SA-… code of category E, and a text |
O |
Not subject to VAT | 0.0 |
VATEX-SA-OOS, and your own wording as the text |
Z, E and O refuse any rate but 0. For S, 15.0 and 5.0 are the Saudi rates that GET /api/invoices/vat/ lists; the server itself refuses only a rate of 0 or below, or above 100. A reason code from another category is refused. An export invoice, 0100100, must have every line Z with VATEX-SA-32 or VATEX-SA-33. The sixteen VATEX-SA-… reason codes and the category each belongs to come from GET /api/invoices/vat-exemption-reasons/; the human list is on Reference data.
invoiced_quantity_unit_of_measure¶
UN/ECE Recommendation 20 codes. This is the list Clix offers and prints labels for. The server does not check the code against it; it refuses only an empty unit, so use a code from here:
| Code | Unit | Code | Unit | Code | Unit |
|---|---|---|---|---|---|
PCE |
piece | PCS |
pieces | PKT |
packet |
CTN |
carton | BOX |
box | PALLET |
pallet |
KGM |
kilogram | GRM |
gram | MGM |
milligram |
MC |
microgram | GRN |
grain | TNE |
tonne |
DTN |
tonne, metric | TON |
ton, US | STN |
short ton |
LTN |
long ton | STI |
stone | LBR |
pound |
ONZ |
ounce | LTR |
litre | K6 |
kilolitre |
GLL |
gallon | BL |
barrel | MTQ |
cubic metre |
FTQ |
cubic foot | H19 |
hundred cubic foot | CDL |
cord |
MTK |
square metre | FTK |
square foot | INK |
square inch |
ACR |
acre | MTR |
metre | CMT |
centimetre |
INH |
inch | FOT |
foot | YRD |
yard |
KWH |
kilowatt-hour | JOU |
joule | D10 |
calorie |
GET /api/invoices/units-of-measure/ returns the same codes with Arabic labels. Services usually use PCE.
Devices¶
invoice_type and business_type, what a device may issue¶
invoice_type |
business_type |
May issue | transaction_code allowed |
|---|---|---|---|
1000 |
B2B |
standard only | 0100000, 0100100 |
0100 |
B2C |
simplified only | 0200000 |
1100 |
BOTH |
either | all three |
Chosen when the device is connected in the app: Businesses, Consumers or Both. An invoice whose transaction_code the device does not allow is refused.
device_status, where the device is in ZATCA onboarding¶
In order. Only pcsid_generated can issue invoices: creating one needs the production certificate.
| Value | Meaning |
|---|---|
csr_pending, csr_generated |
signing request being made |
ccsid_pending, ccsid_generated |
compliance certificate being issued |
ccsid_failed |
compliance certificate refused, usually a bad or used Fatoora code |
sample_invoices_pending, sample_invoices_generated |
Clix submitting the sample invoices ZATCA requires |
sample_invoices_failed |
a sample was rejected |
ZATCA_Submission_Pending |
waiting on ZATCA |
ZATCA_Submission_Completed |
ZATCA accepted every sample; the production certificate is requested next |
ZATCA_Submission_Failed |
ZATCA refused |
pcsid_pending |
production certificate being issued |
pcsid_generated |
production certificate held; the device can issue |
pcsid_failed |
production certificate refused |
The app's Devices list shows pcsid_generated as Active and csr_pending as Setup in Progress. Every other value shows as Unknown Status.
ccsid_status and pcsid_status read ISSUED once each certificate exists; the *CertificateData objects carry not_valid_after and days_until_expiry.
Invoice responses¶
zatca_response_status¶
| Value | Meaning | Final? |
|---|---|---|
CLEARED |
standard invoice accepted and stamped by ZATCA | yes |
REPORTED |
simplified invoice accepted by ZATCA | yes |
NOT_CLEARED |
standard invoice rejected; reasons in zatca_response_data.validationResults.errorMessages[] |
yes; fix the cause and create a new invoice |
NOT_REPORTED |
simplified invoice rejected; same place | yes; fix the cause and create a new invoice |
No response |
ZATCA gave no answer Clix recognises | no; Clix retries it, or send PATCH /api/invoices/{invoice_id}/clearance-reporting/ |
Null while ZATCA has not answered. A rejected invoice cannot be resubmitted: PATCH …/clearance-reporting/ answers 409 once ZATCA has answered, rejection included. The replacement is a new invoice and counts toward the monthly allowance.
zatca_response_code is ZATCA's HTTP status: 200 accepted, 202 accepted with warnings, 400 rejected.
payment_status¶
Set by payments you record, never by ZATCA.
| Value | Meaning |
|---|---|
Pending |
nothing received |
Partially Paid |
some payments recorded, balance remains |
Paid |
payments equal the total |
API keys¶
Access level, the role a key carries¶
| In the app | Value | A key with it can |
|---|---|---|
| View only | ViewInvoice |
read invoices, clients, items, devices, usage |
| Create and view invoices | CreateInvoice |
the above, plus create invoices, notes, clients and items |
| Accountant | Accountant |
the same as CreateInvoice on this surface |
Admin cannot be given to a key. Optional scopes[] narrow a key below its role and never widen it: invoice.create, invoice.get, and the other permission names shown in Swagger.
Related¶
- Quickstart, where these values appear in a body
- Worked example, the same body on the wire
- Reference data, the endpoints that return these lists with Arabic labels
- Invoice types, the same ideas for a non-developer