ForgeAPI keys

Reference

Every route, generated from the OpenAPI document. Base URL: https://api.forge.team/v1

Kept in this tab only. Make a key

POST/v1/conversations

Start a conversation. Creates a conversation and sends its first message. The response shape follows reply and stream.

conversations:write · runs on your credits

Body

cwdoptionalstring The working folder the agent starts in. Omit for your default.
replyoptional"none" | "optional" | "required" Default optional.
streamoptionalboolean Stream the agent's messages as Server-Sent Events instead of one JSON body. Default false.
textstring The first message. Up to 100,000 characters.
titleoptionalstring A title for the conversation. Omit and Forge names it from the first message.

Response

200 · The agent's replies (reply optional or required).

conversationIdstring
messageIdstring The id of the message you sent.
repliesoptionalReply[] The agent's messages, in order. Absent on a 202 (reply: "none").
timedOutoptionalboolean True when the 10-minute wait ran out before the turn ended.

202 · Accepted (reply: "none"): the ids, with nothing awaited. Same fields.

Errors: 400, 401, 402, 403, 404, 409, 504. See Errors and limits.

Try it

Runs on your credits

GET/v1/conversations

List conversations. Your active conversations, newest first. A ticket is one row.

conversations:read

Parameters

limitoptionalnumber · query 1 to 100, default 20.

Response

200 · OK

conversationsConversation[]

Errors: 400, 401, 403, 404. See Errors and limits.

Try it

GET/v1/conversations/{conversationId}

Get a conversation. Whether the agent is working, what waits on you, and the end of its newest message.

conversations:read

Parameters

conversationIdstring · path

Response

200 · OK

acceptedInputsnumber Messages accepted that the next turn has not read yet.
busyboolean
conversationIdstring
deferredboolean The next turn is waiting for its turn to run.
deferredBy"account_cap" | "database" | "demand" | "memory" | "net" | "plan_cap" | "priority" | "provider" | "slot" | "user_cap" | "waitlist" | null
deferredSincenumber | null
etaSecondsnumber | null The measured time left, in seconds, when there is evidence for one.
lastAssistantTextstring | null The end of the agent's newest message.
nextAttemptAtMsnumber | null
pendingGatesPendingGate[]
runStatestring
stage"done" | "execute" | "finalise" | "plan" | "review" | null
stateConversationState | null
statusstring | null The agent's own one-line status, when it set one.
titlestring
updatedAtMsnumber Epoch milliseconds.
waitingForstring | null What the deferred turn waits on, in plain words.

Errors: 400, 401, 403, 404. See Errors and limits.

Try it

POST/v1/messages

Send a message. Sends a message to a conversation. The response shape follows reply and stream.

conversations:write · runs on your credits

Body

conversationIdstring
replyoptional"none" | "optional" | "required" Default optional.
streamoptionalboolean Stream the agent's messages as Server-Sent Events instead of one JSON body. Default false.
textstring The message. Up to 100,000 characters.

Response

200 · The agent's replies (reply optional or required).

conversationIdstring
messageIdstring The id of the message you sent.
repliesoptionalReply[] The agent's messages, in order. Absent on a 202 (reply: "none").
timedOutoptionalboolean True when the 10-minute wait ran out before the turn ended.

202 · Accepted (reply: "none"): the ids, with nothing awaited. Same fields.

Errors: 400, 401, 402, 403, 404, 409, 504. See Errors and limits.

Try it

Runs on your credits

GET/v1/conversations/{conversationId}/messages

List messages. What was said in a conversation, newest page first.

conversations:read

Parameters

conversationIdstring · path
beforeoptionalstring · query From the previous page, to read the messages before it. Opaque: pass it back as given.
limitoptionalnumber · query 1 to 1,000, default 50.

Response

200 · OK

beforestring | null Pass as before to read older messages; null when this page reaches the start.
conversationIdstring
messagesMessage[]

Errors: 400, 401, 403, 404. See Errors and limits.

Try it

Types

ApiError

codeoptionalstring
errorstring

Conversation

One row per piece of work: a ticket with several member conversations is one row, addressed by the member it is live on.

busyboolean The agent is working right now.
conversationIdstring The conversation to send to. For a ticket, its live member.
cwdstring | null
membersoptionalConversationMember[]
modelstring | null
stage"done" | "execute" | "finalise" | "plan" | "review" | null
ticketIdoptionalstring
titlestring
updatedAtMsnumber Epoch milliseconds.

ConversationList

conversationsConversation[]

ConversationMember

conversationIdstring
rolestring | null
titlestring

ConversationPath

conversationIdstring

ConversationState

reason"automatic-wake" | "cron" | "error" | "executing" | "gave-up" | "held" | "idle" | "paused-all" | "paused-one" | "paused-subtree" | "question" | "queue-rule" | "queued-for-slot" | "recovery-wait" | "request" | "retrying" | "stopped-mid-turn" | "ticket-unknown" | "waiting-on-convo" | null

ConversationStatus

Where a conversation is now: whether the agent is working, what waits on you, and its latest words.

