Skip to main content
Send OpenAI-style messages to POST /v1/chat/completions. Set agent for direct agent mode; omit it to use the project orchestrator. model can override the selected agent model for a single call. temperature, max_tokens, and the deprecated project field are accepted for compatibility and applied when supported by the runtime/provider path. An optional loop selects one of the target agent’s assignedLoops.

Per-request tool restriction

Use polpo.execution.allowedTools to narrow tool access for one request:
This is an additional intersection, never an override that grants access. For direct chat, effective access is the intersection of the agent-wide policy, chat.allowedTools, this request policy, and trusted runtime grants. For a Project Loop, Polpo uses the agent-wide policy, loop.allowedTools, the current step policy, this request policy, and trusted grants. Entering a Loop therefore does not carry forward a direct-chat restriction. Client-side OpenAI-compatible tools declared in tools are filtered by the same policy. A forced tool_choice that names a denied tool fails before model execution. Tool-policy trace data records the active mode, requested tools, effective tools, and denied tools.

Request

Streaming uses server-sent events and ends with data: [DONE]. Set stream: false for one chat.completion JSON response. Messages support system, user, assistant, and tool roles. Content can be a string or an array of text, image_url, and file parts. user is an opaque caller-provided end-user identifier; Polpo does not authenticate it. sandbox.isolation can be reuse, fresh, or shared; sandbox.lifecycle controls whether the workspace is pooled or destroyed after the run; sandbox.volumes selects a narrower subset of the target agent’s persistent-volume grants. See Sandboxes. metadata accepts up to 16 string entries, with keys up to 64 characters and values up to 512 characters.

Sessions

Every response includes x-session-id. If the request has no x-session-id header, Polpo creates a new session. Persist the returned value and send it on later requests:
Use x-session-id: new to force a new session. There is no implicit reuse when the header is omitted.

TypeScript SDK

Pass sessionId in the SDK request to continue a session. Call stream.abort() to cancel a streaming request.

Continue after disconnect

Durable delivery is opt-in. Add polpo.delivery.onDisconnect: "continue" to a streaming request when the run must continue after the client loses its SSE connection:
The initial response includes x-polpo-run-id, and persisted SSE frames include an id cursor. The SDK reconnects to GET /v1/runs/{runId}/events from the last complete cursor without repeating the original request.
  • stream.detach() closes only the current subscriber.
  • await stream.cancel(reason) explicitly cancels the run.
  • stream.abort() retains its historical cancel behavior.
  • stream.resume({ after }) attaches to an existing run from a cursor.
Requests that omit this option keep cancel-on-disconnect behavior. Durable delivery requires stream: true; Polpo rejects unsupported combinations rather than silently changing their semantics.

Files and images

Upload a file to an existing persistent volume through the public Files API:
Then use the workspace-relative path as file_id:
A file part becomes a text reference to a project file path, so the agent needs suitable file tools and a grant to that volume. For direct multimodal image input, use an image_url part with an HTTPS URL or data URL and configure a compatible vision model. Persistent volume files belong to the project, not the chat session. The implicit local sandbox workspace instead follows sandbox lifecycle.

Client-side tool calls

In direct agent chat, interactive tools such as ask_user_question stop the model tool loop and return finish_reason: "ask_user". To resume, continue the same x-session-id and send a tool message with the returned tool_call_id, tool name, and serialized answer in content. The interrupted assistant tool call is already stored in that session. Project Loops do not support client-interaction tools in agent steps, deterministic tool steps, or hooks. A Loop configuration that references ask_user_question is rejected with loop_interactive_tool_not_supported. Collect required answers before selecting loop, then start the Loop with complete input. The endpoint follows OpenAI chat request and response conventions, but agent, loop, session headers, and Polpo finish reasons are extensions. OpenAI clients may require an extra-body mechanism for those fields.