Skip to main content

Test mode

Build against a sandbox before you touch the merchant's real data. A test key works exactly like a live one, on the same host and paths, but every call reaches the merchant's sandbox: a separate copy of their catalogue whose invoices are signed with ZATCA's test certificates and never reach their real ZATCA records.

Getting a test key​

The merchant creates the sandbox in the dashboard under Settings → Developers → Sandbox, then issues a test key under Settings → Developers → API keys. A test key starts with ksr_test_:

Authorization: Bearer ksr_test_7c1e...

Every reply to a test key carries the header Kosoor-Mode: test. Check it in your client if you want to be sure a call did not reach live data.

What the sandbox holds​

  • The merchant's branches, items, payment methods, chart of accounts and warehouses, copied when the sandbox is built.
  • None of their customers, invoices or payments. Create your own, or use the fixtures below.
  • The merchant's name and address, with ZATCA's test VAT number 399999999900003.

PDFs from the sandbox carry a red Test, not a tax invoice mark. The sandbox sends no SMS.

When the sandbox is busy​

While the sandbox is being built or reset, a test key answers 503 sandbox_unavailable with a Retry-After: 30 header. Wait and send the same request again.

If the sandbox could not be built, a test key answers 503 sandbox_failed with no Retry-After: retrying will not help until the merchant resets the sandbox. While the sandbox is being deleted, its test keys answer 401 invalid_api_key.

A reset rebuilds the sandbox from the merchant's current catalogue. Your test keys keep working; every document and the request log are cleared. Deleting the sandbox stops every test key.

Fixtures​

Every sandbox holds these customers and one item under fixed ids, each with a known outcome. Use them to exercise your error handling without arranging the data yourself.

IdNameOutcome
5a4db0c5-0000-4000-8000-000000000001Sandbox Persona simplified invoice succeeds
5a4db0c5-0000-4000-8000-000000000002Sandbox Standard Coa standard invoice is cleared
5a4db0c5-0000-4000-8000-000000000003Sandbox CRN Coa company with a commercial registration and no VAT number; a standard invoice is cleared
5a4db0c5-0000-4000-8000-000000000004Sandbox No Street Coa standard invoice is refused: 422 customer_address_incomplete
5a4db0c5-0000-4000-8000-000000000005Sandbox Gulf Tradinga company in the UAE; a standard invoice is cleared
5a4db0c5-0000-4000-8000-000000000006Sandbox Inactive Personany invoice is refused: 422 customer_inactive
5a4db0c5-0000-4000-8000-000000000007Sandbox Credit Limit Cocredit limit 100; an invoice on account above it answers 422 credit_limit_exceeded
5a4db0c5-0000-4000-8000-000000000008Sandbox ZATCA Pending Coa standard invoice answers 201 with zatca.status pending, and is cleared shortly after
5a4db0c5-0000-4000-8000-000000000009Sandbox ZATCA Rejected Coa standard invoice is refused: 422 zatca_rejected, with a sample BR-KSA-63 in zatcaErrors
5a4db0c5-0000-4000-8000-000000000101Test subscription (item)a line naming it is refused: 422 item_not_sellable

Fixtures 8 and 9 never reach ZATCA when the invoice is issued: their answers come from Kosoor, so they are the same every time.