Skip to content

A top-level run completed, failed or was cancelled

View as Markdown
POST
webhook-id
required
string

The event id; the same on every retry. Deduplicate on it.

webhook-timestamp
required
string
/^[0-9]+$/

Unix seconds when the request was signed. Reject requests far from your clock.

webhook-signature
required
string

v1,<base64 HMAC-SHA256 of "{webhook-id}.{webhook-timestamp}.{body}"> under the endpoint’s secret; space-separated when two secrets sign during a rotation.

Media typeapplication/json
object
id
required

Event id, also sent as the webhook-id header; the same on every retry.

string
type
required
string
Allowed value: run.finished
createdAt
required
string format: date-time
data
required
object
run
required

A finished top-level run: its identity and outcome, never its input or output. Field names match GET /v1/runs/{runId}.

object
id
required

RunId.

string format: uuid
projectId
required
string format: uuid
flowId
required
string
flowVersion
required
string
status
required
string
Allowed values: completed failed cancelled
dryRun
required
boolean
failureMessage
required

Why the run failed or was cancelled; null when it completed.

string | null
failure

A failed run’s error, as GET /v1/runs/{runId} reads it back: its code, and the error’s own details when it has them. Absent unless the run failed, and from a runtime that doesn’t send it yet; read failureMessage then.

object
code
required
string
message
required
string
cause

What the error came from, when it says: e.g. for capability-routing-failed, the router’s capability-unsatisfiable with its reasons, by provider.

reason

The error’s own reason, when it gives one: for a turn that ended at its approval (hitl-cancelled), timeout when nobody decided in time. Absent from an older runtime and from errors without one; read code then.

string
details

The error’s own facts, for a code that has them: for rate-limit-exceeded, limit (the budget that refused: schema-compile-time or template-render-time) and budgetMs, the names the API’s 429 uses. Never the wait: read back later, it’s stale. Absent for any other code, and from an older runtime.

object
key
additional properties
any
createdAt
required
string format: date-time
completedAt
required
string format: date-time
usage

The model calls of the run tree (this run and every run it started) that the cost ledger had recorded when this run finished: a child run still running then isn’t in it. calls counts failed calls too. Absent when the runtime records no usage.

object
calls
required
integer
costUsd
required
number
tokens
required
object
prompt
required
integer
completion
required
integer
cacheRead
required
integer
cacheWrite
required
integer
reasoning
required
integer
agent

On an agent’s run: the agent, the version that ran and the conversation, as GET /v1/runs/{runId} shows them (an agent run’s flowId is agent.turn). Absent on a flow’s run, and from a runtime before Kindgi 0.1.6.

object
id
required

The agent id.

string
version
required

The agent version that ran (semver).

string
conversationId
required
string format: uuid
via

Why this version ran: named by the caller (explicit); held by the flow version a flow’s agent step runs in (flow-pin: the node’s config.version, else the version the flow version pinned when it was published); the conversation’s own (conversation); the version live for the run’s scope (live); or the latest, nothing being live (latest). Absent on runs from before Kindgi 0.1.4.

string
Allowed values: explicit flow-pin conversation live latest
liveScope
One of: discriminator: kind

The agent’s default for the whole tenant.

object
kind
required
string
Allowed values: tenant

Received. Any other answer, or none within 10 seconds, is retried.