API conventions
Common rules for formats, pagination, filters, idempotency, and default values.
Base URL and format
Base URL: https://api.test.bilteo.com/api/v1- HTTPS and JSON (
Content-Type: application/json). Authorization: Bearer bk_live_…orBearer bo_at_…; see Authentication.- Bilteo IDs are UUIDs. To address resources by your own ID, see
external_id.
Decimal amounts as strings
Amounts and quantities travel as strings to preserve precision:
{ "quantity": "1", "unit_price": "100.00", "discount": "10" }Dates
- Operation dates:
YYYY-MM-DD. - Timestamps: RFC 3339 in UTC, for example
2026-01-15T10:00:00Z.
Cursor pagination
List endpoints return:
{
"data": [],
"next_cursor": "AAECAwQFBgcICQoLDA0ODw",
"has_more": true
}limit accepts 1 to 100 results and defaults to 50. Send each next_cursor as the next request's ?cursor= until has_more is false.
The cursor is opaque
Do not parse or construct it. An invalid cursor returns 400 (pagination.invalid_cursor).
Filters
Filters combine with each other and with pagination:
| Resource | Main filters |
|---|---|
/invoices | state, type, partner_id |
/external-invoices | state, external_id |
/verifactu-records | invoice_id, state |
/partners | type, is_active, search, external_id |
/products | is_active, search, external_id |
/series | type, is_active |
/taxes | type, tax_use, is_active |
/economic-activities | is_active |
search performs a partial match; external_id is exact and unique per tenant. The API reference defines every accepted value.
Idempotency
| Mechanism | Purpose | Scope |
|---|---|---|
Idempotency-Key | Prevent duplicate effects when retrying a write | 24 hours, per request |
external_id | Permanent link between your record and Bilteo | Persistent, per resource |
Safe retries with Idempotency-Key
Send a new opaque key for each logical operation:
curl -X POST "https://api.test.bilteo.com/api/v1/external-invoices" \
-H "Authorization: Bearer bk_live_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7e9f…-uuid-per-operation" \
-d '{ "numero": "1", "fecha_expedicion": "2026-06-13", "tipo_factura": "F1" }'| Situation | Result |
|---|---|
| Same processed key and body | Replays the response with Idempotent-Replayed: true. |
| Same key still being processed | 409 idempotency.request_in_progress. |
| Same key with a different body | 422 idempotency.key_reused_with_different_body. |
The header is optional. Reuse a key only to retry the exact same operation.
Synchronisation by external_id
partners and products accept your identifier, unique per tenant. Address a resource through …/by-external-id/{external_id}:
| Operation | Route |
|---|---|
| Create or update | PUT /partners/by-external-id/{ext} |
| Read | GET /partners/by-external-id/{ext} |
| Partial update | PATCH /partners/by-external-id/{ext} |
| Delete | DELETE /partners/by-external-id/{ext} |
| Search | GET /partners?external_id={ext} |
PUT converges to the same state: it returns 201 on creation and 200 on update. The same pattern applies to /products.
curl -X PUT "https://api.test.bilteo.com/api/v1/partners/by-external-id/CUS-00042" \
-H "Authorization: Bearer bk_live_xxx" -H "Content-Type: application/json" \
-d '{ "type": "com", "name": "Northwind Ltd", "id_num": "B85447761", "country": "ES" }'external_id is persistent; Idempotency-Key only protects a single retry. To clear external_id in a PATCH, send an empty string.
Default values: series, activity, and currency
| Field | Cascade |
|---|---|
| Economic activity | Only active one → tenant default → first active one. |
| Series | Activity default for the invoice type → first series of that type. |
| Currency | Tenant default → EUR. |
Send these fields explicitly only when you need a specific value.
HTTP status codes
| Code | When |
|---|---|
200 | Successful operation. |
201 | Resource created. |
204 | Successful operation without a body. |
400 | Invalid request or fields. |
401 | Missing, invalid, or expired credential. |
403 | Missing scope or immutable resource. |
404 | Resource does not exist in the tenant. |
409 | State or identifier conflict. |
422 | Operation cannot be completed. |
See the common envelope in Errors.