Skip to content

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_… or Bearer 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:

json
{ "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:

json
{
  "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:

ResourceMain filters
/invoicesstate, type, partner_id
/external-invoicesstate, external_id
/verifactu-recordsinvoice_id, state
/partnerstype, is_active, search, external_id
/productsis_active, search, external_id
/seriestype, is_active
/taxestype, tax_use, is_active
/economic-activitiesis_active

search performs a partial match; external_id is exact and unique per tenant. The API reference defines every accepted value.

Idempotency ​

MechanismPurposeScope
Idempotency-KeyPrevent duplicate effects when retrying a write24 hours, per request
external_idPermanent link between your record and BilteoPersistent, per resource

Safe retries with Idempotency-Key ​

Send a new opaque key for each logical operation:

bash
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" }'
SituationResult
Same processed key and bodyReplays the response with Idempotent-Replayed: true.
Same key still being processed409 idempotency.request_in_progress.
Same key with a different body422 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}:

OperationRoute
Create or updatePUT /partners/by-external-id/{ext}
ReadGET /partners/by-external-id/{ext}
Partial updatePATCH /partners/by-external-id/{ext}
DeleteDELETE /partners/by-external-id/{ext}
SearchGET /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.

bash
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 ​

FieldCascade
Economic activityOnly active one → tenant default → first active one.
SeriesActivity default for the invoice type → first series of that type.
CurrencyTenant default → EUR.

Send these fields explicitly only when you need a specific value.

HTTP status codes ​

CodeWhen
200Successful operation.
201Resource created.
204Successful operation without a body.
400Invalid request or fields.
401Missing, invalid, or expired credential.
403Missing scope or immutable resource.
404Resource does not exist in the tenant.
409State or identifier conflict.
422Operation cannot be completed.

See the common envelope in Errors.

Bilteo · Documentation