Posting sales & purchase invoices
Push invoices and credit notes, with or without their PDF, as book entries.
ConventionsIn the examples,
$API_URLstands for theapi_urlof the connected license and$ACCESS_TOKENfor a valid access token. See Quickstart.
Sales and purchase invoices pushed through the API are converted into book entries in the corresponding daybook. The response contains the generated book entry's Id.
| Action | Sales | Purchases |
|---|---|---|
| Create | invoices.sales.new | invoices.purchases.new |
| Update | invoices.sales.update | invoices.purchases.update |
Before you start
You need:
- the
FolderId, - the
DaybookIdof a sales or purchase daybook (daybooks.list, types200/250for sales and100/150for purchases), - the
CompanyIdof the customer or supplier, found or created as described in Managing customers & suppliers, - the search keys of the accounts to book each line on (
accounts.list), e.g.700000for sales or612000for purchases.
Create a sales invoice
{
"FolderId": "83f26e75-f474-4b09-a1d3-aa698e18fbf0",
"DaybookId": "87f48c7e-54d1-48d2-aed7-447e6003bc67",
"Type": 0,
"Number": 202409001,
"Date": "2024-09-04T00:00:00+00:00",
"DueDate": "2024-10-04T00:00:00+00:00",
"CompanyId": "32ebe925-23cc-4a3e-8b36-8b2b33780fc1",
"TotalAmount": 1210,
"BaseAmount": 1000,
"TaxAmount": 210,
"PaymentReferences": "+++040/7139/58328+++",
"Comment": "Invoice 2024-09-001",
"InvoiceLines": [
{
"Account": "700000",
"BaseAmount": 1000,
"TaxAmount": 210,
"TaxRate": 21,
"TaxOrigin": 0,
"TaxType": 0,
"Comment": "Consulting services"
}
]
}{ "Id": "0d6822be-8559-488a-b348-eea0dd4a735b" }Type is 0 for an invoice and 1 for a credit note.
Amount rules
The API checks that the invoice is consistent:
TotalAmount=BaseAmount+TaxAmount;- the sum of the lines'
BaseAmount= the invoice'sBaseAmount; - the sum of the lines'
TaxAmount= the invoice'sTaxAmount.
Two options let you relax these checks when needed:
| Option | Default | Effect |
|---|---|---|
OverrideTaxAmounts | false | Tax amounts are recalculated (base × rate) and adapted when the provided amount is within 1 cent. Set to true to force your own tax amounts. |
AllowUnbalanced | false | Unbalanced book entries are refused. Set to true to force the entry even though it is not balanced. |
VAT on invoice lines
Each line carries its VAT treatment through a combination of fields:
| Field | Sales | Purchases |
|---|---|---|
TaxRate | ✔ | ✔ |
TaxType (0 National, 1 European, 2 International) | ✔ | ✔ |
TaxOrigin | ✔ | ✔ |
TaxKind (0 Merchandises, 1 Goods & services, 2 Investments) | ✔ | |
TaxCondition / TaxConditionValue | ✔ | |
TaxCountryCode (OSS lines only, TaxOrigin = 13) | ✔ |
Only some combinations are valid. The accepted combinations are listed in these reference files:
Purchase-specific options
Purchase invoices support a few additional fields:
VehicleId, at invoice or line level: associates a vehicle with lines whose account requires one;PersonalShareon a line: the private portion of the expense, as a percentage of the line's total (base + tax) and the corresponding amount.
"InvoiceLines": [
{
"Account": "612000",
"BaseAmount": 1000,
"TaxAmount": 210,
"TaxRate": 21,
"TaxType": 0,
"TaxKind": 0,
"TaxCondition": 1,
"TaxConditionValue": "true",
"TaxOrigin": 2,
"PersonalShare": { "PersonalSharePercentage": 50, "PersonalShareAmount": 605.0 }
}
]Optional features
| Feature | Fields | Notes |
|---|---|---|
| Payment information | PaymentReferences, PaymentMode | E.g. a structured communication +++040/7139/58328+++. |
| Cash discount | Discount | Rate, amount and deadline. If no date is given, 7 days are added to the invoice date. |
| Foreign currency | CurrencyCode, CurrencyRate | null means EUR. The folder must be configured to allow currencies. If no rate is given, the rate of the day is used. |
| Matching | MatchNo | Pre-assign a matching number (see Outstanding items & matching). |
| Analytics | CostLines or CostDistributionKey per line | The sum of a line's cost lines must equal its BaseAmount. If both are provided, cost lines take precedence. |
Confirmation and numbering
Confirmed is false by default: the invoice is created as an unconfirmed entry that the accountant can review in Horus Office. Number is the invoice number associated with the book entry. It can be 0 when the invoice is not confirmed.
Attaching the invoice document
To send the invoice's PDF (or image/XML) together with the data, use multipart/form-data with two fields, file and body, and set FileName:
curl -X POST "$API_URL/invoices.purchases.new" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "[email protected]" \
-F 'body={
"FolderId": "83f26e75-f474-4b09-a1d3-aa698e18fbf0",
"DaybookId": "9d0c7b6a-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"Type": 0,
"Number": 0,
"Date": "2024-09-04T00:00:00+00:00",
"DueDate": "2024-10-04T00:00:00+00:00",
"CompanyId": "32ebe925-23cc-4a3e-8b36-8b2b33780fc1",
"TotalAmount": 121,
"BaseAmount": 100,
"TaxAmount": 21,
"FileName": "supplier-invoice-2024-118.pdf",
"InvoiceLines": [
{ "Account": "612000", "BaseAmount": 100, "TaxAmount": 21, "TaxRate": 21,
"TaxType": 0, "TaxKind": 0, "TaxCondition": 1, "TaxConditionValue": "true", "TaxOrigin": 2 }
]
}'See Documents & attachments for details.
Updating an invoice
invoices.sales.update and invoices.purchases.update take the BookEntryId of the invoice plus the complete invoice payload (same required fields as creation):
- the response contains the newly generated book entry's
Id: replace the one stored on your side; - the original attachment is deleted in both cases. Send the document again with
multipart/form-dataif it should be kept.
Updates are full replacementsUnlike master data updates (companies, accounts…), invoice updates are not partial: send the full invoice as it should be after the update.
Updated about 1 hour ago