Agents API runs
POST /v1/agents/runs is asynchronous. The trigger returns
immediately with a runId; the result lands on
GET /v1/runs/{runId} when the run finishes.
GET /v1/runs/{runId}
curl https://api.kindo.ai/v1/runs/7a7ced7d-95a8-416f-95bb-5c0ff3599f53 \ -H "Authorization: Bearer $KINDO_API_KEY"Response:
{ "runId": "7a7ced7d-95a8-416f-95bb-5c0ff3599f53", "agentId": "18d20df4-d9b3-4cb0-a009-9f11ec9c5d3d", "createdAtUtc": "2026-03-12T15:00:00.000Z", "endedAtUtc": "2026-03-12T15:00:08.000Z", "result": "{\"role\":\"assistant\",\"parts\":[{\"type\":\"text\",\"text\":\"Security scan complete. No critical findings.\"}]}", "status": "success"}| Field | Type | Notes |
|---|---|---|
runId | string | Matches the runId returned by the trigger. |
agentId | string | null | The agent that produced this run. null when the underlying agent has been soft-deleted; the run record remains visible but no longer resolves to a live agent. |
createdAtUtc | string | ISO-8601 timestamp when the trigger was accepted. |
endedAtUtc | string | null | ISO-8601 timestamp when the run reached a terminal status, or null while status is in_progress. |
result | string | null | A JSON-encoded string of the final assistant message payload — parse with JSON.parse to recover { role, parts, ... }. null while in_progress, always null on failure or cancelled, and also null on success when the run produced no assistant payload. |
status | string | One of in_progress, success, failure, cancelled. |
Status lifecycle
in_progress ──▶ success ──▶ failure ──▶ cancelledin_progress— the only non-terminal status. Continue polling.success— the run completed;resultholds the JSON-encoded final assistant payload, or isnullif the run produced no assistant payload.failure— the run errored.resultisnull; inspect the Kindo Terminal or the underlying conversation for diagnostics.cancelled— the run was cancelled (manually or by a timeout).resultisnull.
GET /v1/runs/{runId}/evals
Returns the aggregate evaluation result and per-step verdicts for a completed run. Each agent step can have an objective; this endpoint reports whether those objectives were met.
curl https://api.kindo.ai/v1/runs/7a7ced7d-95a8-416f-95bb-5c0ff3599f53/evals \ -H "Authorization: Bearer $KINDO_API_KEY"Response:
{ "runId": "7a7ced7d-95a8-416f-95bb-5c0ff3599f53", "result": "fail", "steps": [ { "stepNumber": 1, "name": "Perform Web Search for Trending Stock", "result": "pass", "explanation": "Kindo performed web searches and synthesized findings into a clear summary." }, { "stepNumber": 2, "name": "Generate Stock Forecast", "result": "pass", "explanation": "Kindo delivered a comprehensive forecast with analyst targets and risk factors." }, { "stepNumber": 3, "name": "Execute Trade on Robinhood", "result": "fail", "explanation": "Kindo cannot execute trades on Robinhood — it lacks brokerage integration." } ]}| Field | Type | Notes |
|---|---|---|
runId | string | Matches the runId from the trigger. |
result | string | Aggregate eval result. One of pass, fail, pending, skipped, unknown. pass = all objectives satisfied; fail = at least one failed; pending = run in progress or verdicts not yet written; skipped = run failed/cancelled before evaluation; unknown = no definitive result. |
steps | array | One entry per step in the run, ordered by stepNumber. |
Step shape:
| Field | Type | Notes |
|---|---|---|
stepNumber | integer | 1-indexed position in the run. |
name | string | null | Display name of the step, or null if unnamed. |
result | string | null | One of pass, fail, not_evaluated, unknown, or null. pass = objective satisfied; fail = objective not satisfied; not_evaluated = evaluation did not run; unknown = verdict could not be determined. null when no verdict has been recorded yet. |
explanation | string | null | Free-form explanation of the verdict; null when not evaluated. |
The evals endpoint returns 404 when the run does not exist or the
caller lacks access — the same collapse-to-404 behavior as
GET /v1/runs/{runId}.
Polling cadence
Runs are typically long-running (seconds to minutes), so a short poll-then-back-off works well in practice:
- Wait 1–2 seconds before the first poll.
- Back off to 5–10 seconds for subsequent polls.
- Treat any non-
in_progressstatusas terminal and stop.
Kindo does not currently push webhooks for run completion; polling is the only delivery mechanism for the result.
Runs and conversations
A run executed by an agent that uses the Responses API internally
will produce its own conversation server-side. The runId itself
is not a conversation_id — to inspect the underlying conversation
history, fetch it via the
Conversations API using the
conversation ID surfaced in the Kindo Terminal or in the agent’s
configured outputs. For most use cases, result on
GET /v1/runs/{runId} is the only field you need.
See also
- Quickstart — end-to-end discover → trigger → poll flow.
- Request shape — the trigger and discovery bodies.
- Errors —
404 Not found,422 Unprocessable Entity, etc.