Events
An event is a record that something happened. Events are stored and readable through the API, and delivered to any webhook endpoint subscribed to their type. They are recorded while your account has an active API key or an enabled webhook endpoint, so the log starts when the first one exists.
Events are what let you stop polling. Training, crawling and tool runs all finish on their own schedule; an event tells you the moment they do.
The payload
Every event has the same envelope, whatever its type:
{
"object": "event",
"id": "evt_4d9a1f2c8b7e4a6d9c0f3b2a1e5d7c9f",
"type": "knowledge.dataset.trained",
"api_version": "2026-08-14",
"created": 1710000000,
"data": {
"object": {
"object": "knowledge_dataset",
"id": 12
}
}
}id— unique per event, prefixedevt_. Deduplicate on this: a retried delivery re-sends the same id, and receiving one twice is normal.type— what happened. Subscribe by type, or use*for everything.created— Unix timestamp of when it was recorded.data.object— a reference to what changed: itsobjecttype andid. It is not the full resource; fetch that from its REST endpoint when you need the current fields. A few events carry extra fields of their own — for examplewebhook_endpoint.disabledadds the endpoint'surlanddisabled_reason, andbilling.payment.failedadds theinvoice,attempt_countandnext_payment_attempt.api_version— the version that shapeddata.object.
An event is recorded in the same database transaction as the change it describes, or after that change commits — never before. An event you receive describes something that has definitely happened; there is no window where you get told about a change that later gets rolled back.
The catalogue
Generated from the API's own event catalogue, so it lists every type that can actually be delivered — no more, no fewer.
The ones that matter most
Most events describe something you just did yourself — you called POST /v1/chatbots, you get chatbot.created. Useful for audit, not urgent.
These are different. They tell you about work that finished without you asking, and there is no other way to learn about them except polling:
| Event | Why it matters |
|---|---|
knowledge.dataset.trained | Content is now usable in answers |
knowledge.dataset.failed | It is not, and never will be without intervention |
crawl.completed / crawl.failed | Same, for a whole site |
conversation.handoff.requested | A visitor is waiting for a human, right now |
action.run.failed | Your own system failed mid-conversation |
billing.credits.low | Top up before chat starts refusing |
billing.credits.exhausted | Chat is refusing now |
knowledge.dataset.trained, knowledge.dataset.failed,
conversation.handoff.requested, and billing.credits.low. Those cover
"my content is ready", "my content is broken", "a customer needs a person",
and "I am about to run out".
Credit events do not spam
billing.credits.low fires at most once per billing period, and
billing.credits.exhausted likewise. Crossing the threshold does not emit an
event per message — that would make the signal useless. A renewal re-arms
both.
Reading events back
Webhooks are push; this is pull. Both read the same records.
GET/v1/events
curl "https://api.agentency.com/v1/events?limit=20" \
-H "Authorization: Bearer <YOUR_KEY>"Filter by an exact type (no wildcards) and by created[gte] /
created[lte], page with cursors, and fetch one with GET /v1/events/{id} —
{id} is the evt_… id, not a number. This is the right tool for backfilling
after downtime: rather than replaying deliveries one by one, list what you
missed. Each event's payload is the exact body its deliveries carried.
A key restricted to selected agents cannot read events (403 FORBIDDEN): they
cover every agent on the account.
GET /v1/event_types returns the catalogue programmatically, which is handy
for building a subscription UI.
Events are kept for 90 days by default and then pruned (webhook delivery records for 30). Treat them as a delivery mechanism and a short-term recovery log, not permanent storage — if you need history, store what you receive.
What's next
- Webhooks — receive these, and verify they are real.
- Going live — which to subscribe to before launch.