Results, polling and errors
AI team tools return a uniform shape with next-step hints and a polling interval, and errors say whether to retry and what to do. Other tools return text with structured content.
Updated 2026-10-13
Success
The AI-team tools (list_team, assign_task, list_runs, get_run, answer_run, cancel_run, list_approvals, search_library, get_library_item, list_memory, get_plan_build) return the same JSON, both as text and as structured content.
A successful result
{
"ok": true,
"summary": "Iris (researcher) is on it.",
"run": { "id": "…", "status": "queued", "employee": { "id": "…", "name": "Iris", "role": "researcher" } },
"reused": false,
"poll_after_seconds": 20,
"next": [
{ "tool": "get_run", "why": "Check progress and read the report when it finishes.", "args": { "run_id": "…" } }
]
}| Field | Meaning |
|---|---|
ok | True on success. |
summary | One sentence a model can relay to the founder. |
poll_after_seconds | How long to wait before polling again. Null when finished. |
next | What would sensibly come next: a tool, why, and arguments. |
The company, plan and note tools (get_founder_context, get_operating_plan, get_task_prompt, list_artifacts, get_credit_balance, run_research, save_note, save_chat, add_milestone, update_operating_plan, list_workspaces, set_active_workspace) return a text result with a structuredContent object.
Errors
An error result
{
"ok": false,
"code": "insufficient_credits",
"message": "You're out of AI credits for now.",
"retryable": false,
"how_to_fix": "The workspace is out of AI credits. Check get_credit_balance and ask the founder."
}Errors are returned in-band with isError, so the model can react to them rather than the call failing at the protocol level.
| Code | Meaning | What to do |
|---|---|---|
unauthorized | No signed-in Pythe connection. | Reconnect Pythe and sign in again. |
forbidden | The connection cannot reach that workspace. | Reconnect and choose the workspace again. |
not_found | No such employee, run or item. | Check the id with list_team or list_runs. |
ambiguous | More than one employee matches the name. | Use the employee’s id from list_team. |
invalid_input | An argument is wrong. | Check it against the tool’s inputs. |
paused | That employee is paused. | The founder can resume them from Team in Pythe. |
employees | AI employees are not on this plan. | Employees are on Base and Premium; the founder can upgrade. |
group_chats | Group chats are not on this plan. | Base and Premium. |
insufficient_credits (HTTP 402) | The workspace is out of AI credits. | Check get_credit_balance and ask the founder. |
network | Could not reach Pythe. | Retryable. Try again in a moment. |
http_5xx, http_429 | Server trouble or rate limit. | Retryable. |
internal | Something unexpected. | Marked retryable. |
Idempotency
Send the same idempotency_key to assign_task when you retry, and the task starts once. The result says reused: true and gives the existing run.
Plan write conflicts
Plan writes compare the version you read against the stored one. If someone saved a newer plan, nothing is updated and the message tells you to read get_operating_plan again. A save that fails to reach the Library is never reported as success.
Related
Previous: Recipes: delegate, build, research, keep · Next: The REST gateway and API keys