Base URL
All API endpoints are relative to:
Versioning
The current stable version is v1. All v1 endpoints are prefixed with /api/v1/.
There are no version negotiation headers — the version is part of the URL path.
- Content type:
application/json
- Encoding: UTF-8
- All timestamps must be in ISO 8601 format (
YYYY-MM-DDTHH:MM:SSZ)
- Dates (without time) must be
YYYY-MM-DD
All responses return JSON.
Exception: GET /api/v1/batch_invoices/{id}/pdf returns an application/pdf binary payload (the associated issued invoice PDF).
Most endpoints that return a single resource wrap the payload in a data key:
{
"data": {
"id": 123,
"status": "received",
...
}
}
Exception: POST /api/v1/auth/sessions returns a flat JSON object at the root level — no data envelope:
{
"session_token": "...",
"expires_at": "2026-03-27T10:30:00Z"
}
List responses include a meta object with pagination info:
{
"data": [...],
"meta": {
"current_page": 1,
"total_pages": 4,
"total_count": 87,
"per_page": 25
}
}
The POST /api/v1/invoice_batches endpoint may additionally include an errors key alongside data when some invoices in the batch fail validation (partial success):
{
"data": { ... },
"errors": {
"inv-bad-001": ["Issuer nif no puede estar en blanco"]
}
}
The errors object is keyed by external_invoice_id.
List endpoints accept two query parameters:
| Parameter | Type | Default | Max | Description |
|---|
page | integer | 1 | — | Page number (1-indexed) |
per_page | integer | 25 | 100 | Results per page |
Idempotency
POST /api/v1/invoice_batches requires an Idempotency-Key header containing a valid UUID. Resubmitting the same key within the idempotency window returns the cached response without re-processing the batch.
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Rate limiting
Most protected endpoints enforce rate limits per organization. When exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating the number of seconds to wait.
HTTP/1.1 429 Too Many Requests
Retry-After: 30
POST /api/v1/invoice_batches is excluded from rate limiting — idempotency already prevents duplicate processing.
Error responses
All errors follow a consistent envelope:
{
"error": {
"code": "string",
"message": "Human-readable description"
}
}
Error codes
| HTTP status | Code | Description |
|---|
400 | bad_request | Missing or blank required parameter |
401 | unauthorized | Missing, invalid, or expired authentication |
404 | not_found | Resource not found within the current organization |
422 | missing_idempotency_key | Idempotency-Key header is absent |
422 | invalid_idempotency_key | Idempotency-Key is not a valid UUID |
422 | validation_failed | Request body failed validation (see message for details) |
422 | unprocessable_content | Record could not be saved due to validation errors |
429 | too_many_requests | Too many requests — check Retry-After header |