Agents
Dispatch Theo Agents, talk to goal-driven agents on threads, approve their actions, and read their results.
Dispatching
Dispatch any of your Theo Agents by id (requires the ai scope). The dispatch returns 202 with the new run's identifiers; execution continues in the background through the same engine that powers manual runs in-app, including credit accounting and run history.
curl -X POST https://www.opencharts.com/api/v1/agents/AGENT_ID/run \
-H "Authorization: Bearer $OPENCHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "inputs": { "topic": "Weekly metrics recap" } }'Monitoring runs
Poll a run until it reaches a terminal state, or list an agent's recent history. Pair with the evi.run_completed / evi.run_failed webhook events to skip polling.
Talking to an agent
Goal-driven agents (Theo Claw workers) also take messages: send one on a threadId and the agent remembers the whole thread across calls, exactly like a Slack thread or its in-app chat. The reply is the run's result: poll the resultUrl the 202 returns until status is completed (the reply plus any artifacts the agent made), paused (an action needs the owner's approval), or failed.
messagerequiredstringthreadIdstring/agents/{id}/messagesSend a message to a goal-driven agent on a thread.GET/agents/{id}/runs/{runId}/resultGet the reply, artifacts, or pending approval.curl -X POST https://www.opencharts.com/api/v1/agents/AGENT_ID/messages \
-H "Authorization: Bearer $OPENCHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "message": "Summarize this week and share it as a link", "threadId": "weekly-recap" }'
# -> 202 { "runId": "...", "threadId": "weekly-recap", "resultUrl": "/api/v1/agents/AGENT_ID/runs/.../result" }Approvals
When a result reports paused, its pendingApproval names the action and the approve URL. The agent's owner can approve or reject over the API (or in OpenCharts, or in Slack); the run then resumes on the same thread and the result URL fills in.
decisionrequiredapprove | rejectOpenAI-compatible endpoint
Any OpenAI SDK can talk to an agent: point baseURL at /api/v1, use your API key, and set model to agent:AGENT_ID. The last user message is the turn and the agent runs inline, so the request waits for the reply. Keep a conversation with metadata.thread_id (or user). With stream: true the reply arrives as one final chunk over SSE (the connection is kept warm while the agent works).
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://www.opencharts.com/api/v1",
apiKey: process.env.OPENCHARTS_API_KEY,
});
const completion = await client.chat.completions.create({
model: "agent:AGENT_ID",
messages: [{ role: "user", content: "What did we ship this week?" }],
metadata: { thread_id: "weekly-recap" },
});
console.log(completion.choices[0].message.content);Usage
Ask what an agent has cost: runs by outcome and trigger, credits recorded on its runs, average duration, and the last run time over a window of 1 to 90 days. The account-wide balance is GET /account/credits.