Webhooks and events
Where events go, how each delivery went, and the record of every event.
RoutesOpen one for every field it takes and answers.
POST/v1/webhooksRegister a URL and the events it wants.
The signing secret is shown once.
Request4 fields
Body
urlstring (URL)requiredWhere to send the events: a public https URL, at most 2,048 characters. Private, local and internal addresses are refused.
- Limits
- At most 2048 characters.
- Example
https://api.example.com/vestra
events(string | "*")[]requiredThe events it wants: 1 to 40 types, or * for all.
- Limits
- 1 to 40 items.
descriptionstringA note for you, in at most 500 characters.
- Limits
- At most 500 characters.
activebooleanWhether to send to it. Default: true.
- Default
true
Answers 20112 fields
idstringThe endpoint (whk_...).
- Example
whk_2bq
object"webhook_endpoint"Always webhook_endpoint.
- Type
"webhook_endpoint"
urlstringWhere the events go.
- Type
string
events(string | "*")[]The events it wants.
- Type
(string | "*")[]
descriptionstring | nullYour note; null when you gave none.
- Type
string | null
activebooleanWhether events are sent to it.
- Type
boolean
mode"live" | "test"The mode it hears: test or live, the mode of the key that made it. A test endpoint never hears a live event.
- Type
"live" | "test"
deployment_idstring | nullOnly this deployment's events reach it (dep_...), plus your account's, such as keys, users and usage alerts. Set when a deployment's vestra.yaml declared the endpoint. Null: every event its types allow.
- Type
string | null
managed_by"file" | nullfile: declared in that deployment's vestra.yaml, so deploying the file changes it; null: you made it.
- Type
"file" | null
created_atstringWhen it was made, as an ISO 8601 time.
- Type
string
updated_atstringWhen it last changed, as an ISO 8601 time.
- Type
string
secretstringThe signing secret, shown this once: check every delivery against it (the Vestra-Signature header). Keep it on your server.
- Example
whsec_...
const endpoint = await vestra.events.to('https://hooks.example.com/vestra');endpoint = vestra.events.to("https://hooks.example.com/vestra")vestra events --to https://hooks.example.com/vestra# Stream a conversation live. If the connection drops, reconnect with the last seq you saw.curl -N "$VESTRA_BASE_URL/v1/conversations/conv_8f2k/events" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Last-Event-ID: 41" # Read the same events as JSON. You get them in pages, after the seq you give.curl "$VESTRA_BASE_URL/v1/conversations/conv_8f2k/events?format=json&after=41" \ -H "Authorization: Bearer $VESTRA_API_KEY" # Read a task afterwards. You get every step of one task, with tokens and cost per turn.curl "$VESTRA_BASE_URL/v1/tasks/task_91d/trace" \ -H "Authorization: Bearer $VESTRA_API_KEY" # Send events to your server. Register a URL and the events it wants. The signing secret is shown only once.curl "$VESTRA_BASE_URL/v1/webhooks" \ -H "Authorization: Bearer $VESTRA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://hooks.example.com/vestra", "events": ["task.completed", "interaction.created", "usage.cap_reached"] }' # Catch up on what you missed. List the events your webhooks were sent, newest first.curl "$VESTRA_BASE_URL/v1/events?type=task.failed" \ -H "Authorization: Bearer $VESTRA_API_KEY"{ "method": "tools/call", "params": { "name": "events", "arguments": { "user": "traveller-42", "conversation": "conv_8f2k", "after": 0 } }}