> ## 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.

# Quickstart

> Run your first Qoder Cloud Agent in five steps.

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)

<Accordion title="Windows users" defaultOpen>
  The commands in this guide use bash syntax. Windows users should use one of the following:

  * **Git Bash** (recommended): included with [Git for Windows](https://git-scm.com/download/win)
  * **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`
</Accordion>

## Step 1: Obtain a PAT

1. Sign in to the [Qoder console](https://qoder.com).
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:

```bash theme={null}
export QODER_PAT="your-personal-access-token"
```

<Note>
  The token is shown only once at creation. Save it immediately — adding it to `~/.bashrc` or `~/.zshrc` is recommended.
</Note>

## Step 2: Pick an Environment

List the available environments and capture the ID:

```bash theme={null}
curl -s https://api.qoder.com/api/v1/cloud/environments \
  -H "Authorization: Bearer $QODER_PAT"
```

Example response:

```json theme={null}
{
  "data": [
    {
      "id": "env_019e44eb66bb748cabcd1489f6fa4428",
      "type": "environment",
      "name": "default",
      "description": "",
      "config": {
        "type": "cloud",
        "networking": {
          "type": "unrestricted",
          "allowed_hosts": [],
          "allow_package_managers": false,
          "allow_mcp_servers": false
        },
        "packages": {
          "type": "packages",
          "apt": [],
          "npm": [],
          "pip": []
        }
      },
      "metadata": {},
      "archived_at": null,
      "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,
  "next_page": null
}
```

<Tip>
  If the response returns `"data": []` (empty array), your account has no environments yet. Create one first:

  ```bash theme={null}
  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"}}}'
  ```
</Tip>

```bash theme={null}
# 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:

```bash theme={null}
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",
    "system": "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:

```json theme={null}
{
  "id": "agent_019e451902fe7a2ca42c2dfc62d9320e",
  "type": "agent",
  "name": "my-first-agent",
  "description": "",
  "model": "ultimate",
  "system": "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"]}],
  "mcp_servers": [],
  "skills": [],
  "metadata": {},
  "multiagent": null,
  "version": 1,
  "archived_at": null,
  "created_at": "2026-05-18T10:00:00Z",
  "updated_at": "2026-05-18T10:00:00Z"
}
```

## Step 4: Create a Session

Creating a Session requires two parameters: `agent` (Agent ID or object) and `environment_id` (Environment ID).

Bind the Agent to the Environment to create a runtime instance:

```bash theme={null}
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:

```json theme={null}
{
  "id": "sess_019e451b146470cda02c560bf019fb37",
  "type": "session",
  "agent": {
    "id": "agent_019e451902fe7a2ca42c2dfc62d9320e",
    "type": "agent",
    "name": "my-first-agent",
    "model": {"id": "ultimate", "effective_context_window": 200000},
    "version": 1
  },
  "environment_id": "env_019e44eb66bb748cabcd1489f6fa4428",
  "status": "idle",
  "title": null,
  "metadata": {},
  "resources": [],
  "vault_ids": [],
  "deployment_id": null,
  "outcome_evaluations": [],
  "stats": {"active_seconds": 0, "duration_seconds": 0},
  "environment_variables": {},
  "archived_at": null,
  "created_at": "2026-05-18T10:01:00Z",
  "updated_at": "2026-05-18T10:01:00Z"
}
```

<Note>
  The Session starts in `idle` status. It will only begin processing once you send a message in the next step.
</Note>

## Step 5: Send a Message and Stream Events

Send a user message to the Session, then receive Agent responses live over SSE:

```bash theme={null}
# 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 .
```

```bash theme={null}
# 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:

```text theme={null}
id: evt_019ef515680d7a0ebd3160ca45ec5484
event: user.message
data: {"content":[{"text":"Write a Python function that computes the Fibonacci sequence and run a test.","type":"text"}],"id":"evt_019ef515680d7a0ebd3160ca45ec5484","processed_at":"2026-06-23T15:24:41.357659669Z","type":"user.message"}

id: evt_019ef515681a7c52a0b45aa87625f121
event: session.status_running
data: {"id":"evt_019ef515681a7c52a0b45aa87625f121","processed_at":"2026-06-23T15:24:41.357659669Z","type":"session.status_running"}

event: heartbeat
data: {}

id: evt_49dce735a4ab4fc4
event: agent.thinking
data: {"id":"evt_49dce735a4ab4fc4","processed_at":"2026-06-23T15:24:49.357659Z","type":"agent.thinking"}

id: evt_02f80c5a8c245e04
event: agent.message
data: {"content":[{"text":"I'll create a Python module with the Fibonacci function and comprehensive tests.","type":"text"}],"id":"evt_02f80c5a8c245e04","processed_at":"2026-06-23T15:24:49.357659Z","type":"agent.message"}

id: evt_50739b167fb7c6d3
event: agent.tool_use
data: {"evaluated_permission":"allow","id":"evt_50739b167fb7c6d3","input":{"content":"def fibonacci(n): ...","file_path":"/data/fibonacci.py"},"name":"Write","processed_at":"2026-06-23T15:24:49.357659Z","type":"agent.tool_use"}

id: evt_e7c375f3605ff156
event: agent.tool_result
data: {"content":[{"text":"Write file /data/fibonacci.py successfully","type":"text"}],"id":"evt_e7c375f3605ff156","is_error":false,"processed_at":"2026-06-23T15:25:01.853844Z","type":"agent.tool_result"}

id: evt_60eba1483797a419
event: session.status_idle
data: {"id":"evt_60eba1483797a419","processed_at":"2026-06-23T15:25:24.436729Z","stop_reason":{"type":"end_turn"},"type":"session.status_idle"}
```

<Note>
  * Every event (except `heartbeat`) includes an `id:` line and the JSON payload contains `id`, `type`, and `processed_at` fields.
  * `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.
  * `session.status_running` / `session.status_idle` carry no extra fields beyond `id`, `type`, `processed_at`, and (for idle) `stop_reason`.
  * `agent.thinking` signals that the model is reasoning but contains no `content` or `text` field.
</Note>

## End-to-End Script

The whole flow combined into a single runnable script:

```bash theme={null}
#!/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",
      "system": "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: The stream endpoint supports the `Last-Event-ID` header for reconnection replay. Pass the last event `id` you received; the stream resumes from the event after that ID. Event-type query filters are not currently supported.

**Q: `GET /api/v1/cloud/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

<CardGroup cols={2}>
  <Card title="Agent setup" icon="user-gear" href="/cloud-agents/define-agent">
    Every field in the Agent configuration.
  </Card>

  <Card title="Cloud environment setup" icon="server" href="/cloud-agents/environments">
    Customize the runtime environment.
  </Card>

  <Card title="Start a session" icon="play" href="/cloud-agents/sessions">
    Manage Session lifecycle in depth.
  </Card>

  <Card title="Agent Skills" icon="sparkles" href="/cloud-agents/skills">
    Attach domain expertise to your Agent for better task performance.
  </Card>
</CardGroup>
