Step 7 — Invoicing
7.1 Preview lines
POST /gateway/service-order/invoice/preview
Content-Type: application/json
Authorization: Bearer {token}
{
"serviceOrderGuid": "ORDER-GUID",
"documentTypeKeyId": "FAC",
"hoursBillingMode": "ExtraOnly"
}
The equivalent for a standalone intervention is POST /gateway/intervention/invoice/preview, with interventionGuid.
Preview lines come from order/intervention details, plus valued hours and km. Without those, preview returns ServiceOrderInvoice.NothingToInvoice / InterventionInvoice.NothingToInvoice.
The response includes customer data and proposed lines, each with itemKeyId, itemDescription, quantity, retailPrice, netPrice, taxId, isComment and — crucially — originBodyGuid and relationType, which keep traceability to the source intervention.
hoursBillingMode
| Mode | Behaviour |
|---|---|
Full (0) | Invoice all hours used, ignoring the ceiling |
ExtraOnly (1) | Invoice only hours above the available ceiling. Requires a linked contract; otherwise returns ExtraOnlyRequiresContract |
None (2) | Do not invoice hours or km, only consumed items |
In ExtraOnly, the hours grouping header becomes “extra-contract hours”. When invoicing an order with several interventions on the same contract, the ceiling is consumed progressively across interventions (instead of each one seeing a full ceiling).
7.2 Issue
Lines returned by the preview (after the user may adjust them) are sent to the generic endpoint, with the SAT origin declared on the header:
POST /gateway/invoice/invoices
Content-Type: application/json
Authorization: Bearer {token}
{
"documentTypeId": 1,
"serieId": 2026,
"entityKeyId": "C0001",
"serviceOrderGuid": "ORDER-GUID",
"documentBodies": [
{
"itemKeyId": "HORAS",
"itemDescription": "Intervention hours",
"quantity": 2.5,
"retailPrice": 25.00,
"taxId": 3,
"originBodyGuid": "INTERVENTION-GUID",
"relationType": "ServiceOrderInterventionHours"
}
],
"payments": [
{
"paymentTypeId": 1,
"amount": 76.88
}
]
}
Preview uses documentTypeKeyId (alphanumeric) and issue uses documentTypeId (numeric). Always resolve via GET /gateway/document-type — IDs are not portable across tenants.
On issue, the API validates that the SAT origin exists and is billable, confirms submitted lines belong to the order/intervention declared on the header, and links the document to the service order.
After invoicing
GET /gateway/intervention/{guid}/billing-detailsGET /gateway/service-order/{guid}/issued-documents
If the service order was invoiced, the intervention no longer lists that invoice as its own document — it only shows documents that actually belong to it.
Next
RMA (parallel flow) or common errors.