Invoices
Create, retrieve, update, and manage sales invoices.
Invoices represent legally issued sales documents and drive revenue recognition, VAT accounting, and receivables.
Authentication
All endpoints require a valid API key. See Authentication.
The invoice object
{
"id": "inv_42",
"invoiceNumber": "INV-0001",
"status": "sent",
"contactId": "cont_17",
"contact": {
"id": "cont_17",
"name": "Acme Corporation"
},
"currency": "GBP",
"items": [
{
"id": "line_1",
"description": "Consulting services",
"quantity": 10,
"unitPrice": 50000,
"vatRate": 20,
"vatAmount": 100000,
"lineTotal": 600000
}
],
"subtotal": 500000,
"vatAmount": 100000,
"total": 600000,
"amountPaid": 0,
"amountDue": 600000,
"issueDate": "2026-01-31",
"dueDate": "2026-03-02",
"paidDate": null,
"notes": "Payment due within 30 days",
"reference": "PO-12345",
"createdAt": "2026-01-31T10:00:00Z",
"updatedAt": "2026-01-31T10:00:00Z"
}
Invoice attributes
| Field | Type | Description |
|---|---|---|
id | string | Unique invoice identifier (e.g., inv_42) |
invoiceNumber | string | Human-readable invoice number |
status | string | draft, sent, paid, overdue, void |
contactId | string | Customer contact ID |
currency | string | ISO 4217 currency code |
items | array | Line items |
subtotal | integer | Total before VAT (minor units) |
vatAmount | integer | Total VAT (minor units) |
total | integer | Total including VAT (minor units) |
amountPaid | integer | Amount received (minor units) |
amountDue | integer | Outstanding balance (minor units) |
issueDate | string | Date the invoice was issued |
dueDate | string | Payment due date |
paidDate | string | Date fully paid (null if unpaid) |
notes | string | Notes shown on invoice |
reference | string | Customer reference (e.g., PO number) |
Create an invoice
POST /v1/invoices
curl -X POST https://api.speybooks.com/v1/invoices \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"contactId": "cont_17",
"currency": "GBP",
"items": [
{
"description": "Consulting services",
"quantity": 10,
"unitPrice": 50000,
"vatRate": "standard"
}
],
"dueDays": 30,
"notes": "Payment due within 30 days"
}'
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | Customer contact ID |
currency | string | No | Defaults to organisation currency |
items | array | Yes | Line items |
issueDate | string | No | Defaults to today |
dueDate | string | No | Explicit due date |
dueDays | integer | No | Days until due (alternative to dueDate) |
notes | string | No | Notes shown on invoice |
reference | string | No | Customer reference |
Line item parameters
| Field | Type | Required | Description |
|---|---|---|---|
description | string | Yes | Line item description |
quantity | number | Yes | Quantity |
unitPrice | integer | Yes | Price per unit (minor units) |
vatRate | string | Yes | standard, reduced, zero, exempt |
Response
{
"success": true,
"data": {
"id": "inv_42",
"invoiceNumber": "INV-0001",
"status": "draft",
"contactId": "cont_17",
"subtotal": 500000,
"vatAmount": 100000,
"total": 600000,
"issueDate": "2026-01-31",
"dueDate": "2026-03-02",
"createdAt": "2026-01-31T10:00:00Z"
}
}
Retrieve an invoice
GET /v1/invoices/:id
curl https://api.speybooks.com/v1/invoices/inv_42 \
-H "Authorization: Bearer sk_live_your_api_key"
List invoices
GET /v1/invoices
curl "https://api.speybooks.com/v1/invoices?status=sent&limit=20" \
-H "Authorization: Bearer sk_live_your_api_key"
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by invoice status |
contactId | string | Filter by customer |
fromDate | string | Issue date from (inclusive) |
toDate | string | Issue date to (inclusive) |
page | integer | Page number (default: 1) |
limit | integer | Results per page (1–100) |
Response
{
"success": true,
"data": [
{ "id": "inv_42", "invoiceNumber": "INV-0001", "total": 600000, "status": "sent" },
{ "id": "inv_43", "invoiceNumber": "INV-0002", "total": 240000, "status": "draft" }
],
"meta": {
"total": 156,
"page": 1,
"limit": 20,
"hasMore": true
}
}
Update an invoice
Only invoices in the draft state can be updated.
PUT /v1/invoices/:id
curl -X PUT https://api.speybooks.com/v1/invoices/inv_42 \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"notes": "Updated payment terms",
"dueDate": "2026-03-15"
}'
Send an invoice
Marks the invoice as issued and optionally emails it to the customer.
POST /v1/invoices/:id/send
curl -X POST https://api.speybooks.com/v1/invoices/inv_42/send \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"sendEmail": true
}'
Parameters
| Field | Type | Default | Description |
|---|---|---|---|
sendEmail | boolean | false | Email invoice to customer |
Response
{
"success": true,
"data": {
"id": "inv_42",
"status": "sent",
"sentAt": "2026-01-31T10:10:00Z"
}
}
Download invoice PDF
GET /v1/invoices/:id/pdf
Returns the invoice as a PDF document.
curl https://api.speybooks.com/v1/invoices/inv_42/pdf \
-H "Authorization: Bearer sk_live_your_api_key" \
--output invoice.pdf
Record a payment
POST /v1/invoices/:id/payments
curl -X POST https://api.speybooks.com/v1/invoices/inv_42/payments \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"amount": 600000,
"date": "2026-02-15",
"method": "bank_transfer",
"reference": "BACS-123456"
}'
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Payment amount (minor units) |
date | string | Yes | Payment date |
method | string | No | bank_transfer, card, cash, other |
reference | string | No | Payment reference |
Response
{
"success": true,
"data": {
"id": "pay_1",
"invoiceId": "inv_42",
"amount": 600000,
"date": "2026-02-15",
"method": "bank_transfer",
"createdAt": "2026-02-15T14:00:00Z"
}
}
When the invoice balance reaches zero, its status changes to paid automatically.
Void an invoice
Voids an invoice permanently.
POST /v1/invoices/:id/void
curl -X POST https://api.speybooks.com/v1/invoices/inv_42/void \
-H "Authorization: Bearer sk_live_your_api_key"
Constraints:
- Only invoices with no recorded payments can be voided
- Voiding is irreversible
Invoice lifecycle
draft → sent → paid
↓
overdue
| Status | Description |
|---|---|
draft | Created but not issued |
sent | Issued and awaiting payment |
overdue | Past due date and unpaid |
paid | Fully settled |
void | Cancelled and removed from the ledger |
State transitions are enforced by the API.
Common errors
| Code | HTTP | Description |
|---|---|---|
validation_error | 400 | Missing required field or invalid data |
invalid_id | 400 | Malformed invoice ID (expected inv_*) |
not_found | 404 | Invoice does not exist |
unprocessable_entity | 422 | Cannot update non-draft invoice |
unprocessable_entity | 422 | Cannot void invoice with payments |
Key principles
- Invoices are immutable once issued
- Payments settle balances, not revenue
- State transitions are explicit
- Accounting entries are generated automatically
Invoices in SpeyBooks are ledger-backed objects, not editable documents.
Amount format
All monetary values are in minor units (pence for GBP). 600000 = £6,000.00