Integration Documentation
How external operational systems publish financial events to LedgerOS. External systems never post journal entries directly — every event flows through the Financial Event Bus.
All requests authenticate with an API client credential issued per environment. Credentials are scoped to a single organization and a fixed set of event types. Signed requests carry an HMAC-SHA256 signature over the raw request body using a shared secret.
Authorization: Bearer <client_token>
X-LedgerOS-Timestamp: 1739462400
X-LedgerOS-Signature: sha256=<hex>Signatures are verified with a constant-time compare; the timestamp must be within 300 seconds.
Post events to the Financial Event Bus endpoint. Each event is validated against its schema, routed to a rule, and materialized into a financial object. External systems never post journal entries directly.
POST /api/public/integrations/events
Content-Type: application/json
{
"event_type": "work_order.completed",
"external_id": "WO-10001",
"occurred_at": "2026-07-16T14:03:00Z",
"payload": { "...": "..." }
}Supported event types include work_order.completed, invoice.created, payment.received, inventory.consumed, and refund.created.
Every event must include an Idempotency-Key header. The bus deduplicates for 24 hours: a duplicate key returns the original response with X-LedgerOS-Idempotent-Replayed: true.
Idempotency-Key: 6f2e3d90-b0a5-42d7-9e5f-4c9d1e75c001Errors use structured JSON with a stable code and a human message.
HTTP/1.1 422 Unprocessable Entity
{
"code": "unknown_customer",
"message": "External customer SC-CUST-99 is not mapped.",
"correlation_id": "corr_9f21",
"retryable": false
}Non-retryable errors are surfaced as exceptions in the accountant workspace for manual resolution.
- TLS 1.2+ required. Non-TLS requests are refused.
- Client secrets are never returned after creation; rotate via the admin surface.
- Row-level security enforces tenant isolation on every read and write.
- All requests are recorded in the audit log with correlation IDs.
Transient failures (5xx, 429, network) are retried with exponential backoff and jitter: 30s, 2m, 8m, 30m, 2h — up to 5 attempts. Non-retryable errors (4xx other than 408 / 429) are moved to the exception queue immediately.
Publishers should honor Retry-After when present and MUST NOT retry with a different Idempotency-Key for the same logical event.
