Skip to main content
POST /v1/responses is the core call. You make it against your instance, not against api.agent37.com: every instance serves its own chat API at https://{instanceId}.agent37.app, the url of the default port in the create response. This page uses https://ab12cd34ef.agent37.app. Authenticate with the same sk_live_ key you use on the hosting API. The call is agentic by default: the agent can browse, run code, use a terminal, read and write files, call connected tools, and reason across many steps before answering. Omit session_id to start a conversation; the reply carries the session_id the gateway minted. Send it back to continue. The session keeps the full history, so you never resend a transcript: you send only the new input.

Request body

Request bodies are capped at 2 MB; anything larger returns 413 payload_too_large.
input
string
required
The message or task. Text only: a plain string, with no attachment, file, or image field. See Sessions and models for how history carries across turns.
session_id
string
Continue an existing conversation. Omit it to start a new one; the response returns the new session’s id. An unknown id returns 404 session_not_found.
stream
boolean
default:"false"
true returns a Server-Sent Events stream; false returns the finished response as one JSON body. See Streaming.
model
string
The LLM to run this turn on. Omit it to use the session’s current model (the instance default on a new session). List what the instance can run with GET /v1/models; see Sessions and models.
provider
string
The model’s provider, for example anthropic. Both model and provider are set per turn, and sending them on a continuation updates the session’s stored pair for the turns that follow.
reasoning_effort
string
How hard the model thinks: none, minimal, low, medium, high, or xhigh.
metadata
object
Up to 16 key/value pairs, at most 64 KB serialized. Echoed back on the response object, never interpreted.
agent
string
default:"hermes"
Which agent runs the turn. hermes is the default and the only agent today.
mode
string
default:"chat"
chat runs one turn and replies. goal is reserved: sending it returns 400 validation_error today.
instance_id in the body is accepted and ignored. The URL names the instance: one gateway per instance, so there is nothing to route.

Response

The response object. Ids are 32-character hex strings; timestamps from the gateway are epoch milliseconds.
id
string
The response id. Use it to fetch, reconnect, or cancel the turn.
session_id
string
The conversation this turn belongs to. Reuse it on the next call to continue the thread.
status
string
in_progress, then a terminal completed, failed, or cancelled.
agent
string
The agent that ran the turn, hermes today.
model
string | null
The model the turn ran on, null when none was set.
provider
string | null
The model’s provider, null when none was set.
output_text
string
The agent’s final answer. Always a string, empty if the turn produced none.
usage
object | null
Token counts and cost for the turn: { input_tokens, output_tokens, cost_usd }. cost_usd is absent or null when the provider did not report a cost.
error
object | null
Set when the turn failed: { code, message, param?, hint? }. See Errors.
metadata
object | null
Your request metadata, echoed back verbatim.
created
number
When the turn started, epoch milliseconds.
A failed turn does not reject the HTTP call. The POST still returns 200 with status: "failed" and error set. Branch on status, not on the HTTP code.

Example

curl https://ab12cd34ef.agent37.app/v1/responses \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Research the top 3 EV makers, write a memo."
  }'
Set stream: true to receive Server-Sent Events as the agent reasons, calls tools, and writes its answer. The terminal event carries the final output_text and usage. See Streaming.

Continue a conversation

The first message omits session_id and starts a session. The reply returns a session_id; pass it on the next message to continue the same thread. The session holds the full history, so you never resend a transcript: you send only the new input.
# 1. start a session: omit session_id
curl https://ab12cd34ef.agent37.app/v1/responses \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Research the top 3 EV makers, write a memo."
  }'
# -> { "id": "c91d2a7e84f04b6f9a3d5e1c0b87f4a2",
#      "session_id": "7f3e0b6c52a949d2b1c4a8e9d0f31726",
#      "status": "completed", ... }

# 2. continue it: reuse the session_id, send only the new input
curl https://ab12cd34ef.agent37.app/v1/responses \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "7f3e0b6c52a949d2b1c4a8e9d0f31726",
    "input": "Make it shorter, add a quote."
  }'
One active turn per session. A session runs one response at a time. Sending new input while one is in flight returns 409 session_busy. Use another session, or cancel the running turn first.
To list a user’s threads, read a thread’s history, delete one, or pick a model, see Sessions and models.

Follow up on a response

Every response has an id you can use after the call returns.
ActionEndpoint
Fetch it againGET /v1/responses/{id}
Reconnect a dropped streamGET /v1/responses/{id}/stream
Stop a running turnPOST /v1/responses/{id}/cancel
GET /v1/responses/{id} returns the response object at any time, before or after the turn finishes. GET /v1/responses/{id}/stream replays every event so far in order, then stays attached live, so a dropped connection never loses the answer. See Streaming for the replay window. POST /v1/responses/{id}/cancel takes no body and stops a running turn, best effort. It returns 200 with the current response object. Cancelling a finished response is a no-op that returns its terminal state, still 200.
Cancel does not rewind. Whatever the agent has already done (files written, emails sent, tools called) is not undone. The response ends with status: "cancelled".

Status values

A response moves from in_progress to exactly one terminal status.
StatusMeaning
in_progressThe turn is running.
completedThe turn finished and output_text holds the answer.
failedThe turn ended on an error; error says why.
cancelledYou stopped the turn with cancel.

Next steps

Streaming

The full event list and a client parser for stream: true.

Sessions

List threads, read history, delete a session, and pick a model.

Build a chat app

Put send, continue, and list together into a working chat.

Instances

Create, size, and manage the computer a conversation runs on.