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.

Get your first Qoder Cloud Agent running in five steps: obtain a token, pick an environment, create an Agent, create a Session, and exchange messages. The whole flow uses only curl — no SDK required.

Prerequisites

  • A Qoder account
  • A terminal (macOS, Linux, or WSL)
  • curl, plus jq (optional, for formatting JSON)

Windows users

The commands in this guide use bash syntax. Windows users should use one of the following:
  • Git Bash (recommended): included with Git for Windows
  • WSL: install via wsl --install
If using PowerShell, note these differences:
  • Set environment variables: $env:QODER_PAT="your-token" (not export)
  • Use real curl: type curl.exe (PowerShell aliases curl to Invoke-WebRequest)
  • Install jq separately: winget install jqlang.jq

Step 1: Obtain a PAT

  1. Sign in to the Qoder console.
  2. Open “Settings → Personal Access Tokens”.
  3. Click “Create Token”, set a name and expiration.
  4. Copy the token and export it as an environment variable:
export QODER_PAT="your-personal-access-token"
The token is shown only once at creation. Save it immediately — adding it to ~/.bashrc or ~/.zshrc is recommended.

Step 2: Pick an Environment

List the available environments and capture the ID:
curl -s https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT"
Example response:
{
  "data": [
    {
      "id": "env_019e44eb66bb748cabcd1489f6fa4428",
      "name": "default",
      "config": {
        "type": "cloud",
        "networking": {
          "type": "unrestricted"
        }
      },
      "status": "ready",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z"
    }
  ],
  "first_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "last_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "has_more": false
}
If the response returns "data": [] (empty array), your account has no environments yet. Create one first:
curl -s -X POST https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{"name":"default","config":{"type":"cloud","networking":{"type":"unrestricted"}}}'
# Extract the environment ID (use jq to avoid error-prone manual copying of long IDs)
ENV_ID=$(curl -s https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT" | jq -r '.data[0].id')

echo "Environment ID: $ENV_ID"

Step 3: Create an Agent

Define a general-purpose Agent with a shell tool:
AGENT_RESPONSE=$(curl -s -X POST https://api.qoder.com/api/v1/cloud/agents \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-first-agent",
    "model": "ultimate",
    "instructions": "You are an efficient programming assistant skilled at writing code and troubleshooting issues.",
    "tools": [
      {"type": "agent_toolset_20260401", "enabled_tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]}
    ]
  }')
echo "$AGENT_RESPONSE" | jq .
AGENT_ID=$(echo "$AGENT_RESPONSE" | jq -r '.id')
echo "Agent ID: $AGENT_ID"
Example response:
{
  "id": "agent_019e451902fe7a2ca42c2dfc62d9320e",
  "name": "my-first-agent",
  "model": "ultimate",
  "instructions": "You are an efficient programming assistant skilled at writing code and troubleshooting issues.",
  "tools": [{"type": "agent_toolset_20260401", "enabled_tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]}],
  "metadata": {},
  "version": 1,
  "created_at": "2026-05-18T10:00:00Z",
  "updated_at": "2026-05-18T10:00:00Z"
}

Step 4: Create a Session

Bind the Agent to the Environment to create a runtime instance:
SESSION_RESPONSE=$(curl -s -X POST https://api.qoder.com/api/v1/cloud/sessions \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d "{
    \"agent\": \"$AGENT_ID\",
    \"environment_id\": \"$ENV_ID\"
  }")
echo "$SESSION_RESPONSE" | jq .
SESSION_ID=$(echo "$SESSION_RESPONSE" | jq -r '.id')
echo "Session ID: $SESSION_ID"
Example response:
{
  "id": "sess_019e451b146470cda02c560bf019fb37",
  "agent": {"id": "agent_019e451902fe7a2ca42c2dfc62d9320e", "version": 1},
  "agent_id": "agent_019e451902fe7a2ca42c2dfc62d9320e",
  "environment_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "status": "idle",
  "title": null,
  "metadata": {},
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0
  },
  "created_at": "2026-05-18T10:01:00Z",
  "updated_at": "2026-05-18T10:01:00Z"
}
The Session starts in idle status. It will only begin processing once you send a message in the next step.

Step 5: Send a Message and Stream Events

Send a user message to the Session, then receive Agent responses live over SSE:
# Send a message (note: the request body wraps events in an array)
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.message",
        "content": [{"type": "text", "text": "Write a Python function that computes the Fibonacci sequence and run a test."}]
      }
    ]
  }' | jq .
