Documentation
Everything below works against the sandbox with a test key. Swap the key for a live one when you are ready; nothing else changes.
Quickstart
Install the client and send your first event. The call is idempotent on the key you pass, so a retry after a timeout is safe.
npm install @acme/node import { Acme } from '@acme/node'
const acme = new Acme(process.env.ACME_KEY)
const event = await acme.events.send({
provider: 'northwind',
type: 'invoice.paid',
idempotencyKey: 'in_8821',
data: { id: 'in_8821', total: 4200 },
})
console.log(event.status) // 'delivered' Authentication
Keys are scoped to one account, one region and a set of providers. A
key beginning ak_test_ only ever reaches the sandbox, so a
test suite cannot call a real provider by accident.
curl https://api.acme.example/v1/events \
-H "Authorization: Bearer $ACME_KEY" \
-d provider=northwind \
-d type=invoice.paid Events
Every provider is normalised onto one envelope. The data
object is the provider's own payload, untouched; everything outside it
is ours and is the same everywhere.
{
"id": "evt_01HZX9",
"type": "invoice.paid",
"provider": "northwind",
"created": "2026-02-11T09:41:22Z",
"attempts": 1,
"data": { "id": "in_8821", "total": 4200 }
} Errors
Errors are a status code and a stable string. The string is what to branch on; the prose is for a human reading a log.
| Status | Code | Means |
|---|---|---|
400 | invalid_request | The payload did not match the event schema. |
401 | bad_key | The key is unknown, revoked, or for another region. |
403 | scope_denied | The key is valid but not scoped to this provider. |
409 | duplicate_event | An event with this idempotency key already landed. |
429 | rate_limited | Slow down. The Retry-After header says by how much. |