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; use the documentTypes query to look up the ID for invoices.
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 with a Receipt: Record payment against this invoice
- Querying Documents: List, filter and search your invoices
- See
invoiceCreateandInvoiceInsertfor all fields