Skip to content
Getting Started

API: Handle retries, conflicts and synchronization safely

API: Handle retries, conflicts and synchronization safely – HTTP requests and examples for the local Billance API.

3 min readDesktopLast updated on October 1, 2026

Reliable integrations with the Local Automation API

This chapter covers API clients and HTTP requests. Store returned Billance IDs in your source system. Use the installed version’s OpenAPI document at <BASE-URL>/openapi.json and deliberately track the active company profile. Successful writes confirm local persistence; cloud sync can still fail later.

Retry with Idempotency-Key

Mutating POST, PUT and DELETE accept an optional Idempotency-Key: 1–128 printable ASCII characters. Read-only /import/validate and /import/einvoice do not use it. Give each new business operation a new key. A retry must retain the same key, method, path, query parameters and JSON content.

Results are retained for seven days. Completed replays return the stored result with Idempotency-Replayed: true. Different content with the same key returns HTTP 409 idempotency_key_reused. An unresolved first attempt returns HTTP 409 idempotency_pending: inspect existing records before using a new key. After a timeout without idempotency, search for the document before creating it again. Rotating the access token creates a new key context.

Protect updates with ETag

Single-resource reads of invoices, recipients, products and receipts return an ETag. Their general PUT/DELETE endpoints accept If-Match. For example:

curl --fail-with-body -sS -D invoice-headers.txt \
  -H "Authorization: Bearer $BILLANCE_API_TOKEN" \
  "$BASE_URL/invoices/$INVOICE_ID" --output current-invoice.json

Supply the complete ETag including quotes as If-Match. Read and selectively edit formData from current-invoice.json, then send complete formData to PUT /invoices/{id}. Without If-Match, concurrent changes are not protected. HTTP 412 revision_conflict means read again, reconcile changes and deliberately retry. Finalized invoices remain immutable. Payment, status and other subresources have their own rules; do not assume they support If-Match.

Lists and company profiles

Invoice lists always return items, page, pageSize, totalItems and totalPages. For recipients, products and receipts, page or pageSize opts into pagination; without either parameter the response only contains items. Default page size is 50, maximum 200. Read all pages; concurrent changes mean a list is not a consistent snapshot.

Read operations may support profileId. Writes target the active company profile. Server-owned IDs, profile assignments and timestamps cannot be freely overwritten. Invoice and receipt writes targeting another profile may return 409 profile_not_active; master-data repository rules protect profile assignment. Switching profiles in the app can affect your workflow.

Rate limits, errors and cloud sync

The HTTP limit is 120 requests per minute per local client, including public requests. HTTP 429 supplies Retry-After: 60. Limit concurrency and use backoff. 400 bad_request indicates invalid input; 422 validation_failed indicates failed business validation or generation. RFC 7807 errors use application/problem+json; inspect status and code. Validator HTTP 200 does not prove an invoice is valid.

GET /sync/status reports provider state, not individual record delivery. Plan local processing and later synchronization separately. The API is only reachable through 127.0.0.1, with no direct cloud/LAN access or CORS permission.

API tester

The app lets you edit path/query parameters, documented headers and JSON. Mutations require confirmation. If you omit a manual idempotency key, each mutating test click gets a new key and is a new operation. To test replay, enter the same key yourself. The editor supports 1 MiB request text and previews at most 96 KiB response text; use cURL for larger uploads and downloads. The API accepts JSON bodies up to 70 MiB; receipt files are limited to 50 MiB.