Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.qoder.com/llms.txt

Use this file to discover all available pages before exploring further.

A Session is the unit of work in Qoder Cloud Agents. It pairs an Agent (configuration) with an Environment (infrastructure) to form a stateful conversation. You send messages to a Session and receive a stream of events back.

Session Lifecycle

1

Created → idle

A new Session starts in idle, awaiting input.
2

idle → processing

Sending a user.message event moves the Session into processing.
3

processing → idle

When the turn completes, the Session returns to idle. Repeat for each turn.
4

cancelled / archived (terminal)

Cancellation and archival end the Session permanently — they cannot be resumed.
A Session is a state machine. The core states are:
StateDescriptionTransitions to
idleIdle, awaiting a user messageprocessing, cancelled
processingThe Agent is executingidle, cancelled
cancelledCancelled and terminated— (terminal)

Field Reference

FieldTypeDescription
idstringSystem-generated, prefixed with ses_
agent_idstringThe bound Agent ID
environment_idstringThe bound Environment ID
statusstringCurrent state: idle / processing / cancelled
titlestring/nullOptional Session title
metadataobjectCustom key-value pairs
usageobjectToken usage stats
usage.input_tokensintegerCumulative input tokens
usage.output_tokensintegerCumulative output tokens
created_atstringCreation timestamp
updated_atstringLast update timestamp

Create a Session

A Session needs both agent and environment_id.

Option 1: Pass an Agent ID (string)

Binds the latest version of the Agent:
# Create a Session with an Agent ID
curl -s -X POST https://openapi.qoder.sh/api/v1/cloud/sessions \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "ag_r4nD0mId123",
    "environment_id": "env_default"
  }' | jq .

Option 2: Pass an Agent Object (pin a version)

Binds a specific version of the Agent for behavioral consistency:
# Pin a specific Agent version when creating the Session
curl -s -X POST https://openapi.qoder.sh/api/v1/cloud/sessions \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": {
      "id": "ag_r4nD0mId123",
      "version": 2
    },
    "environment_id": "env_default"
  }' | jq .
A successful call returns 201 Created:
{
  "id": "ses_newSession456",
  "agent_id": "ag_r4nD0mId123",
  "environment_id": "env_default",
  "status": "idle",
  "title": null,
  "metadata": {},
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0
  },
  "created_at": "2026-05-18T12:00:00Z",
  "updated_at": "2026-05-18T12:00:00Z"
}
In production, prefer Option 2 (pinned version) so Agent updates do not change Session behavior unexpectedly.

agent Field Format

FormatExampleBehavior
String"ag_r4nD0mId123"Uses the latest version of the Agent
Object{"id": "ag_r4nD0mId123", "version": 2}Pins to the specified version

State Transitions

Event request body format

POST /sessions/{id}/events requests must wrap events in an events array, and content is an array of content blocks:
FieldTypeRequiredDescription
eventsarrayYesEvent array — one or more events per request
events[].typestringYesEvent type, e.g. user.message
events[].contentarrayYesContent block array
events[].content[].typestringYesContent block type, e.g. text
events[].content[].textstringYesText content

idleprocessing

Sending a user.message event moves the Session from idle to processing:
# Send a message to trigger processing
curl -s -X POST "https://openapi.qoder.sh/api/v1/cloud/sessions/ses_newSession456/events" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [{
      "type": "user.message",
      "content": [{"type": "text", "text": "Analyze the cyclomatic complexity of every Python file under the current directory."}]
    }]
  }' | jq .

processingidle

When the Agent finishes a turn the Session returns to idle. You will receive a session.status_idle event on the stream.

Cancel a Session

Force-terminate a running Session:
# Cancel the Session
curl -s -X POST "https://openapi.qoder.sh/api/v1/cloud/sessions/ses_newSession456/cancel" \
  -H "Authorization: Bearer $QODER_PAT"
Cancellation is terminal. A cancelled Session cannot be resumed; create a new Session instead.

Read Sessions

# Get a single Session
curl -s "https://openapi.qoder.sh/api/v1/cloud/sessions/ses_newSession456" \
  -H "Authorization: Bearer $QODER_PAT"
# List Sessions with pagination
curl -s "https://openapi.qoder.sh/api/v1/cloud/sessions?limit=10" \
  -H "Authorization: Bearer $QODER_PAT"
A paginated response:
{
  "data": [
    {
      "id": "ses_newSession456",
      "agent_id": "ag_r4nD0mId123",
      "environment_id": "env_default",
      "status": "idle",
      "usage": {
        "input_tokens": 1520,
        "output_tokens": 834
      }
    }
  ],
  "first_id": "ses_newSession456",
  "last_id": "ses_newSession456",
  "has_more": false
}

Usage Stats

Each Session tracks cumulative token usage:
FieldDescription
usage.input_tokensTotal input tokens across all requests
usage.output_tokensTotal output tokens across all responses
# Inspect Session usage
curl -s "https://openapi.qoder.sh/api/v1/cloud/sessions/ses_newSession456" \
  -H "Authorization: Bearer $QODER_PAT"
{
  "input_tokens": 3840,
  "output_tokens": 2156
}

Session and Agent Version Binding

A Session snapshots its Agent configuration at creation time:
  • The string form "agent": "ag_xxx" binds the latest version at creation time.
  • The object form "agent": {"id": "ag_xxx", "version": N} pins to an exact version.
  • Once a Session exists, modifying the Agent does not change the Session.
  • To use a new Agent version, create a new Session.

Session A — bound to Agent v1

Created before the update. Continues to use v1 even after the Agent has been updated to v2.

Session B — bound to Agent v2

Created after the update. Uses the new v2 configuration.

Multi-Turn Conversations

Sessions support multi-turn conversations. After each message, wait for session.status_idle before sending the next:
#!/bin/bash
# Multi-turn conversation example
BASE_URL="https://openapi.qoder.sh/api/v1/cloud"
SESSION_ID="ses_newSession456"
HEADERS=(
  -H "Authorization: Bearer $QODER_PAT"
)

# Turn 1: state the requirement
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{"events": [{"type": "user.message", "content": [{"type": "text", "text": "Scaffold a Python Flask project."}]}]}'

# Wait for processing to complete (poll or listen on SSE)
sleep 30

# Turn 2: add follow-up requirements
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{"events": [{"type": "user.message", "content": [{"type": "text", "text": "Add unit tests and a CI configuration to the project."}]}]}'

Best Practices

  1. Pin versions — always create production Sessions with {"id": ..., "version": ...}.
  2. Cancel promptly — cancel Sessions you no longer need to free resources.
  3. Watch usage — review usage periodically to catch unexpected token spend.
  4. Use metadata — record business context (task ID, trigger source) in metadata.

FAQ

Q: Do Sessions time out? A: Sessions stay idle for a while; long-inactive Sessions may be archived automatically. Create Sessions on demand and cancel them when work completes. Q: What happens if I send a message to a processing Session? A: The request fails. Wait until the Session returns to idle before sending the next message. Q: Is there a maximum number of turns per Session? A: There is no hard limit on turns, but the model context window applies. Older content may be truncated as the conversation grows. Q: How do I retrieve the full conversation history? A: Use GET /sessions/{id}/events to fetch every event for the Session, including user messages and Agent responses. Q: Can I resume a cancelled Session? A: No — cancelled is terminal. Create a new Session and pass relevant context in the first message.

Next Steps