Events API
Record any business event in an append-only ledger. Each event is canonicalized, hashed, and signed with your tenant's Ed25519 key at ingestion, then appended to an immutable ledger you can verify at any time.
All endpoints require API key authentication via the Authorization: Bearer header. Events are immutable, they cannot be modified or deleted once ingested.
Overview
A compliance event captures who did what, when, and under what authority. When you POST an event, Invoance canonicalizes the payload, computes a SHA-256 payload_hash, signs it with your per-tenant key, and appends the record to the ledger. Nothing about the record can change afterwards, the audit tables reject updates and deletes at the database level.
POST /events (ingest) → GET /events/:id (retrieve) → POST /events/:id/verify (prove)The event_id is server-generated. Ingestion is idempotent, submit the same event with an Idempotency-Key and the ledger returns the original record instead of creating a duplicate. Pass an optional trace_id to group an event into a sealed trace bundle.
Endpoints
/eventsRecords any business event in the append-only ledger, who did what, when, and under what authority. Immutable, timestamped, and cryptographically signed at ingestion. Retained according to the specified policy.
event_type is required. payload is arbitrary JSON. Pass an optional trace_id to attach the event to a trace, and an Idempotency-Key header to make retries safe.
POST /events
Authorization: Bearer invoance_live_xxx
Idempotency-Key: policy-8472-approval
Content-Type: application/json
{
"event_type": "policy.approval",
"event_time": "2026-02-07T12:00:00Z",
"payload": {
"policy_id": "pol_8472",
"approved_by": "risk_committee",
"decision": "approved"
}
}{
"event_id": "evt_01HX…",
"ingested_at":"2026-02-07T12:04:11Z"
}/eventsReturns a paginated list of ledger events for the authenticated tenant. Supports filtering by date range and event type. Maximum 500 results per page, cached for 30 seconds.
Query params: page (default 1), limit (default 50, max 500), event_type, plus optional date-range filters.
GET /events?page=1&limit=50&event_type=policy.approval
Authorization: Bearer invoance_live_xxx{
"events": [
{
"event_id": "evt_01HX…",
"event_type": "policy.approval",
"payload_hash": "a3f2b1c9d4e8f7…",
"event_hash": "f8a1c3d2e5b9f4…",
"retention_policy":"regulatory",
"ingested_at": "2026-02-07T12:04:11Z",
"event_time": "2026-02-07T12:00:00Z"
}
],
"page": 1,
"limit": 50,
"total": 312,
"has_more": true
}/events/:event_idReturns an immutable event record including the full payload and all cryptographic hashes. Read-only. Requires the read scope. Records are append-only and cannot be modified or deleted.
GET /events/evt_01HX…
Authorization: Bearer invoance_live_xxx{
"event_id": "evt_01HX…",
"tenant_id": "org_01…",
"event_type": "policy.approval",
"payload": {
"policy_id": "pol_8472",
"approved_by": "risk_committee",
"decision": "approved"
},
"event_time": "2026-02-07T12:00:00Z",
"retention_policy":"regulatory",
"access_tier": "active",
"api_key_id": "key_01…",
"user_id": null,
"ingested_at": "2026-02-07T12:04:11Z",
"payload_hash": "a3f2b1c9d4e8f7…",
"request_hash": "c7d4e9a1b2f3c8…",
"event_hash": "f8a1c3d2e5b9f4…",
"idempotency_key": null
}/events/:event_id/verifyCompares a submitted hash or raw payload against the anchored event hashes. You can submit either a pre-computed payload_hash or the raw payload object, the server will canonicalize and hash it for you.
POST /events/evt_01HX…/verify
Authorization: Bearer invoance_live_xxx
Content-Type: application/json
{
"payload_hash": "a3f2b1c9d4e8f7…"
}{
"event_id": "evt_01HX…",
"match_result": true,
"matched_field": "payload_hash",
"anchored_hash": "a3f2b1c9d4e8f7…",
"submitted_hash": "a3f2b1c9d4e8f7…",
"anchored_at": "2026-02-07T12:04:11Z",
"method": "hash"
}SDK reference
Every official SDK exposes the events namespace under client.events — typed methods for ingest, get, list, and verify, in all eight languages.
Verification
Every event carries a SHA-256 payload_hash and an Ed25519 signature over its canonical bytes. To prove an event has not changed, hash your copy of the payload and compare, either by POSTing to /v1/events/:id/verify (the server canonicalizes and compares for you) or by validating the signature offline against your tenant's published public key.
Verification is trust-minimizing: the signature check needs no trust in the server's answer, and the public key is retrievable independently. See the full verification guide for the canonicalization rules and offline signature checks.