Run (Synchronous)
POST /api/v1/teams/:teamId/run-sync — execute a team and wait for the full response.
Runs a Team and blocks until it finishes, up to 30 seconds. For anything that might take
longer, use /run-async instead.
POST /api/v1/teams/{teamId}/run-syncDesign decision: /run-sync, not /run
A Team's synchronous run route is /run-sync, not /run — the Studio "Run" button already
registers POST /api/v1/teams/:teamId/run for its own JWT-authenticated use, so the public API's
synchronous route uses a distinct path to avoid the collision. This mirrors the already-distinct
/run-stream and /run-async sibling paths.
Path parameters
| Parameter | Type | Description |
|---|---|---|
teamId | string (UUID) | The team to run. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
message | string (min 1 char) | Yes | The prompt to send the team. The team's own coordination mode and lead decide who reads it first. |
session_id | string | No | Continue an existing conversation. Omit to start a new session — a new session_id is generated and returned. |
user_id | string | No | Your own identifier for the end user. Omit to have one generated. |
include_messages | boolean | No | Default false. When true, the response's messages field is populated with the full message history instead of null. |
This is narrower than the agent /run body:
there's no tag or tool_context field. Neither has a slot on the wire for a team run — teams
don't support tool-context plumbing.
Response
200 OK
{
"runId": "b7e1...",
"teamId": "3f9c...",
"teamName": "Support Escalation Team",
"content": "Hello! How can I help you today?",
"sessionId": "a1c4...",
"userId": "d92e...",
"createdAt": 1732550123,
"success": true,
"metrics": {
"inputTokens": 12,
"outputTokens": 9,
"latencyMs": 842,
"model": null,
"failoverUsed": false
},
"messages": null
}content— the team's final reply text (the lead's synthesis, or the routed member's response in Route mode).metrics— the same shape as the agent/runresponse:inputTokens,outputTokens,latencyMs,model,failoverUsed. There's no separate per-member cost breakdown here — per-member/lead cost attribution lives in the trace view in Studio, not the run response.messages—nullunless you passedinclude_messages: true.
Timeout behaviour
If the team hasn't finished within 30 seconds, the request is aborted and the in-flight run is cancelled upstream:
504 Gateway Timeout
{
"error": "execution_timeout",
"message": "Team execution exceeded the 30 s limit. Use /run-async for long-running tasks."
}If you're hitting this regularly — likely with plan-execute teams, which can take several
iterations — switch that call to POST /run-async and poll for the
result instead.
Cancelling a run
DELETE /api/v1/teams/{teamId}/runs/{runId}Cancels an in-progress run by the runId returned in the response above (or, for streaming, in
the RunStarted event). Returns 200 either way — { "cancelled": true, "runId": "..." } if it
was still running, or { "cancelled": false, "runId": "...", "message": "Run already completed." }
if it had already finished.
Errors
| Status | error | When |
|---|---|---|
400 | validation error ({ "errors": [...] }) | message missing/empty, or another field fails validation |
403 | forbidden | The team belongs to a different project than your project-scoped key |
404 | team_not_found | No team with that ID exists in your organization |
404 | run_not_found (cancel only) | No run with that ID |
502 | bad_gateway / upstream_error | The team runtime is unreachable or returned an error mid-run |
504 | execution_timeout | The run didn't finish within 30 seconds |
Example
curl -X POST https://api.elizon.com/api/v1/teams/{teamId}/run-sync \
-H "X-API-Key: elz_your_key_here" \
-H "Content-Type: application/json" \
-d '{"message": "A customer is asking about a refund on order #4821"}'