Developers
Show batch ingestion and synchronization guides and endpoints, core concepts, and the content hash calculator.
Explore the docs

Work with data

Batch ingestion

Send same-category events together and handle every item result safely.

On this page

At a glance#

  • Send 1-100 events of one category within a 1 MiB request body.
  • Give every item its own idempotency key and preserve it on retries.
  • Inspect every item result. An outer HTTP 200 does not mean every item succeeded.

Use POST /ingest/batch for bulk writes. Single events can continue to use POST /ingest. Both use your bearer API key; batching requires per-item idempotency keys, not a request-level Idempotency-Key header.

Complete request

http
POST /ingest/batch
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
json
{
  "items": [
    {
      "idempotency_key": "create-company-001",
      "category": "client",
      "data": {
        "step": "create", "client_id": "COMPANY-001", "name": "Acme Trading",
        "email": "finance@acme.example", "phone": "+15550001031",
        "address": "100 Market Street", "country": "US", "is_company": true,
        "registration_number": "REG-001", "contact_person": "Jane Smith"
      }
    },
    {
      "idempotency_key": "create-company-002",
      "category": "client",
      "data": {
        "step": "create", "client_id": "COMPANY-002", "name": "Example Supply",
        "email": "finance@supply.example", "phone": "+15550001032",
        "address": "200 Market Street", "country": "US", "is_company": true,
        "registration_number": "REG-002", "contact_person": "Alex Smith"
      }
    }
  ]
}

Rules

  • Send 1-100 items, all with the same category, within 1 MiB total UTF-8 body size. Each item may use its own step.
  • Each idempotency_key must be a nonblank string of at most 255 UTF-8 bytes. Preserve keys and original values for retries.
  • Every item uses the same category/step payload rules and API-side money rounding as single ingestion.
  • Send client batches first, then disbursements, then payments/operations. Parent existence and purchase-client membership are still enforced.
  • Extra envelope/item fields are invalid. Do not include caller-generated content_hash in data.

HTTP 200 does not mean all items succeeded

Items execute sequentially in one transaction with per-item rollback boundaries. A successful item can coexist with a failed item: this is not an all-or-nothing business batch.

results preserves input order. Each result has a status and body matching a single-ingest response. For example, a separate batch containing a client deletion followed by an invalid client item could return:

json
{
  "results": [
    {
      "status": 201,
      "body": {"status": "added", "action": "deleted", "id": "C-1", "idempotency_key": "delete-c1-001", "event_id": 42}
    },
    {
      "status": 400,
      "body": {"error": "Payload validation failed", "details": ["Unknown field: content_hash"]}
    }
  ]
}

Inspect every item, including 200 unchanged, 201 success, and 400/404/409/500 failures. The outer 200 only indicates that the batch returned results.

Whole-request errors

Malformed envelopes/items, empty arrays, more than 100 items, or mixed categories fail the whole request with 400 before item processing. Authentication (401), oversized body (413), readiness (503 SCHEMA_NOT_READY), or transaction-level failure (500) can also fail the whole request. A mixed-category body does not partially process the valid category.

Retry safely

  1. Retain item positions, original content, and keys along with the results.
  2. If the response is lost, resend uncertain items with their original content and keys; already stored results replay exactly.
  3. Correct terminally recorded failures with new keys. Never change an amount under an old key merely because it rounds to the same cents: that returns an item 409 IDEMPOTENCY_KEY_REUSED.
  4. Split an oversized batch into smaller same-category batches while preserving each item's identity.
  5. Pause and contact support for readiness errors; do not reset data.

The validator accepts full batch envelopes and reports indexed item errors. It does not call the API or verify database state.

Validate locally. Verify in sandbox.
The JSON validator checks structure and rounding. Credentials, existing records, and server-side state still require your test environment.

Search documentation

Start typing to find your next step.

    navigate Enter openLocal, private search