HTTP API
Call the Studio runtime from scripts, tests, or custom internal tools.
Studio exposes the same runtime used by the bundled UI as an HTTP API.
Core Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/health | GET | Check that the runtime is alive |
/config | GET | Read agents, quick prompts, and enabled capabilities |
/agents | GET | List registered agents |
/agents/:agentId | GET | Read one agent config |
/agents/:agentId/runs | POST | Run an agent |
/sessions | GET, POST | List or create sessions |
/sessions/:sessionId | GET, DELETE | Read or delete a session |
/sessions/:sessionId/traces | GET | List traces for a session |
/traces | GET | List traces |
/traces/:traceId | GET | Read one trace |
/approvals | GET | List pending or resolved approvals |
/approvals/:approvalId/decision | POST | Approve or reject a tool call |
Run Request Shape
type AgentRunRequest = {
message: string | Message;
history?: Message[];
sessionId?: string;
stream?: boolean;
maxTurns?: number;
toolConcurrency?: number;
metadata?: JsonObject;
trace?: AgentTraceOptions;
};Use history for one-off calls. Use sessionId when Studio should load and persist conversation history.
Non-Streaming Run
curl -X POST http://localhost:4021/agents/support-operations/runs \
-H 'content-type: application/json' \
-d '{
"message": "Summarize order ORD-1001.",
"maxTurns": 3,
"trace": {
"name": "manual-test",
"userId": "dev_1",
"tags": ["studio"]
}
}'The response is a prompt response:
{
"output": "Order ORD-1001 is blocked while allocation is pending.",
"messages": [],
"usage": {
"inputTokens": 0,
"outputTokens": 0,
"totalTokens": 0
}
}Streaming Run
curl -N -X POST http://localhost:4021/agents/support-operations/runs \
-H 'content-type: application/json' \
-d '{"message":"Summarize order ORD-1001.","stream":true}'Streaming responses use newline-delimited JSON.
{"type":"turn_start","turn":1}
{"type":"text_delta","turn":1,"delta":"Order ORD-1001"}
{"type":"turn_end","turn":1}
{"type":"final","output":"Order ORD-1001 is blocked.","messages":[]}Approval events can appear in the same stream:
{"type":"tool_approval_request","approval":{"id":"approval_123","status":"pending"}}
{"type":"tool_approval_result","approval":{"id":"approval_123","status":"approved"}}Test Without Opening a Port
Use .fetch(...) when testing Studio wiring.
import { Studio } from "@anvia/studio";
const studio = new Studio([agent]);
const response = await studio.fetch(
new Request("http://studio.test/agents/support/runs", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ message: "Hello" }),
}),
);
const body = await response.json();This exercises the same routes as the served runtime.
