Skip to main content

Orders API

A commercial order is how a subscription comes into existence, changes, or ends. This page covers the order document endpoints (PDF generation and email delivery) and the order-document-related fields on the order and billing-template resources. For the order lifecycle itself (create, validate, preview, cancel), see the API surface tour and the catalog to first invoice quickstart.

Prerequisites

A bearer token, per Authentication:

export TOKEN=$(curl -s -X POST "$KEYCLOAK_TOKEN_URL" \
-d "grant_type=client_credentials&client_id=$KEYCLOAK_CLIENT_ID&client_secret=$KEYCLOAK_CLIENT_SECRET" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

Order documents

Every commercial order can be rendered to a PDF document (a quote/order confirmation, not an invoice) and, optionally, emailed to the customer. Both endpoints use a dedicated ORDER billing template, never an invoice template, so the two document families can never cross-resolve into each other.

MethodPathDescription
GET/api/v1/orders/{code}/document?template=Download the order document as a PDF.
POST/api/v1/orders/{code}/document/email?template=Render the order document and email it as a PDF attachment.

Download the order document

curl -H "Authorization: Bearer $TOKEN" \
-o order-QS1_ORDER.pdf \
"https://acme.billerang.com/api/v1/orders/QS1_ORDER/document"

Response: 200, Content-Type: application/pdf, with Content-Disposition: attachment; filename="order-{code}.pdf". The response is the raw PDF bytes, not a JSON envelope.

The template defaults to the built-in order-default template, which is auto-provisioned on first use, so this call works out of the box with no setup. To render with a different, uploaded ORDER template, pass ?template=:

curl -H "Authorization: Bearer $TOKEN" \
-o order-QS1_ORDER.pdf \
"https://acme.billerang.com/api/v1/orders/QS1_ORDER/document?template=commercial_order_fr"

Rendering is stateless: nothing is persisted by this call, and the PDF is generated fresh on every request. Rated amounts come from the same virtual rating engine as POST /orders/preview, so a DRAFT order shows real prices, not placeholders. Quote-driven orders also include their persisted order price lines, including ONE_SHOT_INVOICING_PLAN milestones.

The document is available for every order status except CANCELED.

Errors:

StatusBodyCause
404ORDER_NOT_FOUNDNo order with that code.
404TEMPLATE_NOT_FOUNDThe requested ?template= does not exist.
400TEMPLATE_INVALIDThe template exists but is not usable for orders: its documentKind is not ORDER, or its renderingMode is not HTML.
409The order is CANCELED.

All error bodies are JSON, even though a successful response is a PDF stream.

Email the order document

curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{}' \
"https://acme.billerang.com/api/v1/orders/QS1_ORDER/document/email"

Every field in the body is optional; an empty object {} is a valid request and relies entirely on the defaults below.

FieldTypeRequiredDefaultDescription
tostringNoBilling account contact email, then the customer contact emailRecipient address. 400 NO_RECIPIENT if neither default resolves.
ccstring[]NoThe billing account's cced emailsDropped (not merged) when to is explicitly overridden.
subjectstringNo"Your order {orderNumber}"Email subject.
messagestringNoEmail body text.

The sender (from) is not a request field: it is always the seller's contact email, falling back to the platform's mail.from property when the seller has none.

?template= selects the ORDER template used to render the attached PDF, with the same default (order-default) and validation rules as the download endpoint above. The generated PDF is attached as order-{code}.pdf.

Response (200): the effective values after defaults resolution, so a caller can confirm who actually received the email.

{
"sent": true,
"to": ["billing@acme-customer.com"],
"cc": ["ap@acme-customer.com"],
"subject": "Your order ORD-2026-000042"
}

Errors:

StatusBodyCause
400NO_RECIPIENTNo to was given and neither the billing account nor the customer has a contact email.
400TEMPLATE_INVALIDSame template validation as the download endpoint.
404ORDER_NOT_FOUND / TEMPLATE_NOT_FOUNDNo order or template with that code/name.
409The order is CANCELED.

Auto-generate or auto-send on order create/update

POST /api/v1/orders and PUT /api/v1/orders/{code} accept two additional booleans on processingOptions, alongside the existing runBilling:

FieldTypeDescription
generatePdfbooleanRender the order document and store it under the tenant's orders/pdf storage.
sendByEmailbooleanRender the order document and email it, using the same recipient/subject defaults as POST /orders/{code}/document/email.
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"orderType": "NEW",
"orderOffers": [ ... ],
"processingOptions": {
"runBilling": false,
"generatePdf": true,
"sendByEmail": true
}
}' \
https://acme.billerang.com/api/v1/orders

