API reference
Invoices
Customer tax invoices: drafted, approved, issued and cleared. Issuing takes one credit.
- POSTCreate a draft invoice
- GETList
- POSTCredit a cleared invoice
- PUTUpdate a draft
- GETRead one
- POSTAsk a person to approve
- POSTApprove for issue
- POSTIssue and send for clearance
- POSTCancel
- POSTSet back to draft
- GETClearance status
- POSTSend again
- POSTAsk the provider now
- GETPrint
Create a draft invoice
POST/invoices
Send an Idempotency-Key header.
A draft invoice for a customer of this company (customerId). Approve and issue it to send it for clearance. Requires Idempotency-Key.
Parameters
| Field | Type | Description |
|---|---|---|
Idempotency-KeyHeaderRequired | string | 1 to 100 visible ASCII characters, such as a UUID, unique to this request. Sent again with the same request, the first answer is replayed (Idempotent-Replayed: true); with another request, 422 IDEMPOTENCY_KEY_REUSED. |
Request body
29 fields
| Field | Type | Description |
|---|---|---|
lines | object[] | |
lines[].unitPrice | number | What it costs; a product needs no product. VAT-exclusive, as stored. |
lines[].quantity | number | |
lines[].taxRate | number | VAT percent: 5 (standard) or 0 (zero-rated). |
lines[].description | string | |
lines[].productId | string | A product of this company by id … |
lines[].productCode | string | … or by its internal reference (SKU), then its barcode. |
lines[].uom | string | |
lines[].discount | number | Discount percent, 0 to 100. |
lines[].kind | PRODUCT | SECTION | NOTE | |
customerId | string | Required on an invoice. |
issueDate | date | The document's day, YYYY-MM-DD. Defaults to today. |
dueDate | date | |
expiryDate | date | A quotation's expiry day. |
customerRef | string | |
notes | string | |
paymentTermId | string | |
fiscalPositionId | string | |
salespersonId | string | |
salesTeamId | string | |
emirate | ABU_DHABI | DUBAI | SHARJAH | AJMAN | UMM_AL_QUWAIN | RAS_AL_KHAIMAH | FUJAIRAH | |
taxMode | TAX_EXCLUDED | TAX_INCLUDED | |
invoiceAddressId | string | |
deliveryAddressId | string | |
externalId | string | Your system's id for it, kept for good; unique per company. Create only. |
paymentMeansCode | string | UNCL 4461 payment means, such as 30 (credit transfer). |
transactionFlags | FREE_TRADE_ZONE | DEEMED_SUPPLY | MARGIN_SCHEME | SUMMARY_INVOICE | CONTINUOUS_SUPPLY | DISCLOSED_AGENT_BILLING | ECOMMERCE | EXPORTS[] | |
invoicePeriodStart | string | |
invoicePeriodEnd | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices" \
-H "X-Api-Key: $KWN_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"customerId": "cus_4kq9w2m1",
"issueDate": "2026-10-15",
"dueDate": "2026-11-14",
"customerRef": "PO-7781",
"externalId": "SO-10045",
"lines": [
{
"description": "Office chair, mesh back",
"quantity": 4,
"unitPrice": 450,
"taxRate": 5,
"productCode": "CHR-MESH-01"
},
{
"description": "Delivery within Dubai",
"quantity": 1,
"unitPrice": 100,
"taxRate": 5
}
]
}'Responses
201Created
Field Type Description idstringtypeQUOTATION | ORDER | INVOICE | CREDIT_NOTE | DEBIT_NOTEnumberstringstatusDRAFT | SENT | CONFIRMED | ISSUED | SUBMITTED | PROCESSING | APPROVED | REJECTED | FAILED | PAID | CANCELLED | EXPIREDissueDatedatedueDatedateexpiryDatedatecustomerobjectemirateABU_DHABI | DUBAI | SHARJAH | AJMAN | UMM_AL_QUWAIN | RAS_AL_KHAIMAH | FUJAIRAHcurrencystringtaxModeTAX_EXCLUDED | TAX_INCLUDEDcustomerRefstringnotesstringpaymentTermIdstringfiscalPositionIdstringsalespersonIdstringsalesTeamIdstringinvoiceAddressIdstringdeliveryAddressIdstringlinesobject[]subtotalnumberdiscountTotalnumbertaxTotalnumbertotalnumberinvoicedTotalnumberpaidTotalnumbercreditedTotalnumbersourceobjectderivedobject[]originstringAPI, MANUAL, ODOO or POS. externalIdstringclearanceobjecteInvoiceobjectcreatedAtdateupdatedAtdate400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }422That Idempotency-Key was used for a different request (IDEMPOTENCY_KEY_REUSED).
{ "error": "That Idempotency-Key was used for a different request.", "code": "IDEMPOTENCY_KEY_REUSED" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
List
GET/invoices
Newest first, a page at a time: send the previous page's next as cursor. Filter by status, partnerId (the customer), issueFrom/issueTo, number, externalId, createdFrom/createdTo, or updatedSince to poll for changes.
Parameters
| Field | Type | Description |
|---|---|---|
statusQuery | string | A status, by name. |
partnerIdQuery | string | The customer (sales) or the vendor (purchases). |
issueFromQuery | date | Issued on or after this day. |
issueToQuery | date | Issued on or before this day. |
numberQuery | string | |
limitQuery | integer | 1 to 200; 50 by default. |
cursorQuery | string | The previous page's next. |
updatedSinceQuery | date | Only rows changed at or after this instant. |
createdFromQuery | date | |
createdToQuery | date | |
externalIdQuery | string | Only the row your system gave this id. |
Code samples
curl -sS -X GET "https://app.kwn.tax/api/v1/invoices" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description dataobject[]The rows of this page. nextstringThe cursor of the next page, to send as ?cursor=; null on the last page. 400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Credit a cleared invoice
POST/invoices/{id}/credit-notes
Send an Idempotency-Key header.
A draft credit note against a cleared invoice, with its reason. Issue it like an invoice. Requires Idempotency-Key.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string | |
Idempotency-KeyHeaderRequired | string | 1 to 100 visible ASCII characters, such as a UUID, unique to this request. Sent again with the same request, the first answer is replayed (Idempotent-Replayed: true); with another request, 422 IDEMPOTENCY_KEY_REUSED. |
Request body
2 fields
| Field | Type | Description |
|---|---|---|
reason | string | |
date | date | The credit note's day; defaults to today. |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/credit-notes" \
-H "X-Api-Key: $KWN_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reason": "Two chairs returned unused.",
"date": "2026-10-20"
}'Responses
201Created
Field Type Description idstringtypeQUOTATION | ORDER | INVOICE | CREDIT_NOTE | DEBIT_NOTEnumberstringstatusDRAFT | SENT | CONFIRMED | ISSUED | SUBMITTED | PROCESSING | APPROVED | REJECTED | FAILED | PAID | CANCELLED | EXPIREDissueDatedatedueDatedateexpiryDatedatecustomerobjectemirateABU_DHABI | DUBAI | SHARJAH | AJMAN | UMM_AL_QUWAIN | RAS_AL_KHAIMAH | FUJAIRAHcurrencystringtaxModeTAX_EXCLUDED | TAX_INCLUDEDcustomerRefstringnotesstringpaymentTermIdstringfiscalPositionIdstringsalespersonIdstringsalesTeamIdstringinvoiceAddressIdstringdeliveryAddressIdstringlinesobject[]subtotalnumberdiscountTotalnumbertaxTotalnumbertotalnumberinvoicedTotalnumberpaidTotalnumbercreditedTotalnumbersourceobjectderivedobject[]originstringAPI, MANUAL, ODOO or POS. externalIdstringclearanceobjecteInvoiceobjectcreatedAtdateupdatedAtdate400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }422That Idempotency-Key was used for a different request (IDEMPOTENCY_KEY_REUSED).
{ "error": "That Idempotency-Key was used for a different request.", "code": "IDEMPOTENCY_KEY_REUSED" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Update a draft
PUT/invoices/{id}
Replaces the header and the lines of a draft. Anything past a draft is refused with the app's own sentence (RULE_REFUSED).
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Request body
29 fields
| Field | Type | Description |
|---|---|---|
lines | object[] | |
lines[].unitPrice | number | What it costs; a product needs no product. VAT-exclusive, as stored. |
lines[].quantity | number | |
lines[].taxRate | number | VAT percent: 5 (standard) or 0 (zero-rated). |
lines[].description | string | |
lines[].productId | string | A product of this company by id … |
lines[].productCode | string | … or by its internal reference (SKU), then its barcode. |
lines[].uom | string | |
lines[].discount | number | Discount percent, 0 to 100. |
lines[].kind | PRODUCT | SECTION | NOTE | |
customerId | string | Required on an invoice. |
issueDate | date | The document's day, YYYY-MM-DD. Defaults to today. |
dueDate | date | |
expiryDate | date | A quotation's expiry day. |
customerRef | string | |
notes | string | |
paymentTermId | string | |
fiscalPositionId | string | |
salespersonId | string | |
salesTeamId | string | |
emirate | ABU_DHABI | DUBAI | SHARJAH | AJMAN | UMM_AL_QUWAIN | RAS_AL_KHAIMAH | FUJAIRAH | |
taxMode | TAX_EXCLUDED | TAX_INCLUDED | |
invoiceAddressId | string | |
deliveryAddressId | string | |
externalId | string | Your system's id for it, kept for good; unique per company. Create only. |
paymentMeansCode | string | UNCL 4461 payment means, such as 30 (credit transfer). |
transactionFlags | FREE_TRADE_ZONE | DEEMED_SUPPLY | MARGIN_SCHEME | SUMMARY_INVOICE | CONTINUOUS_SUPPLY | DISCLOSED_AGENT_BILLING | ECOMMERCE | EXPORTS[] | |
invoicePeriodStart | string | |
invoicePeriodEnd | string |
Code samples
curl -sS -X PUT "https://app.kwn.tax/api/v1/invoices/<id>" \
-H "X-Api-Key: $KWN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "cus_4kq9w2m1",
"issueDate": "2026-10-15",
"dueDate": "2026-11-14",
"customerRef": "PO-7781",
"externalId": "SO-10045",
"lines": [
{
"description": "Office chair, mesh back",
"quantity": 4,
"unitPrice": 450,
"taxRate": 5,
"productCode": "CHR-MESH-01"
},
{
"description": "Delivery within Dubai",
"quantity": 1,
"unitPrice": 100,
"taxRate": 5
}
]
}'Responses
200OK
Field Type Description idstringtypeQUOTATION | ORDER | INVOICE | CREDIT_NOTE | DEBIT_NOTEnumberstringstatusDRAFT | SENT | CONFIRMED | ISSUED | SUBMITTED | PROCESSING | APPROVED | REJECTED | FAILED | PAID | CANCELLED | EXPIREDissueDatedatedueDatedateexpiryDatedatecustomerobjectemirateABU_DHABI | DUBAI | SHARJAH | AJMAN | UMM_AL_QUWAIN | RAS_AL_KHAIMAH | FUJAIRAHcurrencystringtaxModeTAX_EXCLUDED | TAX_INCLUDEDcustomerRefstringnotesstringpaymentTermIdstringfiscalPositionIdstringsalespersonIdstringsalesTeamIdstringinvoiceAddressIdstringdeliveryAddressIdstringlinesobject[]subtotalnumberdiscountTotalnumbertaxTotalnumbertotalnumberinvoicedTotalnumberpaidTotalnumbercreditedTotalnumbersourceobjectderivedobject[]originstringAPI, MANUAL, ODOO or POS. externalIdstringclearanceobjecteInvoiceobjectcreatedAtdateupdatedAtdate400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Read one
GET/invoices/{id}
The document with its lines, where it came from and what came of it, its e-invoice readiness and, for an invoice or credit note, its clearance. A document of another type under this route is NOT_FOUND.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X GET "https://app.kwn.tax/api/v1/invoices/<id>" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description idstringtypeQUOTATION | ORDER | INVOICE | CREDIT_NOTE | DEBIT_NOTEnumberstringstatusDRAFT | SENT | CONFIRMED | ISSUED | SUBMITTED | PROCESSING | APPROVED | REJECTED | FAILED | PAID | CANCELLED | EXPIREDissueDatedatedueDatedateexpiryDatedatecustomerobjectemirateABU_DHABI | DUBAI | SHARJAH | AJMAN | UMM_AL_QUWAIN | RAS_AL_KHAIMAH | FUJAIRAHcurrencystringtaxModeTAX_EXCLUDED | TAX_INCLUDEDcustomerRefstringnotesstringpaymentTermIdstringfiscalPositionIdstringsalespersonIdstringsalesTeamIdstringinvoiceAddressIdstringdeliveryAddressIdstringlinesobject[]subtotalnumberdiscountTotalnumbertaxTotalnumbertotalnumberinvoicedTotalnumberpaidTotalnumbercreditedTotalnumbersourceobjectderivedobject[]originstringAPI, MANUAL, ODOO or POS. externalIdstringclearanceobjecteInvoiceobjectcreatedAtdateupdatedAtdate400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Ask a person to approve
POST/invoices/{id}/request-approval
Puts a draft in front of a person who may approve it. Not available yet: RULE_REFUSED.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/request-approval" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description alreadyDonebooleanTrue when the document was already where the action takes it; nothing changed. documentobject400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Approve for issue
POST/invoices/{id}/approve
Checks the lock dates, the UAE mandatory fields, the clearance rules and the provider's dry run, and moves the draft to ISSUED. Costs nothing. Approved already: alreadyDone.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/approve" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description alreadyDonebooleanTrue when the document was already where the action takes it; nothing changed. documentobject400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Issue and send for clearance
POST/invoices/{id}/issue
Takes the document's one credit and queues it for clearance. A draft is approved first when the key holds sales:approve, else APPROVAL_REQUIRED. Sent already: alreadyDone. The answer may say SUBMITTED; poll the document or its clearance for the outcome.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/issue" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description alreadyDonebooleanTrue when the document was already where the action takes it; nothing changed. documentobject400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Cancel
POST/invoices/{id}/cancel
A draft, an approved document not yet sent, or a rejected one (its credit is released). A cleared document is credited, never cancelled. Cancelled already: alreadyDone.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/cancel" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description alreadyDonebooleanTrue when the document was already where the action takes it; nothing changed. documentobject400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Set back to draft
POST/invoices/{id}/reset-to-draft
A rejected or failed document opens again for correction. A draft already: alreadyDone.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/reset-to-draft" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description alreadyDonebooleanTrue when the document was already where the action takes it; nothing changed. documentobject400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Clearance status
GET/invoices/{id}/clearance
Where the document stands with e-invoicing clearance: status, provider reference, attempts and the provider's errors.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X GET "https://app.kwn.tax/api/v1/invoices/<id>/clearance" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description statusstringThe document's status: SUBMITTED, PROCESSING, APPROVED (cleared), REJECTED, FAILED, … routestringTAXSTAR, LOCAL_B2C or LOCAL_CREDIT_NOTE; null before it is issued. providerobjectproviderCodestringreferencestringThe provider's or the FTA's reference once cleared. submittedAtdatelastCheckedAtdateclearedAtdateattemptsintegererrorCodestringerrorstringerrorsobject[]deliverystringcanRetrybooleancanRefreshboolean400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Send again
POST/invoices/{id}/clearance/retry
A FAILED document is sent to the provider again, with no second credit.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/clearance/retry" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description statusstringThe document's status: SUBMITTED, PROCESSING, APPROVED (cleared), REJECTED, FAILED, … routestringTAXSTAR, LOCAL_B2C or LOCAL_CREDIT_NOTE; null before it is issued. providerobjectproviderCodestringreferencestringThe provider's or the FTA's reference once cleared. submittedAtdatelastCheckedAtdateclearedAtdateattemptsintegererrorCodestringerrorstringerrorsobject[]deliverystringcanRetrybooleancanRefreshboolean400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
Ask the provider now
POST/invoices/{id}/clearance/refresh
Asks the provider for the outcome of a PROCESSING document now. At most every 30 seconds: REFRESH_TOO_SOON with retryAfter.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string |
Code samples
curl -sS -X POST "https://app.kwn.tax/api/v1/invoices/<id>/clearance/refresh" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
Field Type Description statusstringThe document's status: SUBMITTED, PROCESSING, APPROVED (cleared), REJECTED, FAILED, … routestringTAXSTAR, LOCAL_B2C or LOCAL_CREDIT_NOTE; null before it is issued. providerobjectproviderCodestringreferencestringThe provider's or the FTA's reference once cleared. submittedAtdatelastCheckedAtdateclearedAtdateattemptsintegererrorCodestringerrorstringerrorsobject[]deliverystringcanRetrybooleancanRefreshboolean400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }
GET/invoices/{id}/pdf
The printed document as the app prints it, in English or Arabic (?lang=ar). Counted against the apikey-heavy budget.
Parameters
| Field | Type | Description |
|---|---|---|
idPathRequired | string | |
langQuery | string |
Code samples
curl -sS -X GET "https://app.kwn.tax/api/v1/invoices/<id>/pdf" \
-H "X-Api-Key: $KWN_API_KEY"Responses
200OK
400Refused: the request or a business rule. The code says which (REQUEST_INVALID, RULE_REFUSED, …).
{ "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).
{ "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).
{ "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).
{ "error": "Not found.", "code": "NOT_FOUND" }409A conflict: an externalId taken, or a change that could not be saved (EXTERNAL_ID_TAKEN, CONFLICT).
{ "error": "That externalId is already used by another record of this company.", "code": "EXTERNAL_ID_TAKEN" }429Too many requests: wait retryAfter seconds (RATE_LIMITED).
{ "error": "Too many requests. Wait a little and try again.", "code": "RATE_LIMITED" }