Browse the documentation

MCP tools

Invoices and e-invoicing

MCP tools for ZATCA tax invoices, credit and debit notes, the activity log, the archive and the chain verification.

An invoice here is a tax document issued under ZATCA's e-invoicing rules: a tax invoice, a credit note or a debit note. It starts as a draft you can edit or delete freely, then it is issued: it gets its sequential number, its cryptographic stamp and its QR code, and goes to ZATCA. After that it cannot be changed; a correction is a credit or debit note that references it. The feature is explained in full in E-Invoices (ZATCA).

Warning:Issuing cannot be undone, and only an admin or the owner may issue an invoice or send it to ZATCA again; sales and purchasing members prepare drafts. The chain verification is for the owner alone, and the owner sets up the e-invoicing unit in the app, under Settings → ZATCA. The technical and viewer (no pricing) roles cannot use any tool on this page, because invoices are sale-side money.
Note:Until the unit is live, invoices are issued in phase-1 mode: a sequential number and a five-field QR code, no submission to ZATCA, and zatca_status stays none. The unit is set up once in the app, under Settings → ZATCA. The feature stops at the document: there are no payments, due dates or receivables here, and your accounting software takes the issued invoice from here as PDF or XML.
ToolWhat it does
invoices_listList invoices
invoices_getGet an invoice
invoices_createCreate an invoice draft
invoices_updateUpdate an invoice draft
invoices_deleteDelete an invoice draft
invoices_issueIssue an invoice
invoices_submitSend an invoice to ZATCA again
invoice_pdfDownload the invoice PDF
invoice_xmlDownload the invoice XML
invoice_archive_zipDownload the invoice XML archive
invoice_events_listList the invoice activity log
zatca_chain_verifyVerify the invoice chain and activity log

Finding and reading invoices

invoices_list

Lists your organization's invoices, credit notes and debit notes, newest first. Filter by stage, ZATCA outcome, document or kind, the sales order they bill or the invoice a note corrects, or search by free text.

Read-only · scope invoices.read · roles: owner, admin, sales, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
statusstringNoOnly drafts (draft) or only issued documents (issued).
zatca_statusstringNoOnly documents with this ZATCA outcome: none (no outcome yet: a draft, or an invoice issued without a live unit), pending (ZATCA could not be reached), cleared, reported or rejected.
document_typestringNoThe document: invoice for a tax invoice, credit_note or debit_note.
transaction_typestringNoThe kind: standard for B2B or simplified for B2C.
sales_order_idintegerNoOnly documents that bill this sales order. The ID comes from sales_orders_list.
original_invoice_idintegerNoOnly the credit and debit notes that correct this invoice.
qstringNoA word or number to look for in the invoice number, the customer name and the buyer's VAT number, up to 200 characters.
pageintegerNoPage number, starting at 1.
page_sizeintegerNoResults per page: 20 by default, 100 at most.
{
  "status": "issued",
  "zatca_status": "rejected",
  "page_size": 50
}
Example arguments

Returns: A page of invoices, each with its number, UUID, kind, stage, ZATCA outcome, buyer, totals and the sales order and tender it is linked to, and the total count.

  • Drafts also carry zatca_status none. Add status: issued to find only the invoices issued without a live unit.

invoices_get

Returns one invoice in full: header, lines, buyer, totals, ZATCA's outcome and messages and the QR code, with the sales order, quotation and tender it is linked to and the notes that correct it. For a draft it also lists what is still missing before it can be issued.

Read-only · scope invoices.read · roles: owner, admin, sales, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.

