Authentication

Bearer tokens, scopes, token lifecycle, and idempotent requests.

Backfill REST API routes live on the API host under /v1.

  • Base URL: https://api.backfill.io/v1
  • Authentication scheme: Authorization: Bearer <api_token>

API tokens are tenant-bound credentials created in the dashboard under Settings → API keys. They use the bf_live_ prefix and are stored by SHA-256 hash; the plaintext token is not recoverable after creation.

curl https://api.backfill.io/v1/accounts \
  -H "Authorization: Bearer bf_live_..."

Token lifecycle

API tokens may have:

  • expires_at — nullable. A token with no expiration remains valid until revoked.
  • last_used_at — updated during authentication, throttled to at most once per hour.
  • revoked_at — set when a token is revoked. Revoked tokens are rejected and retained as an audit anchor.

Expired and revoked tokens return 401 unauthorized.

Scopes

Scopes restrict what the token can do. Route-level scope checks return a standard 403 forbidden envelope when the token is authenticated but lacks the required scope.

ScopeUse
finance:readRead finance resources such as customers, vendors, invoices, accounts, and transactions.
finance:writeCreate, update, void, delete, or otherwise mutate finance resources.
reports:readGenerate and export reports and saved datasets.
banking:readRead bank accounts and bank transactions.
banking:writeMutate banking workflows such as reconciliation.
connectors:readRead connector, extension, and outbound webhook configuration.
connectors:writeMutate connector, extension, and outbound webhook configuration.
extensions:deployDeploy and promote extensions. Also grants connector read/write through the permission map.

Wildcards are supported by the authorization layer: finance:* satisfies both finance:read and finance:write, and * satisfies any scope.

Idempotent POST requests

All authenticated /v1 POST requests accept Idempotency-Key.

curl https://api.backfill.io/v1/customers \
  -H "Authorization: Bearer bf_live_..." \
  -H "Idempotency-Key: cust-import-2026-07-02-0001" \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme Inc."}'

Behavior:

  • Keys are scoped to the API client.
  • Keys may be up to 255 bytes after trimming.
  • Completed responses are retained for 24 hours.
  • A retry with the same method, path, query string, content type, and body replays the stored response with idempotency-replayed: true.
  • The first completed response includes idempotency-replayed: false.
  • Reusing the key for a different request returns 409 idempotency_key_conflict.
  • Retrying while the first request is still processing returns 409 idempotency_key_in_progress.