diff --git a/docs/ai-coder/agents/getting-started.md b/docs/ai-coder/agents/getting-started.md index 514c2698caccc..5667ba2de0dd1 100644 --- a/docs/ai-coder/agents/getting-started.md +++ b/docs/ai-coder/agents/getting-started.md @@ -203,7 +203,7 @@ deployment. Use this to encode organizational conventions: - Any guardrails specific to your environment. Configure the system prompt from **Admin settings** > **AI** > **Coder Agents** > **Instructions** -or via the API at `PUT /api/v2/chats/config/system-prompt`. +or via the API at `PUT /api/experimental/chats/config/system-prompt`. See [Platform Controls](./platform-controls/index.md) for details. ### Understand the security model @@ -272,20 +272,25 @@ This is useful for building automations such as: **Quick example — create a Coder Agent via the API:** ```sh -curl -X POST https://coder.example.com/api/v2/chats \ +curl -X POST https://coder.example.com/api/experimental/chats \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ + "organization_id": "", "content": [ {"type": "text", "text": "Fix the failing tests in the auth service"} ] }' ``` +`organization_id` is required, and the caller must be a member of that +organization. To find the ID, call `GET /api/v2/organizations` and use the +`id` field of the organization you want. + Stream updates in real time by connecting to the WebSocket endpoint: ```txt -GET /api/v2/chats/{chat}/stream +GET /api/experimental/chats/{chat}/stream ``` For service-to-service automation, use diff --git a/docs/ai-coder/agents/platform-controls/chat-auto-archive.md b/docs/ai-coder/agents/platform-controls/chat-auto-archive.md index 69f83441afb56..26a36d56aab75 100644 --- a/docs/ai-coder/agents/platform-controls/chat-auto-archive.md +++ b/docs/ai-coder/agents/platform-controls/chat-auto-archive.md @@ -78,8 +78,8 @@ enable auto-archiving. Use the admin API to read or update the value: - GET /api/v2/chats/config/auto-archive-days - PUT /api/v2/chats/config/auto-archive-days + GET /api/experimental/chats/config/auto-archive-days + PUT /api/experimental/chats/config/auto-archive-days ## Rollout advice diff --git a/docs/ai-coder/agents/platform-controls/chat-debug-logging.md b/docs/ai-coder/agents/platform-controls/chat-debug-logging.md index 36b485e47c9eb..7b2206281a4cd 100644 --- a/docs/ai-coder/agents/platform-controls/chat-debug-logging.md +++ b/docs/ai-coder/agents/platform-controls/chat-debug-logging.md @@ -12,11 +12,12 @@ Off by default. Three layers control whether it runs for a given chat: 1. **Runtime admin gate.** With the deployment override unset, the *Let users record chat debug logs* toggle decides whether users can opt in. Configure it under **Admin settings** > **AI** > **Coder Agents** > **Lifecycle**, or at - `GET/PUT /api/v2/chats/config/debug-logging`. + `GET/PUT /api/experimental/chats/config/debug-logging`. + 1. **Per-user toggle.** Users with the admin gate enabled can turn debug logging on for their own chats from **Agents** > **Settings** > **General** under *Record debug logs for my chats*. The endpoint - `PUT /api/v2/chats/config/user-debug-logging` returns + `PUT /api/experimental/chats/config/user-debug-logging` returns `409 Conflict` if the deployment override is active and `403 Forbidden` if the admin has not enabled user opt-in. @@ -51,9 +52,9 @@ the newest runs. The same data is available through the API: -- `GET /api/v2/chats/{chat}/debug/runs` lists the most recent runs +- `GET /api/experimental/chats/{chat}/debug/runs` lists the most recent runs for a chat (up to 100, newest first). -- `GET /api/v2/chats/{chat}/debug/runs/{debugRun}` returns a single +- `GET /api/experimental/chats/{chat}/debug/runs/{debugRun}` returns a single run with all of its steps, including normalized request and response bodies. Fetch a single run and save it as JSON: @@ -66,7 +67,7 @@ export RUN_ID="11111111-1111-1111-1111-111111111111" curl -fsS \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ - "$CODER_URL/api/v2/chats/$CHAT_ID/debug/runs/$RUN_ID" \ + "$CODER_URL/api/experimental/chats/$CHAT_ID/debug/runs/$RUN_ID" \ | jq . > "coder-agents-debug-run-$RUN_ID.json" ``` @@ -77,7 +78,7 @@ from above: ```sh RUN_IDS=$(curl -fsS \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ - "$CODER_URL/api/v2/chats/$CHAT_ID/debug/runs" \ + "$CODER_URL/api/experimental/chats/$CHAT_ID/debug/runs" \ | jq -r '.[].id') || { echo "Failed to list debug runs" >&2 exit 1 @@ -89,7 +90,7 @@ trap 'rm -f "$RUN_EXPORTS"' EXIT for RUN_ID in $RUN_IDS; do curl -fsS \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ - "$CODER_URL/api/v2/chats/$CHAT_ID/debug/runs/$RUN_ID" \ + "$CODER_URL/api/experimental/chats/$CHAT_ID/debug/runs/$RUN_ID" \ >> "$RUN_EXPORTS" || { echo "Failed to fetch debug run $RUN_ID" >&2 exit 1 diff --git a/docs/ai-coder/agents/platform-controls/chat-debug-retention.md b/docs/ai-coder/agents/platform-controls/chat-debug-retention.md index d5504dab5cb3b..8efb8bbc4cf69 100644 --- a/docs/ai-coder/agents/platform-controls/chat-debug-retention.md +++ b/docs/ai-coder/agents/platform-controls/chat-debug-retention.md @@ -28,8 +28,8 @@ is `3650` days. Use the admin API to read or update the value: ```txt -GET /api/v2/chats/config/debug-retention-days -PUT /api/v2/chats/config/debug-retention-days +GET /api/experimental/chats/config/debug-retention-days +PUT /api/experimental/chats/config/debug-retention-days ``` ## Interaction with conversation retention diff --git a/docs/ai-coder/agents/platform-controls/chat-retention.md b/docs/ai-coder/agents/platform-controls/chat-retention.md index e28d6fe70a7f6..5d52c768fd3a5 100644 --- a/docs/ai-coder/agents/platform-controls/chat-retention.md +++ b/docs/ai-coder/agents/platform-controls/chat-retention.md @@ -31,8 +31,8 @@ disable retention entirely. Use the admin API to read or update the value: ```txt -GET /api/v2/chats/config/retention-days -PUT /api/v2/chats/config/retention-days +GET /api/experimental/chats/config/retention-days +PUT /api/experimental/chats/config/retention-days ``` ## What gets deleted diff --git a/docs/ai-coder/agents/platform-controls/index.md b/docs/ai-coder/agents/platform-controls/index.md index c83ba9685c12a..b18d8c08d1103 100644 --- a/docs/ai-coder/agents/platform-controls/index.md +++ b/docs/ai-coder/agents/platform-controls/index.md @@ -75,8 +75,8 @@ This setting is available under **Admin settings** > **AI** > **Coder Agents** > The same value is exposed over the chat configuration API: -- `GET /api/v2/chats/config/plan-mode-instructions` -- `PUT /api/v2/chats/config/plan-mode-instructions` +- `GET /api/experimental/chats/config/plan-mode-instructions` +- `PUT /api/experimental/chats/config/plan-mode-instructions` ### Template routing diff --git a/docs/ai-coder/agents/platform-controls/spend-management.md b/docs/ai-coder/agents/platform-controls/spend-management.md index a2ae8b825b99d..61d1f0cc07252 100644 --- a/docs/ai-coder/agents/platform-controls/spend-management.md +++ b/docs/ai-coder/agents/platform-controls/spend-management.md @@ -28,9 +28,9 @@ $1,000,000 per member per period. > Configured per-model prices and historical native cost totals are also not migrated to AI Gateway. > Before upgrading, record any per-model prices you need from **Admin settings** > **AI** > **Models**. > The old cost endpoints default `start_date` to 30 days before the request and `end_date` to the request time, so choose explicit RFC 3339 UTC values that cover all history you need. -> Fetch `/api/v2/chats/cost/users?start_date=&end_date=&limit=100&offset=0` and save the response. +> Fetch `/api/experimental/chats/cost/users?start_date=&end_date=&limit=100&offset=0` and save the response. > After each page, stop when `offset + users.length >= count`; otherwise, increase `offset` by 100 and fetch the next page. -> For every `users[].user_id` across those pages, save `/api/v2/chats/cost/{user_id}/summary?start_date=&end_date=` with the same dates. +> For every `users[].user_id` across those pages, save `/api/experimental/chats/cost/{user_id}/summary?start_date=&end_date=` with the same dates. > Each summary contains the user's totals plus `by_model` and `by_chat` breakdowns. > After upgrading, the native **Spend** page, per-model pricing fields, and aggregate cost endpoints are unavailable. > Historical `chat_messages.total_cost_micros` values remain in the database temporarily for rolling upgrade compatibility, but AI Gateway reports do not include or reconstruct them. diff --git a/docs/ai-coder/agents/platform-controls/virtual-desktop.md b/docs/ai-coder/agents/platform-controls/virtual-desktop.md index 89dd9661ffe6c..8630a6ee4b764 100644 --- a/docs/ai-coder/agents/platform-controls/virtual-desktop.md +++ b/docs/ai-coder/agents/platform-controls/virtual-desktop.md @@ -40,5 +40,5 @@ provider is set. The same configuration is available at: -- `GET /api/v2/chats/config/computer-use-provider` -- `PUT /api/v2/chats/config/computer-use-provider` +- `GET /api/experimental/chats/config/computer-use-provider` +- `PUT /api/experimental/chats/config/computer-use-provider` diff --git a/docs/ai-coder/agents/tasks-to-chats-migration.md b/docs/ai-coder/agents/tasks-to-chats-migration.md index 9f9de00024467..867844c966128 100644 --- a/docs/ai-coder/agents/tasks-to-chats-migration.md +++ b/docs/ai-coder/agents/tasks-to-chats-migration.md @@ -7,8 +7,8 @@ > previous version of the Coder documentation, from a release before v2.36. The Tasks API (`/api/v2/tasks`) and the -[Chats API](../../reference/api/chats.md) (`/api/v2/chats`) serve similar -goals (programmatic access to AI-powered coding agents) but they differ +[Chats API](../../reference/api/chats.md) (`/api/experimental/chats`) serve +similar goals (programmatic access to AI-powered coding agents) but they differ significantly in architecture, capabilities, and usage patterns. This guide walks you through updating your integrations from the Tasks API @@ -47,21 +47,21 @@ Before mapping individual endpoints, understand the structural changes: The table below maps each Tasks API endpoint to its Chats API equivalent. -| Operation | Tasks API | Chats API | -|-------------------|-------------------------------------------|-------------------------------------------------------------------| -| List | `GET /api/v2/tasks` | `GET /api/v2/chats` | -| Create | `POST /api/v2/tasks/{user}` | `POST /api/v2/chats` | -| Get by ID | `GET /api/v2/tasks/{user}/{task}` | `GET /api/v2/chats/{chat}` | -| Delete | `DELETE /api/v2/tasks/{user}/{task}` | `PATCH /api/v2/chats/{chat}` with `{"archived": true}` | -| Send follow-up | `POST /api/v2/tasks/{user}/{task}/send` | `POST /api/v2/chats/{chat}/messages` | -| Update input | `PATCH /api/v2/tasks/{user}/{task}/input` | `PATCH /api/v2/chats/{chat}/messages/{message}` | -| Get logs / stream | `GET /api/v2/tasks/{user}/{task}/logs` | `GET /api/v2/chats/{chat}/stream` (WebSocket) | -| Pause | `POST /api/v2/tasks/{user}/{task}/pause` | `POST /api/v2/chats/{chat}/interrupt` | -| Resume | `POST /api/v2/tasks/{user}/{task}/resume` | `POST /api/v2/chats/{chat}/messages` (send a new message) | -| Watch all | n/a | `GET /api/v2/chats/watch` (WebSocket) | -| Get messages | n/a | `GET /api/v2/chats/{chat}/messages` | -| List models | n/a | `GET /api/experimental/organizations/{organization}/chats/models` | -| Upload file | n/a | `POST /api/v2/chats/files` | +| Operation | Tasks API | Chats API | +|-------------------|-------------------------------------------|---------------------------------------------------------------------| +| List | `GET /api/v2/tasks` | `GET /api/experimental/chats` | +| Create | `POST /api/v2/tasks/{user}` | `POST /api/experimental/chats` | +| Get by ID | `GET /api/v2/tasks/{user}/{task}` | `GET /api/experimental/chats/{chat}` | +| Delete | `DELETE /api/v2/tasks/{user}/{task}` | `PATCH /api/experimental/chats/{chat}` with `{"archived": true}` | +| Send follow-up | `POST /api/v2/tasks/{user}/{task}/send` | `POST /api/experimental/chats/{chat}/messages` | +| Update input | `PATCH /api/v2/tasks/{user}/{task}/input` | `PATCH /api/experimental/chats/{chat}/messages/{message}` | +| Get logs / stream | `GET /api/v2/tasks/{user}/{task}/logs` | `GET /api/experimental/chats/{chat}/stream` (WebSocket) | +| Pause | `POST /api/v2/tasks/{user}/{task}/pause` | `POST /api/experimental/chats/{chat}/interrupt` | +| Resume | `POST /api/v2/tasks/{user}/{task}/resume` | `POST /api/experimental/chats/{chat}/messages` (send a new message) | +| Watch all | n/a | `GET /api/experimental/chats/watch` (WebSocket) | +| Get messages | n/a | `GET /api/experimental/chats/{chat}/messages` | +| List models | n/a | `GET /api/experimental/organizations/{organization}/chats/models` | +| Upload file | n/a | `POST /api/experimental/chats/files` | ## Migration steps @@ -101,7 +101,7 @@ path segment is required: ```sh # Chats API: create a chat -curl -X POST https://coder.example.com/api/v2/chats \ +curl -X POST https://coder.example.com/api/experimental/chats \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ @@ -144,7 +144,7 @@ curl -X POST https://coder.example.com/api/v2/tasks/me/my-task/send \ ```sh # Chats API: send a message curl -X POST \ - https://coder.example.com/api/v2/chats/$CHAT_ID/messages \ + https://coder.example.com/api/experimental/chats/$CHAT_ID/messages \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ @@ -172,7 +172,7 @@ curl https://coder.example.com/api/v2/tasks/me/my-task/logs \ **Chats API**. You open a one-way WebSocket connection: ```txt -GET wss://coder.example.com/api/v2/chats/{chat}/stream +GET wss://coder.example.com/api/experimental/chats/{chat}/stream ``` The WebSocket sends JSON envelopes with a `type` field (`"ping"`, @@ -219,7 +219,7 @@ The Tasks API uses `DELETE` to remove a task. The Chats API uses archiving: - curl -X DELETE https://coder.example.com/api/v2/tasks/me/my-task \ - -H "Coder-Session-Token: $CODER_SESSION_TOKEN" -+ curl -X PATCH https://coder.example.com/api/v2/chats/$CHAT_ID \ ++ curl -X PATCH https://coder.example.com/api/experimental/chats/$CHAT_ID \ + -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"archived": true}' @@ -248,12 +248,12 @@ message resumes processing: ```sh # Chats API: interrupt curl -X POST \ - https://coder.example.com/api/v2/chats/$CHAT_ID/interrupt \ + https://coder.example.com/api/experimental/chats/$CHAT_ID/interrupt \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" # Chats API: resume by sending a new message curl -X POST \ - https://coder.example.com/api/v2/chats/$CHAT_ID/messages \ + https://coder.example.com/api/experimental/chats/$CHAT_ID/messages \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ @@ -484,7 +484,7 @@ WORKSPACE_ID=$(curl -s -X POST \ }' | jq -r '.id') # 2. Create the chat bound to that workspace. -curl -s -X POST https://coder.example.com/api/v2/chats \ +curl -s -X POST https://coder.example.com/api/experimental/chats \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d "{ @@ -525,7 +525,7 @@ If this returns an empty list or an error, revisit Create a simple chat that does not require a workspace: ```sh -curl -s -X POST https://coder.example.com/api/v2/chats \ +curl -s -X POST https://coder.example.com/api/experimental/chats \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ @@ -544,7 +544,7 @@ returns a response. Using [websocat](https://github.com/vi/websocat): ```sh websocat -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ - "wss://coder.example.com/api/v2/chats/$CHAT_ID/stream" + "wss://coder.example.com/api/experimental/chats/$CHAT_ID/stream" ``` You should see JSON envelopes with `"type": "data"` containing @@ -557,7 +557,7 @@ Verify multi-turn conversation works: ```sh curl -s -X POST \ - "https://coder.example.com/api/v2/chats/$CHAT_ID/messages" \ + "https://coder.example.com/api/experimental/chats/$CHAT_ID/messages" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ @@ -587,7 +587,7 @@ as `execute`) against the attached workspace. After the chat finishes, verify the chat is bound to the workspace via the API: ```sh -curl -s "https://coder.example.com/api/v2/chats/$CHAT_ID" \ +curl -s "https://coder.example.com/api/experimental/chats/$CHAT_ID" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '{workspace_id, status}' ``` @@ -602,14 +602,14 @@ Start a long-running chat and interrupt it: ```sh curl -s -X POST \ - "https://coder.example.com/api/v2/chats/$CHAT_ID/interrupt" \ + "https://coder.example.com/api/experimental/chats/$CHAT_ID/interrupt" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" ``` Then confirm the chat status returns to `"waiting"`: ```sh -curl -s "https://coder.example.com/api/v2/chats/$CHAT_ID" \ +curl -s "https://coder.example.com/api/experimental/chats/$CHAT_ID" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '.status' ``` @@ -618,20 +618,20 @@ curl -s "https://coder.example.com/api/v2/chats/$CHAT_ID" \ ```sh # Archive curl -s -X PATCH \ - "https://coder.example.com/api/v2/chats/$CHAT_ID" \ + "https://coder.example.com/api/experimental/chats/$CHAT_ID" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"archived": true}' # Confirm it no longer appears in the default list -curl -s "https://coder.example.com/api/v2/chats" \ +curl -s "https://coder.example.com/api/experimental/chats" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ | jq --arg id "$CHAT_ID" '[.[] | select(.id == $id)] | length' # Should return 0 # Restore curl -s -X PATCH \ - "https://coder.example.com/api/v2/chats/$CHAT_ID" \ + "https://coder.example.com/api/experimental/chats/$CHAT_ID" \ -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"archived": false}'