Returns: An object with invoice, items, readiness_issues, qr_image (a PNG data URI, empty for a draft), sales_order, quotation, tender, original_invoice, corrections (the notes that correct it), egs (the unit's environment and status) and events (the invoice's 50 most recent activity rows).

  • readiness_issues is a list of codes for what a draft lacks, and it is empty once issued. Codes starting with seller_ belong to the organization record in settings and cannot be fixed on the invoice. The other codes name a missing buyer, line or note field, such as buyer_identity, supply_date, original_invoice and line_exemption_reason.
  • ZATCA's messages on a rejection are in invoice.zatca_error and invoice.zatca_response. The signed and the cleared XML are not in this reply; download them with invoice_xml.

Drafts

A draft has no number, hash or XML. Save it half-filled if you like: nothing is checked against ZATCA's requirements until you issue, and invoices_get shows what is missing.

invoices_create

Saves a tax invoice, credit note or debit note as a draft with at least one line. Nothing is numbered, signed or sent until you issue it. Name a customer profile to fill the buyer's name, identifier and address, and send any field you want to win over the profile.

Changes data · scope invoices.write · roles: owner, admin, sales, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
customer_idintegerNoA customer profile to start from, from customers_list. Every buyer field you leave out is filled from it according to the customer's tax treatment, and anything you send wins over the profile. Send null to use none.
customer_namestringNoThe buyer's name as printed, 1 to 200 characters. Required unless customer_id is given; if you send both, this name is used.
document_typestringNoThe document: invoice for a tax invoice (the default), credit_note or debit_note.
transaction_typestringNoThe kind: standard is a B2B invoice that ZATCA clears before the buyer receives it (the default), simplified is a B2C invoice that is reported. A note whose original invoice you name takes that invoice's kind when you send none.
original_invoice_idintegerNoFor a credit or debit note: the issued tax invoice it corrects. It is required to issue the note and may be left empty while it is a draft. It must be an issued tax invoice of your organization, not a draft and not another note. Ignored for invoice. Send null to clear it.
reasonstringNoFor a credit or debit note: why it is issued, up to 500 characters. Required to issue the note. Send null to clear it.
buyer_vat_numberstringNoThe buyer's Saudi VAT number: 15 digits starting and ending with 3. A malformed number blocks issue. Send null to clear it.
buyer_id_schemestringNoThe kind of the buyer's other identifier, for a buyer with no VAT number: CRN commercial registration, MOM municipal licence (MOMRA), MLS HR ministry licence (MHRSD), 700 the unified 700 number, SAG investment licence (MISA), NAT national ID, GCC GCC citizen ID, IQA iqama, PAS passport, OTH other. Send it with buyer_id_value. Send null to clear it.
buyer_id_valuestringNoThe value of the other identifier, such as the commercial registration number, up to 50 characters. A standard invoice to a buyer with no VAT number needs it together with buyer_id_scheme. Send null to clear it.
buyer_street_namestringNoThe street of the buyer's national address, up to 200 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_building_numberstringNoThe building number, up to 10 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_districtstringNoThe district, up to 100 characters. Send null to clear it.
buyer_citystringNoThe city, up to 100 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_postal_codestringNoThe postal code, up to 10 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_additional_numberstringNoThe additional number of the national address, up to 10 characters. Send null to clear it.
buyer_country_codestringNoThe buyer's two-letter country code (ISO 3166-1). Defaults to SA.
sales_order_idintegerNoThe sales order the invoice bills, from sales_orders_list. It must be one of your organization's orders. Send null to unlink.
quotation_idintegerNoThe quotation the sale came from, from quotations_list. It must be one of your organization's quotations. Send null to unlink.
tender_idintegerNoThe tender the sale relates to, for reference, from tenders_list. Send null to unlink.
currencystringNoThe three-letter currency code (ISO 4217). Defaults to SAR.
supply_datestringNoThe date of supply, as YYYY-MM-DD. A standard invoice needs it to be issued. Send null to clear it.
payment_means_codestringNoHow the buyer pays, as a UNTDID 4461 code: 10 cash, 30 credit transfer (the default), 42 bank account, 48 card, 1 unspecified. It is printed on the document and does not record a payment.
notesstringNoFree-form notes on the invoice, up to 2,000 characters. Send null to clear them.
itemsobject[]YesThe invoice lines, from 1 to 500. Each line's fields are described below as items[].….
items[].product_idintegerNoThe catalog product this line is for, from products_list. It must be one of your organization's products.
items[].sales_order_item_idintegerNoThe sales order line this invoice line bills.
items[].descriptionstringYesWhat is invoiced, 1 to 1,000 characters.
items[].quantitynumberYesThe quantity, above 0.
items[].unit_codestringNoThe unit of measure as a UN/ECE Recommendation 20 code, up to 10 characters. Defaults to PCE (piece); others include BX (box), PK (pack) and KGM (kilogram).
items[].unit_pricenumberYesThe price per unit before VAT, in the invoice's currency, 0 or more, with up to four decimals.
items[].discount_amountnumberNoA discount as an amount, not a percentage, taken off this line, 0 or more. Anything above the line's gross amount is cut off.
items[].vat_categorystringNoThe VAT category: S standard-rated (the default), Z zero-rated, E exempt or O out of scope.
items[].vat_ratenumberNoThe VAT rate as a whole percent, 0 to 100. Defaults to 15 for S and 0 for the other categories. To issue, an S line needs a rate above 0 and a Z, E or O line needs 0.
items[].vat_exemption_codestringNoZATCA's exemption reason code for a Z, E or O line, up to 30 characters, for example VATEX-SA-35 for medicines and medical equipment. It is required to issue such a line and ignored on an S line. Send null to clear it.
items[].vat_exemption_reasonstringNoThe exemption reason as text, up to 500 characters. If you leave it out, it is filled from the code when the code is on ZATCA's list. Send null to clear it.
{
  "customer_id": 214,
  "transaction_type": "standard",
  "sales_order_id": 87,
  "supply_date": "2026-10-04",
  "payment_means_code": "30",
  "items": [
    {
      "description": "Disposable syringe 5 ml, box of 100",
      "quantity": 40,
      "unit_code": "BX",
      "unit_price": 38.5,
      "vat_category": "Z",
      "vat_exemption_code": "VATEX-SA-35"
    },
    {
      "description": "Delivery to Riyadh warehouse",
      "quantity": 1,
      "unit_price": 150
    }
  ]
}
Example arguments