# Stream events over SSE
curl -s -N "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events/stream" \
  -H "Authorization: Bearer $QODER_PAT"
Example event stream output:
event: user.message
data: {"type":"user.message","content":"Write a Python function that computes the Fibonacci sequence and run a test."}

event: session.status_running
data: {"type":"session.status_running","status":"running"}

event: heartbeat
data: {}

event: span.model_request_start
data: {"type":"span.model_request_start"}

event: agent.thinking
data: {"type":"agent.thinking","content":"Let me write a Fibonacci function..."}

event: agent.message
data: {"type":"agent.message","content":[{"type":"text","text":"Here is an implementation of the Fibonacci sequence: ..."}]}

event: agent.tool_use
data: {"type":"agent.tool_use","name":"Bash","input":{"command":"python3 fib.py"}}

event: agent.tool_result
data: {"type":"agent.tool_result","output":"..."}

event: span.model_request_end
data: {"type":"span.model_request_end"}

event: session.status_idle
data: {"type":"session.status_idle","status":"idle"}
  • heartbeat events are sent approximately every 15 seconds to keep the connection alive.
  • The content field in agent.message uses the [{"type":"text","text":"..."}] array format.

End-to-End Script

The whole flow combined into a single runnable script:
#!/bin/bash
# Qoder Cloud Agents quickstart script
# Usage: export QODER_PAT="your-token" && bash quickstart.sh

set -euo pipefail

BASE_URL="https://api.qoder.com/api/v1/cloud"
HEADERS=(
  -H "Authorization: Bearer $QODER_PAT"
)

echo "=== Step 1: Fetch environment ==="
ENV_ID=$(curl -s "$BASE_URL/environments" "${HEADERS[@]}" | jq -r '.data[0].id')
if [ "$ENV_ID" = "null" ] || [ -z "$ENV_ID" ]; then
  echo "No environment found. Creating a default one..."
  ENV_ID=$(curl -s -X POST "$BASE_URL/environments" \
    "${HEADERS[@]}" \
    -H "Content-Type: application/json" \
    -d '{"name":"default","config":{"type":"cloud","networking":{"type":"unrestricted"}}}' | jq -r '.id')
fi
echo "Environment ID: $ENV_ID"

echo "=== Step 2: Get or create the Agent ==="
AGENT_ID=$(curl -s "$BASE_URL/agents" "${HEADERS[@]}" | jq -r '.data[0].id')
if [ "$AGENT_ID" = "null" ] || [ -z "$AGENT_ID" ]; then
  AGENT_ID=$(curl -s -X POST "$BASE_URL/agents" \
    "${HEADERS[@]}" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "quickstart-agent",
      "model": "ultimate",
      "instructions": "You are an efficient programming assistant.",
      "tools": [{"type": "agent_toolset_20260401", "enabled_tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebFetch", "WebSearch"]}]
    }' | jq -r '.id')
fi
echo "Agent ID: $AGENT_ID"

echo "=== Step 3: Create the Session ==="
SESSION_ID=$(curl -s -X POST "$BASE_URL/sessions" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d "{\"agent\": \"$AGENT_ID\", \"environment_id\": \"$ENV_ID\"}" | jq -r '.id')
echo "Session ID: $SESSION_ID"

echo "=== Step 4: Send a message ==="
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": "Print Hello World and tell me the current system time."}]}
    ]
  }' | jq .

echo "=== Step 5: Stream events ==="
echo "(Press Ctrl+C to exit)"
curl -s -N "$BASE_URL/sessions/$SESSION_ID/events/stream" "${HEADERS[@]}"

FAQ

Q: I’m getting 401 Unauthorized. A: Check that $QODER_PAT is set correctly and the token has not expired. Recreate the token and update the environment variable. Q: Creating an Agent returns 400 Bad Request. A: Verify the request JSON. The model field must be a valid value (such as "ultimate"), and tools must be an array. Q: The Session stays in idle and emits no events. A: A newly created Session starts in idle status. You must send a user.message event (Step 5) to trigger Agent execution. Q: My SSE stream disconnected. A: Recommended: save the id field of the last event received before disconnection (e.g. evt_...), then reconnect with ?after_id=<last_event_id> query parameter. The server will resume pushing from after that event, without losing intermediate events. If not saved, use GET /sessions/{id}/events?order=desc to replay recent events before opening the stream. Q: GET /environments returns an empty array. A: New accounts may not have a pre-provisioned environment. Follow the tip in Step 2 to create one manually.

Next Steps