REST API reference
The "Tauraco Public API" (version 1.0.0-beta) is described by an OpenAPI 3.1 specification exported from the application itself, never written by hand: a contract test checks that the published file lists exactly the routes being served.
Files and interactive reference
The interactive reference is served from this site (no third-party script, no remote font, no request sent from the page).
The interactive reference could not be loaded.
Address and versions
- Address:
https://api.tauraco.io/public/v1(online since 2026-11-05; see Versions and changelog). - API version: optional request header
Tauraco-Version: 2026-11-01, always returned in the response; a version that is not served is refused (400 invalid_request). - Deprecation: a withdrawn operation is first announced with
Deprecation,SunsetandLink: <…>; rel="deprecation"(RFC 9745, RFC 8594).
Version 1 resources
The OpenAPI file above is authoritative: it publishes 73 operations, with their parameters, schemas, examples and the scope each one requires (x-required-scopes). The financial institution operations (/bank/*) are included (bank API, lot 2C).
| Resource | Operations | Scope |
|---|---|---|
/me, /companies/me | read | company:read |
/customers | list, get, create | customers:read, customers:write |
/suppliers | list, get | suppliers:read |
/invoices | list, get, create, PDF (/invoices/{invoice_id}/pdf) | invoices:read, invoices:write |
/bills | list, get | bills:read |
/payments | list, get, record | payments:read, payments:write |
/purchase-orders | list, get | purchases:read |
/products | list | products:read |
/treasury/movements | list | treasury:read |
/accounting/accounts, /accounting/entries, /accounting/trial-balance | list | accounting:read |
/inventory/items, /inventory/balances, /inventory/movements | list | inventory:read |
/tenders | list, get (relayed public notices, unverified external data) | tenders:read |
/financing/requests | list, get (no decision) | financing:read |
/documents | list by parent (parent_type, parent_id), get, content; in v1, documents of financing requests | documents:read and the parent's scope (financing:read) |
/exports | list, create, get, cancel, download with the bearer token, single-use signed link | exports:read, exports:write |
/webhooks | event types, endpoints (create, get, update, delete, secret rotation, enable, disable, test), deliveries, replay | webhooks:manage |
/integrations/datasets, /integrations/formats, /integrations/connections | catalogue: exportable datasets, formats, delivery connections | exports:read |
/bank/* | see the bank integration guide | bank:* |
Outside version 1: /projects, /contracts, /applications, /guarantees, inventory and accounting writes. Collateral depots are served over REST, read-only: GET /collateral/depots and GET /collateral/depots/{depot_id} (scope collateral:read, ERP_OWNER delegator only); they can also be exported (dataset collateral_depots, see Collateral).
Conventions
- Format. UTF-8 JSON; a write that carries a body sends it with
Content-Type: application/json(otherwise415 unsupported_media_type); body limited to 1 MB (413 payload_too_large); an unknown or invalid field gives422 validation_failed. A write also requires a write role for the application in the company (otherwise403 forbidden). - Amounts. Decimal strings in major units, at the currency's exponent: XOF, XAF, GNF and KMF without decimals (
"150000"), EUR and USD with two ("1234.56"). Read them with a decimal type, never a float. - Dates.
dateasYYYY-MM-DD; timestamps ISO 8601 UTC withZ. - Identifiers. UUID strings; business numbers (an invoice's
number) are fields, not identifiers. - Excluded fields.
tenant_id, internal notes, bank details, factoring fields, chaining hashes, person names and personal data are never served by default.
Pagination
Lists return {"data": [...], "next_cursor": "…", "has_more": true}. Parameters: limit (1 to 200, 50 by default; at most 100 for /exports and webhook deliveries) and cursor, opaque and signed: it is bound to the dataset and to the filters of the first page (a cursor replayed with other filters gives 400 invalid_cursor). Ordering is stable (creation key, then identifier).
Filters
Depending on the resource: status, counterparty (customer_id, supplier_id, invoice_id), dates (issue_date_from / issue_date_to, due_date_from / due_date_to, paid_from / paid_to, movement_date_from / movement_date_to), accounting period (period_start, period_end, mandatory for the trial balance), created_after / created_before, updated_after / updated_before (only for datasets with a modification date), q (text search where it is declared). The OpenAPI file lists the filters of each operation. An unknown parameter gives 400 invalid_request; an invalid value 422 validation_failed with errors: [{field, message}].
Idempotency
Idempotency-Key (at most 255 printable ASCII characters, otherwise 400 invalid_request) is mandatory on every POST (otherwise 400 idempotency_key_required). The key belongs to your application and the company; it is kept for 24 hours. Same key and same body: original response with Idempotent-Replayed: true, with no new effect. Same key, other body: 422 idempotency_key_reused. Same key while processing: 409 idempotency_in_progress. A replayed response never contains a secret.
Headers
| Header | Meaning |
|---|---|
Authorization: Bearer <token> | access token (audience tauraco-public-api) |
X-Request-Id | request correlation identifier, to quote to support |
Idempotency-Key | mandatory on every POST |
Idempotent-Replayed: true | replayed response |
RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset | the application's per-minute bucket |
X-Quota-Limit, X-Quota-Remaining | UTC daily quota (X-Quota-Remaining omitted when the bucket refuses) |
Retry-After | seconds to wait (429, 503) |
Deprecation, Sunset, Link | deprecation policy |
Tauraco-Version | API version |
WWW-Authenticate | on 401 and 403: error, scope, resource_metadata |
Content-Disposition, X-Content-SHA256, Cache-Control: private, no-store | file or document download (plus Referrer-Policy: no-referrer on a signed link) |
Location | resource created by a POST (customer, invoice, payment, export, webhook endpoint) |
Rate limits and quotas
Each application has a per-minute bucket (120 requests by default) and a daily quota (50,000 by default, reset at midnight UTC), adjustable by Tauraco. Exceeding them gives 429 rate_limited or 429 quota_exceeded with Retry-After. Refusals come in a stable order: authentication (401), then rate (429), then scope (403).
Security
- HTTPS only; no company data is served without a token.
- Access control happens at every layer: token scope, Tauraco application rights rebuilt for the grant's company, then the services' company filters. A resource of another company answers
404 not_found, indistinguishable from a missing resource. - CORS: only the developer portal origins are allowed, without cookies.