Returns: The new draft's ID as invoice_id. Read it back with invoices_get.

  • Totals are calculated per line and rounded to the cent: the net is quantity times unit price minus the discount, VAT is applied at the line's rate, and the invoice totals are the sums of its lines.
  • A standard invoice needs the buyer's VAT number or another identifier, a street, building number, city and postal code, and a supply date before it can be issued. A simplified invoice needs only the customer name. A zero-rated medical line takes category Z with VATEX-SA-35.
  • A customer, sales order, quotation, product or original invoice that is not found in your organization, or a tender you cannot see, answers 404. A note whose original is not an issued tax invoice answers 400.

invoices_update

Changes a draft. Only the fields you send change, null clears a field that can be empty, and items, when sent, replaces all the lines. An issued invoice cannot be changed: issue a credit or debit note that references it instead.

Changes data · scope invoices.write · roles: owner, admin, sales, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.
customer_idintegerNoThe customer profile the document is linked to, from customers_list. It does not refill the buyer fields, so send the ones you want changed. Send null to unlink.
customer_namestringNoThe buyer's name, 1 to 200 characters.
document_typestringNoThe document: invoice, credit_note or debit_note. Switching back to invoice clears the original invoice and the reason.
transaction_typestringNoThe kind: standard for B2B or simplified for B2C.
original_invoice_idintegerNoFor a credit or debit note: the issued tax invoice it corrects. It is required to issue the note and may be left empty while it is a draft. It must be an issued tax invoice of your organization, not a draft and not another note. Ignored for invoice. Send null to clear it.
reasonstringNoFor a credit or debit note: why it is issued, up to 500 characters. Required to issue the note. Send null to clear it.
buyer_vat_numberstringNoThe buyer's Saudi VAT number: 15 digits starting and ending with 3. A malformed number blocks issue. Send null to clear it.
buyer_id_schemestringNoThe kind of the buyer's other identifier, for a buyer with no VAT number: CRN commercial registration, MOM municipal licence (MOMRA), MLS HR ministry licence (MHRSD), 700 the unified 700 number, SAG investment licence (MISA), NAT national ID, GCC GCC citizen ID, IQA iqama, PAS passport, OTH other. Send it with buyer_id_value. Send null to clear it.
buyer_id_valuestringNoThe value of the other identifier, such as the commercial registration number, up to 50 characters. A standard invoice to a buyer with no VAT number needs it together with buyer_id_scheme. Send null to clear it.
buyer_street_namestringNoThe street of the buyer's national address, up to 200 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_building_numberstringNoThe building number, up to 10 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_districtstringNoThe district, up to 100 characters. Send null to clear it.
buyer_citystringNoThe city, up to 100 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_postal_codestringNoThe postal code, up to 10 characters. A standard invoice needs it to be issued. Send null to clear it.
buyer_additional_numberstringNoThe additional number of the national address, up to 10 characters. Send null to clear it.
buyer_country_codestringNoThe buyer's two-letter country code (ISO 3166-1). Defaults to SA.
sales_order_idintegerNoThe sales order the invoice bills, from sales_orders_list. It must be one of your organization's orders. Send null to unlink.
quotation_idintegerNoThe quotation the sale came from, from quotations_list. It must be one of your organization's quotations. Send null to unlink.
tender_idintegerNoThe tender the sale relates to, for reference, from tenders_list. Send null to unlink.
currencystringNoThe three-letter currency code (ISO 4217). Defaults to SAR.
supply_datestringNoThe date of supply, as YYYY-MM-DD. A standard invoice needs it to be issued. Send null to clear it.
payment_means_codestringNoHow the buyer pays, as a UNTDID 4461 code: 10 cash, 30 credit transfer (the default), 42 bank account, 48 card, 1 unspecified. It is printed on the document and does not record a payment.
notesstringNoFree-form notes on the invoice, up to 2,000 characters. Send null to clear them.
itemsobject[]NoWhen sent, this list replaces all the current lines (1 to 500) and the totals are recalculated. Leave it out to keep the lines as they are.
items[].product_idintegerNoThe catalog product this line is for, from products_list. It must be one of your organization's products.
items[].sales_order_item_idintegerNoThe sales order line this invoice line bills.
items[].descriptionstringYesWhat is invoiced, 1 to 1,000 characters.
items[].quantitynumberYesThe quantity, above 0.
items[].unit_codestringNoThe unit of measure as a UN/ECE Recommendation 20 code, up to 10 characters. Defaults to PCE (piece); others include BX (box), PK (pack) and KGM (kilogram).
items[].unit_pricenumberYesThe price per unit before VAT, in the invoice's currency, 0 or more, with up to four decimals.
items[].discount_amountnumberNoA discount as an amount, not a percentage, taken off this line, 0 or more. Anything above the line's gross amount is cut off.
items[].vat_categorystringNoThe VAT category: S standard-rated (the default), Z zero-rated, E exempt or O out of scope.
items[].vat_ratenumberNoThe VAT rate as a whole percent, 0 to 100. Defaults to 15 for S and 0 for the other categories. To issue, an S line needs a rate above 0 and a Z, E or O line needs 0.
items[].vat_exemption_codestringNoZATCA's exemption reason code for a Z, E or O line, up to 30 characters, for example VATEX-SA-35 for medicines and medical equipment. It is required to issue such a line and ignored on an S line. Send null to clear it.
items[].vat_exemption_reasonstringNoThe exemption reason as text, up to 500 characters. If you leave it out, it is filled from the code when the code is on ZATCA's list. Send null to clear it.
{
  "id": 311,
  "supply_date": "2026-10-05",
  "buyer_vat_number": "300012345600003"
}
Example arguments

