Runs
A run is one invocation of an agent. The lifecycle is three calls: POST /v1/runs to open, zero or more POST /v1/runs/{id}/events, POST /v1/runs/{id}/finish to close. The SDK constructs the run ID locally as a UUIDv7 with the run_ prefix and the team's region segment, then dispatches all three without waiting on prior responses.
All three are idempotent: retrying with the same ID returns 200 OK, retrying with conflicting fields returns 409 Conflict. Events may be posted before the run record.
Base URL: https://eu.ingest.agentping.io/v1/...
POST /v1/runs
Start a new run.
Request
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Client-generated. Format run_<region>_<32 hex>. See Identifiers. |
agent |
string | Yes | Agent slug. New agents are auto-created on first appearance. |
started_at |
string (ISO 8601, UTC) | Yes | Client clock, millisecond precision. |
customer_id |
string | No | Used for per-customer cost attribution. |
feature |
string | No | Free-form feature label, indexed for filters. |
metadata |
object | No | Flat key/value JSON. Paid feature, limits below. |
Response
202 Accepted on first write, 200 OK on idempotent retry, 409 Conflict if the ID exists with a different agent or started_at.
{
"id": "run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6",
"agent": "support-triage",
"started_at": "2026-05-15T14:32:01.123Z",
"received_at": "2026-05-15T14:32:01.156Z",
"status": "running"
}
Example
curl -X POST https://eu.ingest.agentping.io/v1/runs \
-H "Authorization: Bearer apk_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6" \
-H "Content-Type: application/json" \
-d '{
"id": "run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6",
"agent": "support-triage",
"started_at": "2026-05-15T14:32:01.123Z",
"customer_id": "acme-corp",
"feature": "ticket-routing"
}'
POST /v1/runs/{id}/events
Append one or more events to an in-flight run. Each event has its own client-generated id for deduplication; the batch is processed atomically.
Request
| Field | Type | Required | Description |
|---|---|---|---|
events |
array | Yes | Up to 50 per batch. Larger returns 400 Bad Request. |
events[].id |
string | Yes | Client-generated. Format evt_<region>_<32 hex>. |
events[].type |
string | Yes | llm_call, log, tool_call, or custom. See Events. |
events[].ts |
string (ISO 8601, UTC) | Yes | Client clock. |
events[].data |
object | Yes | Payload. See Events. |
Response
202 Accepted with batch summary.
{ "accepted": 2, "duplicates": 0 }
Events with existing ids are silently dropped and counted under duplicates. cost_usd on llm_call events is server-computed; clients don't supply it.
Example
curl -X POST https://eu.ingest.agentping.io/v1/runs/run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6/events \
-H "Authorization: Bearer apk_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"id": "evt_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b7",
"type": "llm_call",
"ts": "2026-05-15T14:32:02.456Z",
"data": {
"provider": "anthropic",
"model": "claude-opus-4-7",
"input_tokens": 1200,
"output_tokens": 340,
"latency_ms": 4500
}
},
{
"id": "evt_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b8",
"type": "log",
"ts": "2026-05-15T14:32:03.001Z",
"data": {"message": "Routed to billing department"}
}
]
}'
POST /v1/runs/{id}/finish
Close out a run with a terminal status.
Request
| Field | Type | Required | Description |
|---|---|---|---|
status |
string | Yes | success, failed, timeout, or cancelled. |
finished_at |
string (ISO 8601, UTC) | Yes | Client clock. |
output |
object | No | Run result, arbitrary JSON. |
scores |
object | No | Self-reported scores keyed by metric. Numeric or boolean. |
Response
202 Accepted on first write, 200 OK on idempotent retry. A run already finished with a mismatching payload returns the original finish record unchanged. Downstream (cost finalisation, checks, alerts, judge enqueue) runs asynchronously.
Example
curl -X POST https://eu.ingest.agentping.io/v1/runs/run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6/finish \
-H "Authorization: Bearer apk_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6" \
-H "Content-Type: application/json" \
-d '{
"status": "success",
"finished_at": "2026-05-15T14:32:05.789Z",
"output": {"department": "billing", "severity": 2},
"scores": {"confidence": 0.92, "auto_resolved": true}
}'
GET /v1/runs/{id}
Retrieve a run's full record: events, scores, check results, judge results, parent/child trace links. Served by the control API. Response shape matches the dashboard's run detail page.