Developers Coming soon

SDKs and client libraries

Official PHP, Node.js and Python SDKs are built and tested, but not published yet. The API is plain HTTPS and JSON, so any HTTP client works today.

This page describes a capability that is not available yet. It is published so you can plan ahead, and details may change before release. Everything marked "Available" in these docs works today.

Today: any HTTP client

You do not need an SDK: JSON in and out over HTTPS, and one header. Every page has copyable examples in cURL, PHP, Node.js and Python.

curl -X POST https://fatoora.tw.sa/api/v1/invoices \
  -H "Authorization: Bearer wbk_test_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
  "issue": false,
  "issue_date": "2026-11-03",
  "customer": {
    "name": "Example Trading Co.",
    "vat_number": "300000000000003",
    "address_line1": "King Fahd Rd",
    "city": "Riyadh",
    "postal_code": "12345",
    "country": "SA"
  },
  "items": [
    { "description": "Consulting", "quantity": 2, "unit_price": 500, "vat_rate": 15 }
  ]
}'
<?php
$response = $client->post('invoices', [
    'json' => [
        'issue'      => false,          // a draft: no legal number, nothing sent to ZATCA
        'issue_date' => '2026-11-03',
        'customer'   => [
            'name'          => 'Example Trading Co.',
            'vat_number'    => '300000000000003',
            'address_line1' => 'King Fahd Rd',
            'city'          => 'Riyadh',
            'postal_code'   => '12345',
            'country'       => 'SA',
        ],
        'items' => [
            ['description' => 'Consulting', 'quantity' => 2, 'unit_price' => 500, 'vat_rate' => 15],
        ],
    ],
    'http_errors' => false,
]);

$body = json_decode((string) $response->getBody(), true);
if ($body['ok']) {
    echo $body['data']['invoice']['number']; // DRAFT-… until it is issued
} else {
    echo $body['error']['code'];
}
const res = await fetch("https://fatoora.tw.sa/api/v1/invoices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.WONDERFATOORA_API_KEY}`,
    "Content-Type": "application/json",
    Accept: "application/json",
  },
  body: JSON.stringify({
    issue: false, // a draft: no legal number, nothing sent to ZATCA
    issue_date: "2026-11-03",
    customer: {
      name: "Example Trading Co.",
      vat_number: "300000000000003",
      address_line1: "King Fahd Rd",
      city: "Riyadh",
      postal_code: "12345",
      country: "SA",
    },
    items: [{ description: "Consulting", quantity: 2, unit_price: 500, vat_rate: 15 }],
  }),
});

const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(body.data.invoice.id, body.data.invoice.number);
res = requests.post(
    "https://fatoora.tw.sa/api/v1/invoices",
    headers={
        "Authorization": f"Bearer {os.environ['WONDERFATOORA_API_KEY']}",
        "Accept": "application/json",
    },
    json={
        "issue": False,  # a draft: no legal number, nothing sent to ZATCA
        "issue_date": "2026-11-03",
        "customer": {
            "name": "Example Trading Co.",
            "vat_number": "300000000000003",
            "address_line1": "King Fahd Rd",
            "city": "Riyadh",
            "postal_code": "12345",
            "country": "SA",
        },
        "items": [
            {"description": "Consulting", "quantity": 2, "unit_price": 500, "vat_rate": 15}
        ],
    },
    timeout=30,
)
body = res.json()
print(res.status_code, body["data"]["invoice"]["number"] if body["ok"] else body["error"])

Official SDKs

Coming soon The SDKs are written and tested but not available yet: they are not on Packagist, npm or PyPI, so there is nothing to install today. Package names and details may change before release.
Language Planned package Requirements
PHP wonderfatoora/wonderfatoora-php PHP 8.1+ with cURL, no other dependencies. Optional Laravel service provider, facade and webhook middleware.
Node.js @wonderfatoora/sdk Node.js 18+, no dependencies, TypeScript types included.
Python wonderfatoora Python 3.9+, standard library only, typed.

What they do

  • One method for each API operation, with typed answers, generated from the OpenAPI document and refined by hand.
  • An Idempotency-Key on every write that accepts one, added automatically, or your own key when you pass it.
  • Retries after 429 and 503 that wait for Retry-After, only for requests that are safe to repeat.
  • Typed errors carrying code, message, details and the request id.
  • Cursor pagination as an iterator, and PDF and XML downloads as bytes.
  • Webhook signature checks: constant-time, within a time tolerance, and accepting both secrets during a rotation.
  • Versioned with the API's OpenAPI version.

Laravel

See Laravel e-invoicing integration for a service class, configuration and a queued job you can use today.

The OpenAPI 3.1 document is published at /developers/openapi.json: you can generate a client for your language with a standard OpenAPI generator today.

Ready to build?

API access is part of the Business and Enterprise plans. Create a key in Settings → API keys and make your first call in minutes.