Integration guide for AI agents
If you are an automated agent integrating a system with ChatInvoice, this page is the whole contract in the order you need it. Everything else is discoverable from the API itself.
01Discover before you act
GET /v1/me— readallowed_document_types,business.prices_include_vat,business.vat_rate,tax_authority_connected,auto_send,limits. Do not assume; read.GET /v1/document-types— per type:requires_payments,allows_discount,based_on_types,based_on_required.GET /v1/customers?q=— find an existing customer before creating one by name.
02Choose the document type
| situation | type | notes |
|---|---|---|
| Price offer, nothing sold yet | quote | cancellable |
| Payment request before payment (e.g. bank transfer pending) | proforma | any legal type; not an accounting document |
| Sale completed, payment NOT yet received, business is not an exempt dealer | tax_invoice | later a receipt with based_on closes it |
| Sale completed AND paid, business is not an exempt dealer | tax_invoice_receipt | payments required, must equal total |
| Payment received, business IS an exempt dealer / NPO | receipt | the only accounting document they issue for income |
| Donation received (NPO) | donation_receipt | payments required |
| Refund / correction of a tax invoice | credit_note | based_on required |
| Goods shipped / returned | delivery_note / return_note | no amounts due |
If allowed_document_types does not contain the type you chose, choose again from the table — never override the business's legal type.
03Build the request
- Send only the fields in the schema. Unknown fields fail with
400 validation_error. - Never send: a document number, a VAT rate,
is_tax_exempt, an allocation number, a status, computed totals as fields. Never guess VAT — if you must verify a figure, useexpected_total. - Prices: read
business.prices_include_vat; setprices_include_vatexplicitly if your prices differ from that default. - Payments: only on
tax_invoice_receipt,receipt,donation_receipt; the sum must equal the total (compute it from the same items or useexpected_total). - Date: omit it (today), or a past date not earlier than the last document of that type. Never a future date.
- For an allocation number (invoice above ₪5,000 net, business connected): include
customer.tax_id. The document is issued either way — readallocation.status. - Always set
external_refto your own id andIdempotency-Keyto a value unique per logical document (e.g.<your-order-id>:invoice).
04Handle the response
201: persistid,number,view_url,pdf_url. Readdelivery.status— ifdisabled/suppressed/no_recipient, the customer has NOT received anything; sendview_urlyourself if that is expected.409 customer_identity_conflict: the tax id belongs to a differently-named customer. Prefercustomer.id = details.existing_customer_idif it is the same entity; otherwise resend withcustomer.identity_confirmed: true.422: a business rule. Nothing was issued. Fix perhint; e.g.legal_type_forbidden→ pick fromallowed_document_types;date_before_last_document→ usedetails.last_document_date.retryable: true(502/503/409 request_in_progress/429): retry with backoff using the sameIdempotency-Key. Never change the key on retry.402: stop and surfacedetails.payment_urlto the business owner.
05Do not
- Do not cancel accounting documents — issue a
credit_notewithbased_on. - Do not re-issue a document to “edit” it. Cancel/credit, then issue anew.
- Do not create a new customer when
GET /v1/customers?q=finds a match by tax id or exact name. - Do not exceed
limits; honorRateLimit-*andRetry-After.
06Minimal happy path
GET /v1/me → allowed types, prices_include_vat, auto_send
GET /v1/customers?q=515123456 → customer.id (or none)
POST /v1/documents (Idempotency-Key: order-10021:invrec)
{ type: "tax_invoice_receipt", customer: {id}, items, payments, expected_total, external_ref }
201 → store id/number/view_url; check delivery.status and allocation.status
Machine-readable: openapi.json · llms-full.txt · GET /v1/errors.
ChatInvoice · API v1.0 · updated 2026-09-07 · openapi.yaml · llms.txt