This documentation describes API 4.2.0 (September 14, 2026). Confirm availability in your target environment before upgrading. Review security enforcements and payload checks. The payload field set is unchanged; unclean requests can fail until the payload is cleaned.
Choose single or batch ingestion
| Endpoint | Use it for | Key location |
|---|---|---|
POST /ingest | One business event | Idempotency-Key header |
POST /ingest/batch | 1-100 events of one category | idempotency_key inside each item |
Both use Authorization: Bearer YOUR_API_KEY, JSON bodies, synchronous processing, and a 1 MiB total body limit. Public callers do not need internal service credentials. Use sandbox for integration testing; confirm availability before production rollout.
Send a complete event
POST /ingest
Authorization: Bearer YOUR_API_KEY
Idempotency-Key: create-company-001
Content-Type: application/json{
"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"
}
}Company gender is normalized to company; individual creates require gender. Unknown envelope/data fields are rejected. Do not send database audit fields or content_hash. Declared info objects can contain custom metadata. Use the local validator for structural checks, not proof that database references exist.
Categories and ordering
| Category | Guide | Dependency |
|---|---|---|
client | Client fields | Create before referring to the client |
disbursement | Loan/purchase fields | Loan client or optional purchase-client links |
payment | Payment fields | Parent disbursement; purchase client must be linked |
operation | Operation fields | Parent disbursement |
Steps remain create, update, and delete. Duplicate business-ID creates return 409; they are not upserts. Missing update targets return 404. Old categories such as loan, purchase, schedule, insurance, and worker-managed status/history categories are not accepted.
Idempotency: preserve the original request
- Use a nonblank, case-sensitive key of at most 255 UTF-8 bytes. UUID is recommended, not required. Keys are tenant-scoped and remain reserved while their event records exist; waiting for a cache timeout does not release a key.
- Identical stored request/key pairs replay the original HTTP status and body, not a generic duplicate response. Object-property ordering does not matter.
- Changing category, step, or payload under a stored key returns
409 IDEMPOTENCY_KEY_REUSED. This includes different submitted amounts that happen to round to the same cents. - After a timeout or lost response, retry the same original content and key. Do not create a new logical event just because a response was lost.
- Known terminal processing failures can be replayed. Correct a terminally recorded request using a new key. Pre-persistence validation failures and unexpected rolled-back failures are not stored terminal replays.
- Older events may replay bodies without the newer fields. A legacy pending event can return
409 IDEMPOTENCY_REQUEST_IN_PROGRESS; contact support if it persists.
Interpret responses
| Outcome | HTTP | status | action |
|---|---|---|---|
| Create | 201 | added | created |
| Changed update | 201 | added | updated |
| Unchanged update | 200 | unchanged | unchanged |
| Delete | 201 | added | deleted |
| Exact replay | Original | Original | Original, if present |
New successful responses include the business id, event_id, and idempotency_key. Creates/updates also include a server-computed content_hash; deletes omit it. Keep the business ID separate from the event identifier.
An unchanged update still records an ingest event/response, but does not rewrite domain rows, refresh domain timestamps, or generate child/history effects. Treat it as success. Partial updates are merged with the stored row before hashing.
Money is rounded by the API, not rejected for extra decimals: 10.255 becomes 10.26. Read money and rounding for sign/range rules, derived sums, and retry implications. Use batch ingestion for bulk work and synchronization to avoid unnecessary updates.
Errors and support
| HTTP | Meaning | Client action |
|---|---|---|
400 | Invalid structure/field/key, money overflow, or parent/client validation | Correct the request; use a new key if a terminal event was recorded |
401 | Missing/invalid bearer key | Check your credentials |
404 | Update target missing | Reconcile IDs before choosing a step |
409 | Changed-content key reuse, duplicate ID, or restricted deletion | Inspect error; these are distinct conflicts |
413 | Body larger than 1 MiB | Reduce the request; split bulk items, not one logical event |
500 | Unexpected processing/storage failure | Retry original content/key after transient failures; contact support if persistent |
503 SCHEMA_NOT_READY | Tenant setup incomplete | Pause affected requests and contact support; retries do not perform setup |
Error bodies vary: error may be symbolic or human-readable, with optional details and event_id. Do not assume logged domain codes appear as HTTP error strings. Send or retain X-Correlation-ID for support; it is a tracing ID, not an idempotency key.
GET /health is public and returns status, environment, and timestamp; it does not prove your tenant is ready. See the API reference for exact schemas.
