Creating an Invoice
This guide walks you through creating an invoice using the invoiceCreate mutation. Before calling it, you'll need a few pieces of information: a customer, a product and a document set.
Prerequisites
To create an invoice you need:
- A customer ID: the customer you're billing
- A product ID: the item(s) being invoiced
- A document set ID: the numbering series for the invoice
If you don't already have these IDs, you can fetch them with the queries shown below.
Fetching a document set
A document set is a numbering series for documents. Each company has one or more document sets, and each set can be associated with multiple document types (e.g. a single set may handle both invoices and receipts). Use documentSetsForDocument to get the sets that are configured for invoices in your company:
query {
documentSetsForDocument(companyId: 1, documentTypeId: 1) {
errors { field msg }
data {
documentSetId
name
isDefault
}
}
}
Document types are system-defined and fixed. See the Document Types guide for the complete list of IDs and codes, or use the documentTypes query at runtime.
Pick the documentSetId from the appropriate series.
Fetching a customer
query {
customers(companyId: 1, options: {
search: { field: ALL, value: "Acme" }
pagination: { page: 1, qty: 5 }
}) {
data {
customerId
name
vat
}
}
}
Fetching a product
query {
products(companyId: 1, options: {
search: { field: ALL, value: "Chair" }
pagination: { page: 1, qty: 5 }
}) {
data {
productId
name
reference
price
}
}
}
Required fields
The InvoiceInsert input has these required fields:
| Field | Type | Description |
|---|---|---|
documentSetId | Int! | The document set (numbering series) to use |
customerId | Int! | The customer being billed |
date | DateTime! | Invoice date |
expirationDate | Date! | Payment due date |
products | [DocumentProductInput!]! | Line items (at least one) |
Each line item in the products array requires at minimum:
| Field | Type | Description |
|---|---|---|
productId | Int! | The product ID |
qty | Float! | Quantity |
ordering | Int! | Position of the line (starting from 1) |
See DocumentProductInput for all available fields.
Creating a simple invoice
This example creates a finalized invoice for 2 units of a product:
mutation {
invoiceCreate(
companyId: 1
data: {
documentSetId: 4
customerId: 42
date: "2025-03-20T10:00:00.000Z"
expirationDate: "2025-04-20"
status: 1
products: [
{
productId: 88
qty: 2
ordering: 1
}
]
}
) {
errors { field msg }
data {
documentId
number
date
expirationDate
totalValue
grossValue
taxesValue
status
}
}
}
Response:
{
"data": {
"invoiceCreate": {
"errors": [],
"data": {
"documentId": 1234,
"number": 56,
"date": "2025-03-20T10:00:00.000Z",
"expirationDate": "2025-04-20",
"totalValue": 99.98,
"grossValue": 81.28,
"taxesValue": 18.70,
"status": 1
}
}
}
}
An empty errors array means the invoice was created successfully. The response includes the generated documentId and sequential number.
Draft vs finalized
The status field controls whether the invoice is a draft or finalized:
| Status | Meaning |
|---|---|
0 | Draft: can be edited or deleted |
1 | Finalized: locked, assigned a sequential number, reported to tax authorities (if applicable) |
To create a draft, set status: 0 (or omit it):
mutation {
invoiceCreate(
companyId: 1
data: {
documentSetId: 4
customerId: 42
date: "2025-03-20T10:00:00.000Z"
expirationDate: "2025-04-20"
status: 0
products: [
{
productId: 88
qty: 2
ordering: 1
}
]
}
) {
errors { field msg }
data {
documentId
number
status
}
}
}
Handling errors
Always check the errors array before using data. If validation fails, the API returns one or more errors indicating which field caused the problem:
{
"data": {
"invoiceCreate": {
"errors": [
{
"field": "customerId",
"msg": "The customer provided does not exist for this company"
}
],
"data": null
}
}
}
Common validation errors include:
- Invalid or missing
documentSetId - Customer not found for the given company
- Product not found
- Missing required fields (
date,expirationDate) - Invalid date formats
See the Error Handling guide for the full error model and best practices.
Optional fields
Beyond the required fields, InvoiceInsert supports a variety of optional fields:
| Field | Type | Description |
|---|---|---|
notes | String | Free-text notes on the invoice |
yourReference | String | Customer's reference (e.g. PO number) |
ourReference | String | Internal reference number |
globalDiscount | Float | Discount percentage applied to the whole invoice (0–100) |
salespersonId | Int | Assign a salesperson |
alternateAddressId | Int | Use an alternate delivery address for the customer |
currencyExchangeId | Int | Foreign currency exchange rate |
See the full list in the InvoiceInsert reference page.
Overriding line item details
Each product line can override catalog defaults:
products: [
{
productId: 88
qty: 5
ordering: 1
price: 39.99
discount: 10
}
]
| Field | Description |
|---|---|
price | Override the catalog price |
discount | Line-level discount percentage (0–100) |
summary | Override the product description |
warehouseId | Deduct stock from a specific warehouse |
exemptionReason | Tax exemption reason for this line |
See DocumentProductInput for all options.
Next steps
- Paying an Invoice: Record payment against this invoice
- Querying Documents: List, filter and search your documents
- Downloading a Document PDF: Export this invoice as a PDF
- See
invoiceCreateandInvoiceInsertfor all fields