Invoices
External read API for billing invoices and invoice PDFs.
Invoices
Prefix: /api/v1/external/invoices
See Overview for authentication, pagination, and errors.
Read-only access to billing Invoice records (header plus line items) and the stored invoice PDF. Invoices are produced by billing runs; this API does not create or edit them.
Picklists (invoiceStatus, invoiceType, paymentStatus, approvalStatus, and similar) and currency are returned as names / ISO codes, not UUIDs.
Endpoint summary
| Method | Path |
|---|---|
| GET | /invoices |
| GET | /invoices/{invoiceId} |
| GET | /invoices/{invoiceId}/pdf |
List invoices
GET /api/v1/external/invoices?page=0&size=20&q=INV-10&accountId=11111111-1111-1111-1111-111111111111&fromDate=2026-08-01&toDate=2026-08-31
Authorization: Bearer YOUR_API_TOKEN| Query | Description |
|---|---|
page | 0-based page index (default 0) |
size | Page size (default 20, max 20) |
q | Optional search on invoiceNo |
accountId | Optional billing account UUID |
fromDate | Optional inclusive start of invoice date (YYYY-MM-DD) |
toDate | Optional inclusive end of invoice date (YYYY-MM-DD) |
Either date bound may be omitted. If both are sent, fromDate must be on or before toDate (400 otherwise). List rows are invoice headers only (no items). Envelope: Overview.
Response 200
{
"requestId": "req-1",
"success": true,
"status": 200,
"errors": [],
"data": {
"content": [
{
"__type__": "Invoice",
"Id": "55555555-5555-5555-5555-555555555555",
"InvoiceNo": "INV-1001",
"AccountId": "11111111-1111-1111-1111-111111111111",
"ApprovalStatus": "fe07e71d-cba4-4316-9c7c-4935c3adec34",
"ApprovalStatus__r": { "Name": "Approved" }
}
],
"totalElements": 1,
"size": 20,
"number": 0
}
}Response 400 when the date range is inverted.
{
"status": 400,
"error": "Validation Error",
"message": "fromDate must be on or before toDate",
"path": "uri=/api/v1/external/invoices"
}Get invoice
GET /api/v1/external/invoices/{invoiceId}
Authorization: Bearer YOUR_API_TOKENReturns the same PascalCase + __r header row as list (no nested items).
Response 200
{
"id": "55555555-5555-5555-5555-555555555555",
"invoiceNo": "INV-1001",
"invoiceDate": "2026-08-01",
"accountId": "11111111-1111-1111-1111-111111111111",
"invoiceStatus": "Posted",
"invoiceType": "Generated",
"amount": 40.0,
"taxAmount": 4.0,
"balance": 44.0,
"currency": "USD",
"dueDate": "2026-08-31",
"periodStart": "2026-08-01",
"periodEnd": "2026-08-31",
"paymentStatus": "Unpaid",
"approvalStatus": "Approved",
"contractId": "3a2f1c5d-9b7e-4c1a-8f36-2d4b6e8a0c11",
"invoiceFileName": "INV-1001.pdf",
"items": [
{
"id": "66666666-6666-6666-6666-666666666666",
"invoiceId": "55555555-5555-5555-5555-555555555555",
"serviceId": "e6cbd28a-f34c-482e-8da5-34e21dbd5eb7",
"description": "Usage",
"volume": 16000,
"ratePerUnit": 0.0025,
"amount": 40.0,
"tax": 4.0,
"balance": 44.0,
"chargeType": "Usage",
"priceMethodType": "QUANTITY",
"billStartDate": "2026-08-01",
"billEndDate": "2026-08-31",
"serviceName": "gpt-4o",
"serviceCode": "MODEL-GPT-4O",
"currency": "USD"
}
]
}Response 404 when the invoice does not exist.
{
"status": 404,
"error": "Not Found",
"message": "Invoice not found",
"path": "uri=/api/v1/external/invoices/55555555-5555-5555-5555-555555555555"
}Download invoice PDF
GET /api/v1/external/invoices/{invoiceId}/pdf
Authorization: Bearer YOUR_API_TOKENcurl -sS -L \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-o INV-1001.pdf \
"https://YOUR_TENANT_HOST/api/v1/external/invoices/55555555-5555-5555-5555-555555555555/pdf"Response 200 — binary body with PDF headers.
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="INV-1001.pdf"The PDF is the file already stored for that invoice (from invoice PDF generation).
Response 404 when no PDF has been generated yet.
{
"status": 404,
"error": "Not Found",
"message": "Invoice PDF has not been generated",
"path": "uri=/api/v1/external/invoices/55555555-5555-5555-5555-555555555555/pdf"
}