KWNDevelopersالعربيةOpen KWN

API reference

Bill push (legacy)

The first API route, kept unchanged for systems already using it. New integrations use Bills.

Push a vendor bill (legacy)

POST/bills

Needs
purchases.write
Scopes
purchase:write

Drafts a vendor bill with no VAT, matching the vendor by TRN and then by name, or creating it. Sending it again with the same vendor reference — or, for a bill with no reference, the same Idempotency-Key header — returns the first bill with duplicate: true. A bill with VAT is made from a purchase order: POST /api/v1/purchase-orders/{id}/bills.

Parameters

FieldTypeDescription
Idempotency-KeyHeaderstring

Request body

16 fields
FieldTypeDescription
vendorobject
vendor.namestring
vendor.trnstring
vendor.emailstring
vendor.phonestring
referencestring
billDatedate
dueDatedate
linesobject[]
lines[].descriptionstring
lines[].quantitynumber
lines[].unitPricenumber
lines[].discountnumber
lines[].uomstring
lines[].productCodestring
notesstring

Code samples

curl -sS -X POST "https://app.kwn.tax/api/v1/bills" \
  -H "X-Api-Key: $KWN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "vendor": {
    "name": "Gulf Office Supplies L.L.C.",
    "trn": "100456789100003"
  },
  "reference": "GOS-INV-88213",
  "billDate": "2026-10-12",
  "dueDate": "2026-11-11",
  "lines": [
    {
      "description": "A4 copier paper, box of 5 reams",
      "quantity": 20,
      "unitPrice": 95
    }
  ]
}'

Responses

  • 200OK
    FieldTypeDescription
    idstring
    numberstring
    statusDRAFT | SENT | CONFIRMED | RECEIVED | POSTED | PAID | CANCELLED
    subtotalnumber
    taxTotalnumber
    totalnumber
    duplicateboolean
  • 201Created
    FieldTypeDescription
    idstring
    numberstring
    statusDRAFT | SENT | CONFIRMED | RECEIVED | POSTED | PAID | CANCELLED
    subtotalnumber
    taxTotalnumber
    totalnumber
    duplicateboolean
  • 400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
    Example
    {
      "error": "Lines: at least one line is required.",
      "code": "REQUEST_INVALID"
    }
  • 401No key, a key that is not ours, or one revoked (API_KEY_INVALID); a merchant not active (MERCHANT_INACTIVE).
    Example
    {
      "error": "That API key is not valid, or it was revoked.",
      "code": "API_KEY_INVALID"
    }
  • 403The key's scopes do not carry the capability (APP_NOT_GRANTED, ROLE_TOO_LOW), or the plan lacks the app (APP_LOCKED).
    Example
    {
      "error": "This key's scopes do not include sales.approve.",
      "code": "ROLE_TOO_LOW"
    }
  • 404Not found: another type under this route, or another company's (NOT_FOUND).
    Example
    {
      "error": "Not found.",
      "code": "NOT_FOUND"
    }
  • 409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
    Example
    {
      "error": "That externalId is already used by another record of this company.",
      "code": "EXTERNAL_ID_TAKEN"
    }
  • 429Too many requests: wait retryAfter seconds (RATE_LIMITED).
    Example
    {
      "error": "Too many requests. Wait a little and try again.",
      "code": "RATE_LIMITED"
    }