The External API connects your own systems, automations, and integrations with Billutant. One token is enough to manage customers, items, templates, and invoices for the connected tenant.
POST /invoices
Authorization: Bearer bt_live_...
Content-Type: application/json
{
"customerId": "customer_123",
"itemIds": ["item_setup", "item_monthly"],
"draft": false,
"send": true,
"emailTemplateId": "template_invoice"
}The integration needs no OAuth flow and no local SDK installation. A secret, a base URL, and JSON are enough for the first test.
Create an API token in Billutant and store it as a secret in the external system.
Start against the test environment until payload, status, and sending work cleanly.
Send JSON with customerId and itemIds to /invoices. Production later only needs the other base URL.
Tokens are created in Billutant settings. Every request uses the header Authorization: Bearer TOKEN and is automatically rate-limited.
Production and test use the same path under /api/v1.
https://app.billutant.com/api/v1https://test.billutant.com/api/v1The token is only visible once. Store it as a secret in your external tool.
Authorization: Bearer bt_live_...
Write requests use application/json. GET endpoints do not need a body.
Content-Type: application/json
By default, 60 requests per minute and token are planned. If exceeded, the API responds with 429.
The invoice API is intentionally lean: customers and items are referenced by ID, and Billutant sets the invoice date automatically.
/invoicesCreates an invoice from an existing customer ID and item IDs. Optionally sends it right away.
/invoicesReturns the invoices for the connected Billutant tenant.
/invoices/{id}Reads a single invoice when it belongs to the tenant connected to the token.
/invoices/{id}Updates only invoices in draft status. Finalized invoices stay locked.
/invoices/{id}/sendSends an existing invoice that is not saved as a draft with emailTemplateId.
/invoices/{id}Invoices cannot be deleted through the API.
customerId and itemIds are required. send automatically sends the invoice when a valid emailTemplateId is provided and the customer has a valid email address.
createDate is not accepted and is set by Billutant.
draft: true creates a draft.
draft and send cannot both be true.
PATCH /invoices/{id} can change drafts, but cannot send them.
POST /invoices/{id}/send only needs emailTemplateId in the body.
DELETE /invoices/{id} is blocked.
curl -X POST https://test.billutant.com/api/v1/invoices \
-H "Authorization: Bearer bt_live_..." \
-H "Content-Type: application/json" \
-d '{"customerId":"customer_123","itemIds":["item_setup"],"send":false}'{
"success": true,
"data": {
"id": "invoice_123",
"invoiceNumber": "2026-0012",
"status": "pending",
"customerId": "customer_123",
"files": ["2026-0012.pdf"],
"sent": true,
"draft": false
}
}For robust integrations, the client should evaluate the HTTP status first and only then process the JSON response.
Successful
The request was processed. For POST /invoices, data contains the created invoice.
Check payload
Required fields are missing or rules such as draft and send were violated.
Check token
The bearer token is missing, invalid, or stored incorrectly in the external tool.
Enable feature
The External Invoice API has not yet been enabled for the connected tenant.
Check resource
The requested ID does not exist or does not belong to the tenant connected to the token.
Change method
The route exists, but the HTTP method is not allowed there, for example DELETE /invoices/{id}.
Retry later
The rate limit was reached. Clients should retry with a delay.
async function createBillutantInvoice(token) {
const response = await fetch('https://test.billutant.com/api/v1/invoices', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
customerId: 'customer_123',
itemIds: ['item_setup'],
send: false,
}),
});
const payload = await response.json();
if (!response.ok) {
throw new Error(payload.error || `Billutant API request failed with ${response.status}`);
}
return payload.data;
}{
"success": false,
"error": "emailTemplateId is required when send is true."
}Customers, items, and email templates can be maintained directly via the API so external systems do not need manual preparation in Billutant.
/customersLists existing customers for selection in external tools.
/customersCreates a customer. Company, name, or email is required for identification.
/customers/{id}Reads a single customer when it belongs to the tenant connected to the token.
/customers/{id}Changes master data for an existing customer.
/customers/{id}Deletes customers when external workflows explicitly need it.
/itemsReads products and services used as invoice line items.
/itemsStores a service with name, description, price, tax, and unit.
/items/{id}Reads a single product or service from the connected tenant.
/items/{id}Changes name, description, price, tax, or unit for an item.
/items/{id}Deletes an item when external workflows no longer need it.
/email-templatesReads email templates used for automatic delivery.
/email-templatesCreates a template with type, label, subject, and body for invoice delivery.
/email-templates/{id}Reads a single email template from the connected tenant.
/email-templates/{id}Updates type, label, subject, body, or reminder parameters for a template.
/email-templates/{id}Deletes an email template when it is no longer used.
Use the test environment first. Once the payload and delivery work as expected, switch only the base URL to production in your external tool.