Developer API
Facturen pushen zonder factuurmodule te bouwen.
Gebruik één HTTP API voor facturen, klanten, PDF-statussen en usage events. Je eigen SaaS blijft leidend; Factuurhub verwerkt nummering, branding, PDF’s en team-isolatie.
{
"data": {
"id": "01jz...invoice",
"invoice_number": "HOST-2026-000001",
"status": "finalized",
"currency": "EUR",
"subtotal_cents": 2500,
"tax_total_cents": 525,
"total_cents": 3025,
"pdf_status": "pending"
}
}
Bearer tokens
Plain tokens worden één keer getoond en daarna alleen gehasht opgeslagen.
Idempotency
Retries met dezelfde key maken nooit een tweede factuur.
Private PDF’s
Download geeft 202 zolang de PDF nog niet ready is.
Quickstart
Een factuur in één request.
Maak per SaaS-dienst een API token aan, stuur een Bearer token mee en gebruik een Idempotency-Key voor veilige retries vanuit queues, webhooks of cronjobs.
- 1 Maak een service app. Bijvoorbeeld met key hosting.
- 2 Maak een API token. Met invoices:create en invoices:read.
- 3 Stuur de request. Geef de prijs excl. btw in centen en het btw-tarief op.
- 4 Retry gerust. Met dezelfde Idempotency-Key.
curl -X POST https://factuurhub.test/api/v1/invoices \
-H "Authorization: Bearer factuurhub_test_xxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: inv-host-2026-0001" \
-H "Content-Type: application/json" \
-d '{
"service_app_key": "hosting",
"external_invoice_id": "HOST-2026-0001",
"status": "finalized",
"currency": "EUR",
"invoice_date": "2026-06-05",
"customer": {
"type": "company",
"company_name": "Voorbeeld BV",
"email": "klant@example.nl",
"country": "NL"
},
"lines": [{
"description": "Hostingpakket juni 2026",
"quantity": "1.0000",
"unit_price_cents": 2500,
"vat_rate": "21.00"
}]
}'
Endpoints
Klein oppervlak, duidelijke verantwoordelijkheden.
De API doet alleen wat je SaaS nodig heeft: facturen aanmaken, ophalen, betaald markeren, PDF downloaden en usage events loggen.
Maak een factuur aan
Idempotent via header of external_invoice_id. Maakt ook customer, regels, PDF-status en usage event aan.
Haal factuurdetails op
Geeft customer, regels, totalen en PDF-status terug binnen dezelfde service app.
Markeer betaald
Zet paid of partially_paid en logt een usage event.
Download PDF
Vereist invoices:download en geeft 202 als de PDF nog niet ready is.
Log usage
Voor pay-as-you-go events zoals invoice.api_call of invoice.downloaded.
Auth & abilities
Tokens zijn per SaaS-dienst. Plain tokens worden één keer getoond en daarna alleen gehasht opgeslagen.
- invoices:create
- invoices:read
- invoices:mark_paid
- invoices:download
- usage:create
Idempotency
Gebruik een Idempotency-Key voor queue retries. Zonder header gebruikt Factuurhub service_app_id + external_invoice_id als natuurlijke deduplicatie.
Duplicate requests verhogen het factuurnummer niet.
Errors
Fouten zijn bewust simpel: statuscode, korte message en waar nodig validatie-errors. Geen secrets of tokens in logs.
- 401
- Token ontbreekt of is ongeldig.
- 403
- Token mist de vereiste ability.
- 404
- Resource bestaat niet binnen deze service app.
- 409
- Idempotency-conflict: zelfde key, andere payload.
- 422
- Validatiefout, met veld-errors in de response.
- 429
- Rate limit bereikt: 120 requests per minuut per token.
Voorbeelden
Gebruik de API vanuit elke stack.
Geen SDK nodig. Stuur een Bearer token mee, gebruik een vaste Idempotency-Key per factuur en laat Factuurhub de btw en totalen per regel berekenen.
curl -X POST https://factuurhub.test/api/v1/invoices \
-H "Authorization: Bearer factuurhub_test_xxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: inv-host-2026-0001" \
-H "Content-Type: application/json" \
-d '{
"service_app_key": "hosting",
"external_invoice_id": "HOST-2026-0001",
"currency": "EUR",
"invoice_date": "2026-06-05",
"customer": {
"type": "company",
"email": "klant@example.nl",
"country": "NL"
},
"lines": [{
"description": "Hostingpakket juni 2026",
"quantity": "1.0000",
"unit_price_cents": 2500,
"vat_rate": "21.00"
}]
}'
$payload = [
'service_app_key' => 'hosting',
'external_invoice_id' => 'HOST-2026-0001',
'currency' => 'EUR',
'invoice_date' => '2026-06-05',
'customer' => [
'type' => 'company',
'email' => 'klant@example.nl',
'country' => 'NL',
],
'lines' => [[
'description' => 'Hostingpakket juni 2026',
'quantity' => '1.0000',
'unit_price_cents' => 2500,
'vat_rate' => '21.00',
]],
];
$ch = curl_init('https://factuurhub.test/api/v1/invoices');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer factuurhub_test_xxxxxxxxxxxxxxxxx',
'Idempotency-Key: inv-host-2026-0001',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
Http::withToken(config('services.factuurhub.token'))
->withHeaders([
'Idempotency-Key' => 'invoice-'.$invoice->uuid,
])
->post('https://factuurhub.test/api/v1/invoices', [
'service_app_key' => 'hosting',
'external_invoice_id' => $invoice->number,
'currency' => 'EUR',
'invoice_date' => now()->toDateString(),
'customer' => [
'type' => 'company',
'email' => $customer->email,
'country' => 'NL',
],
'lines' => $lines,
])
->throw();
import requests
payload = {
"service_app_key": "hosting",
"external_invoice_id": "HOST-2026-0001",
"currency": "EUR",
"invoice_date": "2026-06-05",
"customer": {
"type": "company",
"email": "klant@example.nl",
"country": "NL",
},
"lines": [{
"description": "Hostingpakket juni 2026",
"quantity": "1.0000",
"unit_price_cents": 2500,
"vat_rate": "21.00",
}],
}
response = requests.post(
"https://factuurhub.test/api/v1/invoices",
headers={
"Authorization": "Bearer factuurhub_test_xxxxxxxxxxxxxxxxx",
"Idempotency-Key": "inv-host-2026-0001",
},
json=payload,
timeout=10,
)
response.raise_for_status()
Koppel je eerste SaaS-dienst.
Begin met één service app, één token en één factuurflow. De rest kan later op dezelfde API mee.