Returns: The draft's ID as invoice_id.

  • An issued invoice answers 409 whatever you send, and an invoice that is not in your organization answers 404.
  • Sending items deletes the current lines and puts the new ones in their place, so send the whole list, not only the lines that changed.

invoices_delete

Deletes a draft. An issued invoice is a tax record and cannot be deleted. The deletion stays in the activity log.

Deletes or overwrites data · scope invoices.write · roles: owner, admin, sales, purchasing · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.

Returns: A confirmation (ok: true).

  • An issued invoice answers 409. Correct an issued invoice with a credit or debit note.

Issuing and sending to ZATCA

Issuing is the one step that cannot be undone, and only an admin or the owner may take it.

invoices_issue

Issues a draft: it assigns the sequential number and the issue date and time (Riyadh), builds and stamps the invoice XML, adds the QR code, freezes the document and sends it to ZATCA, for clearance if it is a standard invoice or reporting if it is a simplified one. This cannot be undone.

Changes data · scope invoices.write · roles: owner, admin · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.

Returns: invoice_id, invoice_number, signed (false when issued without a live unit), zatca_status (cleared, reported, rejected, pending or none), zatca_has_warnings and zatca_error (ZATCA's messages on a rejection).

  • A draft that lacks something ZATCA requires answers 400 with issues, a list of field codes, and stays a draft with no number used. Read readiness_issues from invoices_get before issuing.
  • With no live e-invoicing unit the invoice is still issued, with a five-field QR code and zatca_status none, and it can never be sent to ZATCA afterwards. Set the unit up first if the invoice must reach ZATCA.
  • pending means ZATCA could not be reached: the invoice is issued and stamped, and invoices_submit sends the same file again. A rejected invoice keeps its number, and if the cause was on the unit's side and is fixed, it can be sent again.
  • Answers 409 when the invoice is already issued, and when another invoice of your organization is being issued at that moment (try again shortly).

invoices_submit

Sends an issued invoice to ZATCA again with the same stored, stamped file, so its hash does not change. Use it for an invoice left pending by an outage, or rejected for a reason on the unit's side that has since been fixed.

Changes data · scope invoices.write · roles: owner, admin · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.

Returns: invoice_id, invoice_number, signed, zatca_status, zatca_has_warnings and zatca_error, as in invoices_issue.

  • Answers 409 for a draft, for an invoice issued without a live unit (it carries no stamp), for an invoice ZATCA has already accepted (cleared or reported), and when the unit that stamped it is no longer live.

Files and the archive

invoice_pdf

Prints the invoice as a PDF in Arabic with English, with its QR code and VAT breakdown. A draft prints as a watermarked preview without a QR code.

Read-only · scope invoices.read · roles: owner, admin, sales, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.

Returns: A PDF file with filename, content_type, size_bytes and the content as base64 in base64.

  • A file over 4 MB is not embedded in the reply; the tool answers with an error that names the REST endpoint to download it from. Every download is recorded in the activity log.

invoice_xml

Returns an issued invoice's signed XML, the very file ZATCA received (UBL 2.1). With cleared: true it returns the copy ZATCA stamped at clearance instead.

Read-only · scope invoices.read · roles: owner, admin, sales, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
idintegerYesThe invoice's ID, from invoices_list.
clearedbooleanNoSet true for the copy ZATCA stamped at clearance instead of the submitted one. Only a cleared standard invoice has one. Defaults to false.

Returns: An XML file with filename, content_type, size_bytes and the content as base64 in base64.

  • A draft has no XML and answers 404, and so does cleared: true for an invoice ZATCA returned no cleared copy of. Every download is recorded in the activity log.

invoice_archive_zip

Packs the signed XML of every issued invoice, credit note and debit note into one ZIP, for your archive or an auditor. Files are named the way ZATCA asks you to keep them, and a manifest.json lists what is inside.

Read-only · scope invoices.read · roles: owner, admin · Pro and Enterprise plans

ParameterTypeRequiredDescription
fromstringNoThe first issue date to include, as YYYY-MM-DD.
tostringNoThe last issue date to include, as YYYY-MM-DD, inclusive. It must not be before from.

Returns: A ZIP file with filename, content_type, size_bytes and the content as base64 in base64. Each document is a file named <VAT number>_<issue date>T<issue time>_<invoice number>.xml, with ZATCA's stamped copy beside it as .cleared.xml where held, plus manifest.json with numbers, UUIDs, counters and hashes.

  • A window with more than 5,000 documents answers 413: narrow it with from and to. A window with no issued invoices answers 404.
  • An archive over 4 MB is not embedded in the reply; the tool answers with an error that names the REST endpoint to download it from. Every export is recorded in the activity log.

Activity log and verification

The platform writes the activity log itself and nobody can edit or delete a row, each row being chained to the previous one by hash. A verification tool checks the records as a whole.

invoice_events_list

Lists the e-invoicing activity log, newest first: every draft created, edited or deleted, each issue and submission to ZATCA, each PDF, XML and archive download, each verification and every step in the unit's life. Each row says who did it and through which channel.

Read-only · scope invoices.read · roles: owner, admin, sales, purchasing, viewer · Pro and Enterprise plans

ParameterTypeRequiredDescription
invoice_idintegerNoOnly the rows about this invoice.
eventstringNoOnly this event, one of invoice.created, invoice.updated, invoice.deleted, invoice.issued, invoice.submitted, invoice.pdf_downloaded, invoice.xml_downloaded, invoices.archived, chain.verified, unit.created, unit.compliance_csid, unit.compliance_checks, unit.production_csid, unit.renewed or unit.reset.
scopestringNoall for everything (the default), invoice for rows about a document, or unit for rows about the unit, archive exports and verifications.
fromstringNoThe start of the period, inclusive, as an ISO date or timestamp. A date alone means the start of that day (UTC).
tostringNoThe end of the period, exclusive, as an ISO date or timestamp.
pageintegerNoPage number, starting at 1.
page_sizeintegerNoRows per page: 50 by default, 100 at most.
{
  "scope": "invoice",
  "event": "invoice.issued",
  "from": "2026-10-01",
  "page_size": 25
}
Example arguments

Returns: A page of rows, each with id, invoice_id, invoice_number, event, actor_email, channel (app, api or system), detail, created_at, prev_hash and entry_hash, and the total count.

  • The channel app is the web app, api is any call through the API, MCP or the assistants on a member's behalf, and system is the platform acting on its own.
  • A row without an invoice_id is about the unit, an archive export or a verification.

zatca_chain_verify

Proves the e-invoicing records intact. It re-hashes every issued document from its stored XML and checks each stamp against the certificate inside the file, each invoice's link to the previous one and the counter sequence, the unit's counter and last hash, and the activity log's own chain. It changes nothing except adding one chain.verified row to the log. Run it before an audit.

Read-only · scope settings.write · roles: owner · Pro and Enterprise plans

No parameters.

Returns: An object with ok, checked_at, invoices (documents examined), chains (one per unit that stamped documents, each with ok, issues, last_hash and highest_icv), phase1 (documents issued without a unit), unit (the counter and last-hash checks) and log (the activity log's chain).

  • Each problem in issues names the invoice and a code for what does not hold: hash_mismatch, signature_invalid, signature_missing, pih_mismatch, icv_gap, icv_duplicate, xml_row_mismatch, xml_missing or certificate_unreadable.
  • It needs the write scope settings.write although none of your invoice data changes, because the run is recorded in the activity log.