Both run after the order is created/validated on POST (or after the DRAFT edit on PUT), and both are failure-tolerant: same contract as processingOptions.runBilling. A document rendering or email delivery failure is logged but never fails the order create/update call itself — the order operation always reflects only its own outcome.

Order document templates

Order documents are rendered through the same billing template resource used for invoices (/api/v1/billingTemplates), distinguished by a documentKind field.

POST /api/v1/billingTemplates (multipart upload) accepts:

FieldTypeRequiredDefaultDescription
documentKindstring, enum INVOICE|ORDERNoINVOICEThe business document this template renders. ORDER requires renderingMode=HTML; uploading an ORDER template with renderingMode=JASPER (or omitted, since JASPER is the rendering-mode default) returns 400.

BillingTemplateV1 (the read/list response) includes documentKind on every template, so a caller can tell invoice and order templates apart without inspecting the file bundle.

curl -X POST -H "Authorization: Bearer $TOKEN" \
-F "templateName=commercial_order_fr" \
-F "description=French commercial order confirmation" \
-F "renderingMode=HTML" \
-F "documentKind=ORDER" \
-F "htmlBody=@invoice.html" \
-F "cssBody=@styles.css" \
"https://acme.billerang.com/api/v1/billingTemplates"

ORDER templates use the same HTML bundle layout as HTML invoice templates: an invoice.html entry file, styles.css, and optional i18n/*.properties translation files. There is no separate entry-file naming for order documents; documentKind alone decides how the bundle is interpreted at render time.

ORDER template merge model

An HTML ORDER template is rendered with the following variables available:

VariableDescription
${order}The CommercialOrder entity: code, orderNumber, orderDate, activationDate, status, description.
${customerName} / ${customerCode}The order's customer.
${billingAccountName} / ${billingAccountCode} / ${billingAccountEmail}The order's billing account.
${sellerName}The seller issuing the order.
${offers}List of {offerLabel, subscriptionCode, products: [{productLabel, quantity}]}, one entry per order offer line.
${lines}List of {label, chargeCode, type, quantity, amountWithoutTax}. type is one of ONE_TIME, RECURRING, USAGE, INVOICING_PLAN.
${totals}{oneTime, recurring, tax, withTax, currency}, the aggregated order amounts.
${generatedOn}Timestamp the document was rendered.
${i18n}Translation helper, resolved against the template's i18n/*.properties bundle for the requested locale.
${baseUrl}Base URL for resolving relative asset references (images, fonts) from the template bundle.

This mirrors the invoice HTML template's merge model in shape (entity plus computed totals plus an ${i18n} helper), but with order-specific fields: ${offers}/${lines} in place of invoice lines, and no payment or due-date block, since an order document is a confirmation, not a bill.

See also

  • API principles for the update-semantics, idempotency, and error-model conventions shared by every v1 resource, including processingOptions.runBilling.
  • Catalog to first invoice quickstart for the full order lifecycle, run live, from offer to validated invoice.
  • The full request/response schemas (CommercialOrderV1Dto, ProcessingOptionsV1Dto, OrderDocumentEmailV1Dto, BillingTemplateUploadFormV1) are in the Interactive API Explorer.