acceptedInputsnumber Messages accepted that the next turn has not read yet.
busyboolean
conversationIdstring
deferredboolean The next turn is waiting for its turn to run.
deferredBy"account_cap" | "database" | "demand" | "memory" | "net" | "plan_cap" | "priority" | "provider" | "slot" | "user_cap" | "waitlist" | null
deferredSincenumber | null
etaSecondsnumber | null The measured time left, in seconds, when there is evidence for one.
lastAssistantTextstring | null The end of the agent's newest message.
nextAttemptAtMsnumber | null
pendingGatesPendingGate[]
runStatestring
stage"done" | "execute" | "finalise" | "plan" | "review" | null
stateConversationState | null
statusstring | null The agent's own one-line status, when it set one.
titlestring
updatedAtMsnumber Epoch milliseconds.
waitingForstring | null What the deferred turn waits on, in plain words.

ConversationStatus_eta_estimate_complete

asOfMsoptionalnumber the clock this reading is AS OF: the reader's own for a live read, the held one for a stale copy. A reader rendering it later says "as of X ago" once it is past STALE_AFTER_MS.
highMsnumber
kind"complete" | "estimate"
lowMsnumber
progressAgeMsoptionalnumber active ms since the last evidence (WorkProjection.progressAgeMs).
remainingMsnumber
runningLongoptionaltrue an in-flight tick is past its reference, or the work outran its estimate: say it is running long, never present the range as on track.
snapshotAgeMsoptionalnumber Derived age of that confirmed copy at the reader's clock; never persisted in storage.

ConversationStatus_eta_unknown

asOfMsoptionalnumber the clock this reading is AS OF: the reader's own for a live read, the held one for a stale copy. A reader rendering it later says "as of X ago" once it is past STALE_AFTER_MS.
basis"none"
confidence"none"
kind"unknown"
progressAgeMsoptionalnumber active ms since the last evidence (WorkProjection.progressAgeMs).
reasonoptional"no-plan" | "no-progress"
runningLongoptionaltrue an in-flight tick is past its reference, or the work outran its estimate: say it is running long, never present the range as on track.
snapshotAgeMsoptionalnumber Derived age of that confirmed copy at the reader's clock; never persisted in storage.

ConvoBucket

The bucket a row displays in — a SUPERSET of the state: buckets. needs-you is an is: property rather than a state value: it spans several unrelated runtime situations (a question, a spent error, a row the machine gave up on), so making it a state: value would break the rule that every row sits in exactly one State bucket — which group-by depends on. null is the resting state: a dormant conversation, and done, which is a resting state rather than a runtime one. Nullable so group-by keeps its "no state" section instead of inventing a Running bucket for every dormant conversation.

"inactive" | "needs-you" | "paused" | "running" | "scheduled" | null

CreateConversationRequest

cwdoptionalstring The working folder the agent starts in. Omit for your default.
replyoptional"none" | "optional" | "required" Default optional.
streamoptionalboolean Stream the agent's messages as Server-Sent Events instead of one JSON body. Default false.
textstring The first message. Up to 100,000 characters.
titleoptionalstring A title for the conversation. Omit and Forge names it from the first message.

ListConversationsQuery

limitoptionalnumber 1 to 100, default 20.

ListMessagesQuery

beforeoptionalstring From the previous page, to read the messages before it. Opaque: pass it back as given.
limitoptionalnumber 1 to 1,000, default 50.

Message

A message in a conversation: what you (or anyone in your workspace) said, and what the agent said back. Tool activity, thinking and notes are not part of the API.

messageIdstring
role"assistant" | "user"
textstring
timestampstring | null ISO 8601, when known.

MessagePage

A page of messages, oldest first within the page. The first request returns the newest page; pass before back to read older ones. limit bounds the transcript entries read and anything that is not a message (tool activity, notes) is left out, so a page can hold fewer than limit.

beforestring | null Pass as before to read older messages; null when this page reaches the start.
conversationIdstring
messagesMessage[]

PendingGate

Something waiting on you: a question, an approval or a task.

kindstring
promptstring
requestIdstring | null
tooloptionalstring

ProjectionBasis

"history" | "none" | "ticks" | "ticks+history"

ProjectionConfidence

"high" | "low" | "medium" | "none"

Reply

One message the agent sent to you.

messageIdstring
textstring
timestampstring ISO 8601.

RunPhase

"awaiting" | "draining" | "error" | "idle" | "queued" | "stopping" | "streaming" | "thinking" | "tool" | "working"

SendMessageRequest

conversationIdstring
replyoptional"none" | "optional" | "required" Default optional.
streamoptionalboolean Stream the agent's messages as Server-Sent Events instead of one JSON body. Default false.
textstring The message. Up to 100,000 characters.

SendResult

conversationIdstring
messageIdstring The id of the message you sent.
repliesoptionalReply[] The agent's messages, in order. Absent on a 202 (reply: "none").
timedOutoptionalboolean True when the 10-minute wait ran out before the turn ended.