Invoices
See a contract's invoices, payments, credit notes and refunds, and raise new invoices.
The CRM keeps invoices, payments (receipts), credit notes and refunds in one ledger per contract.
The API shows the ledger with each entry's kind, and lets you raise invoices and
record payments.
GET Invoice types
/v1/invoices/typesWhat type means on the write calls: your organisation's invoice types by kind, and the payment
methods. No parameters. Cached for five minutes.
curl https://api.evacrm.co.uk/v1/invoices/types \
-H "Authorization: Bearer sk_..."{
"types": [
{ "id": "…", "name": "Deposit Invoice", "kind": "invoice", "description": null, "numberPrefix": "INV", "deposit": true, "lineItems": false },
{ "id": "…", "name": "Balance Invoice", "kind": "invoice", "description": null, "numberPrefix": "BAL", "deposit": false, "lineItems": false },
{ "id": "…", "name": "Receipt", "kind": "payment", "description": null, "numberPrefix": "REC", "deposit": false, "lineItems": false },
{ "id": "…", "name": "Credit Note", "kind": "creditNote", "description": null, "numberPrefix": "CRN", "deposit": false, "lineItems": false }
],
"paymentMethods": [ { "id": "…", "name": "BACS" }, { "id": "…", "name": "Card" } ]
}GET List a contract's ledger
/v1/contracts/{id}/invoicesEvery entry on the contract, oldest first.
idstring · uuidRequiredThe contract's id.
kindstringOnly entries of that kind. All by default.
invoice, payment, creditNote, refundcurl "https://api.evacrm.co.uk/v1/contracts/6c99094a-6f2e-4c7d-9b1e-2b4a8f3c1d05/invoices?kind=invoice" \
-H "Authorization: Bearer sk_..."{
"object": "list",
"data": [
{
"id": "…",
"number": "INV000189",
"kind": "invoice",
"type": { "id": "…", "name": "Deposit Invoice" },
"status": "paid",
"description": "Deposit",
"dateRaised": "2026-09-01T00:00:00.000+01:00",
"receivedDate": null,
"dueDate": "2026-09-08T00:00:00.000+01:00",
"amounts": { "net": 416.67, "vat": 83.33, "vatRate": 20, "gross": 500, "balance": 0, "allocated": 500 },
"paymentMethod": null,
"contract": { "id": "…", "code": "CON000561" },
"allocations": [
{ "id": "…", "amount": 500, "with": { "id": "…", "number": "REC000191", "kind": "payment" }, "createdAt": "…" }
],
"items": [],
"exported": false,
"exportedAt": null,
"createdAt": "…",
"updatedAt": "…"
}
]
}statusis the CRM's:not_raised,draft,raised,matched,paid_part,paid,cancelled.amounts.balanceis what is still outstanding on an invoice, or still unallocated on a payment.allocatedis the difference fromgross.allocationsname the other side of each match: the payment on an invoice, the invoice on a payment.numberis the CRM's printed number and can be used anywhere an invoice id is accepted.
GET Get an entry
/v1/invoices/{id}One entry of any kind, by id or by number.
Numbers come from a sequence and are unique in practice, but the CRM does not enforce it: an
import or a manual edit can repeat one. If a number matches more than one entry the API answers
409 with the candidate ids rather than guessing, and the same request by id resolves it. The
same rule applies wherever a number is accepted in place of an id.
idstring · id or numberRequiredThe entry's id, or its number such as INV000189.
curl https://api.evacrm.co.uk/v1/invoices/INV000189 \
-H "Authorization: Bearer sk_..."{
"id": "e3f4a5b6-c7d8-4e9f-0a1b-2c3d4e5f6071",
"number": "INV000189",
"kind": "invoice",
"type": {
"id": "…",
"name": "Deposit Invoice"
},
"status": "paid",
"description": "Deposit",
"dateRaised": "2026-09-01T00:00:00.000+01:00",
"receivedDate": null,
"dueDate": "2026-09-08T00:00:00.000+01:00",
"amounts": {
"net": 416.67,
"vat": 83.33,
"vatRate": 20,
"gross": 500,
"balance": 0,
"allocated": 500
},
"paymentMethod": null,
"contract": {
"id": "6c99094a-6f2e-4c7d-9b1e-2b4a8f3c1d05",
"code": "CON000561"
},
"allocations": [
{
"id": "…",
"amount": 500,
"with": {
"id": "3a1f0c92-7d4e-4b8a-9c21-5e6f7a8b9c0d",
"number": "REC000191",
"kind": "payment"
},
"createdAt": "2026-09-02T10:14:03.512+01:00"
}
],
"items": [],
"exported": false,
"exportedAt": null,
"createdAt": "2026-09-01T09:00:00.000+01:00",
"updatedAt": "2026-09-02T10:14:03.512+01:00"
}GET Download a PDF
/v1/invoices/{id}/pdfA link to the entry as a PDF, produced the way the CRM's own download button produces it: the organisation's invoice, credit note or receipt template, the invoice type's template override where one is set, and the reverse-charge template when the tax band calls for it. Works for payments too, which come out as receipts.
The link points at the CRM's PDF service, needs no key, and is good for 30 minutes. Fetch the file straight away rather than storing the link; ask again for a fresh one.
idstring · id or numberRequiredThe entry's id, or its number such as INV000189.
curl https://api.evacrm.co.uk/v1/invoices/INV000189/pdf \
-H "Authorization: Bearer sk_..."
# then fetch the file
curl -L -o INV000189.pdf "https://pdf-api.crummy.io/gen/3f9c…?action=download"{
"url": "https://pdf-api.crummy.io/gen/3f9c2a7e1b4d8f60a5c3e9b1d2f4a6c8?action=download",
"fileName": "Invoice INV000189.pdf",
"expiresAt": "2026-09-03T10:45:12.000+01:00"
}POST Create an invoice
/v1/contracts/{id}/invoicesNot available yet. The route is reserved and answers 501. The CRM creates a contract's deposit and balance invoices when a lead converts; raise those with raise an invoice. Creating further invoices through the API will be announced in the changelog.
{
"error": "Creating invoices is not available yet",
"hint": "The CRM creates a contract's invoices on conversion; raise one with POST /v1/invoices/{id}/raise"
}POST Raise an invoice
/v1/invoices/{id}/raiseRaises an invoice the CRM has already prepared. When a lead converts, the CRM creates the
contract's deposit and balance invoices with status not_raised, no number and the amounts from
the sale; raising one gives it the next number, raised status and its balance, and updates the
contract's summary. The amount is the CRM's and cannot be set here.
No field is required: an empty body raises it today, due on receipt.
idstring · id or numberRequiredThe invoice's id or number.
dateRaisedstring · date or date-timeCannot be earlier than the day the invoice was created; backdating is a staff permission the API does not carry.
todaydueDatestring · date or date-timeLeft out, the invoice is due on receipt: the same day it is raised. Not with dueDays.
dateRaiseddueDaysinteger · 0 to 365Days after dateRaised. Not with dueDate.
curl -X POST https://api.evacrm.co.uk/v1/invoices/BAL000193/raise \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{ "dateRaised": "2026-09-02", "dueDays": 14 }'{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"number": "BAL000202",
"kind": "invoice",
"type": {
"id": "…",
"name": "Balance Invoice"
},
"status": "raised",
"description": "Balance",
"dateRaised": "2026-09-03T00:00:00.000+01:00",
"receivedDate": null,
"dueDate": "2026-09-17T00:00:00.000+01:00",
"amounts": {
"net": 3175,
"vat": 635,
"vatRate": 20,
"gross": 3810,
"balance": 3810,
"allocated": 0
},
"paymentMethod": null,
"contract": {
"id": "6c99094a-6f2e-4c7d-9b1e-2b4a8f3c1d05",
"code": "CON000561"
},
"allocations": [],
"items": [],
"exported": false,
"exportedAt": null,
"createdAt": "2026-09-01T09:00:00.000+01:00",
"updatedAt": "2026-09-03T09:12:41.020+01:00"
}POST Unraise an invoice
/v1/invoices/{id}/unraiseReturns a raised invoice to not_raised: the number is cleared (the next raise gets a fresh
one), the balance goes to zero and the contract's summary is recalculated. No body.
idstring · id or numberRequiredThe invoice's id or number.
curl -X POST https://api.evacrm.co.uk/v1/invoices/BAL000193/unraise \
-H "Authorization: Bearer sk_..."{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"number": null,
"kind": "invoice",
"type": {
"id": "…",
"name": "Balance Invoice"
},
"status": "not_raised",
"description": "Balance",
"dateRaised": null,
"receivedDate": null,
"dueDate": null,
"amounts": {
"net": 3175,
"vat": 635,
"vatRate": 20,
"gross": 3810,
"balance": 0,
"allocated": 0
},
"paymentMethod": null,
"contract": {
"id": "6c99094a-6f2e-4c7d-9b1e-2b4a8f3c1d05",
"code": "CON000561"
},
"allocations": [],
"items": [],
"exported": false,
"exportedAt": null,
"createdAt": "2026-09-01T09:00:00.000+01:00",
"updatedAt": "2026-09-03T09:15:02.311+01:00"
}DEL Delete an entry
/v1/invoices/{id}Deletes an entry of any kind that has no allocations and has not been exported, and recalculates the contract.
idstring · id or numberRequiredThe entry's id or number.
curl -X DELETE https://api.evacrm.co.uk/v1/invoices/BAL000193 \
-H "Authorization: Bearer sk_..."{ "deleted": true, "id": "…", "number": "BAL000193" }