diff --git a/services/www/src/docs/content/console/api/budgets.mdx b/services/www/src/docs/content/console/api/budgets.mdx new file mode 100644 index 000000000000..2d236164ef55 --- /dev/null +++ b/services/www/src/docs/content/console/api/budgets.mdx @@ -0,0 +1,98 @@ +--- +title: "Budgets API" +description: "Read effective monthly budgets for every workspace member and manage each member's custom budget." +--- + +Read effective monthly budgets for every workspace member and manage each member's custom budget from an integration. + +## Quick start + +Create a [service account](/console/api#service-accounts) API key with **All** permissions in the [Console](https://opencode.ai/console). +Inference-only keys cannot access budget data or change limits. + +```bash +export CONSOLE_URL="https://opencode.ai/console" +export SERVICE_API_KEY="oc_sk_..." +``` + +List member budgets: + +```bash +curl --fail-with-body \ + "${CONSOLE_URL}/api/v1/budgets/members" \ + --header "Authorization: Bearer ${SERVICE_API_KEY}" \ + --header "Accept: application/json" +``` + +## List member budgets + +```text +GET /api/v1/budgets/members +``` + +The response includes every current member, ordered by email. A limit with source `custom` is a member override; +source `default` is inherited from the workspace default. A null limit and source mean the member is unlimited. + +```json +[ + { + "user_id": "user_...", + "email": "alice@example.com", + "limit_micro_cents": "7525000000", + "spent_micro_cents": "1250000000", + "exceeded": false, + "resets_at": "2026-10-01T00:00:00.000Z", + "source": "custom", + "updated_at": "2026-09-03T12:00:00.000Z" + } +] +``` + +Monetary response fields are decimal strings in microcents so integrations do not lose precision. There are +100,000,000 microcents per US dollar. Spend and reset timestamps cover the current UTC calendar month. `updated_at` is +null when there is no custom member override. + +## Set a custom budget + +```text +PUT /api/v1/budgets/members/:user_id +``` + +Set a $75.25 monthly budget for one member: + +```bash +curl --fail-with-body --request PUT \ + "${CONSOLE_URL}/api/v1/budgets/members/user_..." \ + --header "Authorization: Bearer ${SERVICE_API_KEY}" \ + --header "Content-Type: application/json" \ + --data '{"budget_dollars":75.25}' +``` + +`budget_dollars` accepts a non-negative US-dollar amount with at most two decimal places. The PUT is idempotent and +returns HTTP 204. Use the member ID returned by the list operation. + +## Return to the workspace default + +```text +DELETE /api/v1/budgets/members/:user_id +``` + +Remove the custom override: + +```bash +curl --fail-with-body --request DELETE \ + "${CONSOLE_URL}/api/v1/budgets/members/user_..." \ + --header "Authorization: Bearer ${SERVICE_API_KEY}" +``` + +Deleting an override does not delete the member. The member inherits the workspace default budget afterward, or +becomes unlimited when the workspace has no default. Repeating the request is safe and returns HTTP 204. + +## Errors + +| Status | Meaning | +| ------ | -------------------------------------------------------- | +| `400` | Invalid member ID or budget amount. | +| `401` | Missing, invalid, expired, or revoked service API key. | +| `403` | The API key does not have permission to manage budgets. | +| `404` | The member is not in the workspace bound to the API key. | diff --git a/services/www/src/docs/content/console/api/index.mdx b/services/www/src/docs/content/console/api/index.mdx new file mode 100644 index 000000000000..ac9c07068ee8 --- /dev/null +++ b/services/www/src/docs/content/console/api/index.mdx @@ -0,0 +1,166 @@ +--- +title: "API Overview" +description: "Authenticate with the OpenCode Console API using service account keys or user tokens." +--- + +The Console API lets integrations read workspace configuration and manage budgets. Paths are relative +to the Console base URL. + +```bash +export CONSOLE_URL="https://opencode.ai/console" +export SERVICE_API_KEY="oc_sk_..." + +curl --fail-with-body "${CONSOLE_URL}/api/v2/config" \ + --header "Authorization: Bearer ${SERVICE_API_KEY}" +``` + +| API | Endpoints | +| ----------------------------------- | ------------------------------------------ | +| [Inference](/console/api/inference) | `https://opencode.ai/inference/...` | +| [Providers](/console/api/providers) | `https://opencode.ai/inference/custom/...` | +| [Budgets](/console/api/budgets) | `/api/v1/budgets/members` | +| [Config](#workspace-config) | `GET /api/v2/config` | + +## Service accounts + +Integrations authenticate with a service account: a non-human member of the workspace with its own API keys, usage, +and [budget](/console/budgets#service-account-budgets). Owners and admins manage them from **Keys**. + +1. Open **Keys** and click **Add Service Account**, then name it, for example `CI Pipeline`. +2. Open the service account and click **Add API Key**. +3. Choose a **Key name**, **Permissions**, and an optional **Expiry date**, then click **Create key**. +4. Copy the key. It is shown only once. + +```text +oc_sk_1a2b3c4d5e6f_... +``` + +Send the key as a bearer token. It is bound to one workspace, so no workspace header is needed. + +```text +Authorization: Bearer oc_sk_... +``` + +### Permissions + +| Permission | Allows | +| -------------- | --------------------------------------------------------------------------------------------------------------- | +| Inference only | [Inference](/console/api/inference) and [Providers](/console/api/providers) requests, and `GET /api/v2/config`. | +| All | Everything above, plus the Console API with admin access, except managing models. | + +Some actions always require a person signed in to the Console, even with an **All** key: inviting members, changing +roles, removing members, and creating or revoking keys. + +### Revoke keys + +Open the service account and revoke a key from **API Keys**. Removing the service account revokes all its keys. +Automations using a revoked or expired key get HTTP `401` immediately. + +## User tokens + +User tokens act as a signed-in person with their workspace role. Send the token with an `x-org-id` header naming the +workspace. + +```bash +curl --fail-with-body "${CONSOLE_URL}/api/v2/config" \ + --header "Authorization: Bearer ${USER_TOKEN}" \ + --header "x-org-id: org_..." +``` + +Tokens from the [device flow](#device-flow) are bound to the workspace chosen during sign-in and do not need the +header. A different `x-org-id` returns `403`. + +## Device flow + +OpenCode signs in with the OAuth device authorization grant (RFC 8628). Other CLIs can use the same flow. + +1. Request a device code. Send `supports_org_scope=true` to bind the token to a workspace. + + ```bash + curl --fail-with-body "${CONSOLE_URL}/auth/device/code" \ + --data "client_id=my-cli" \ + --data "supports_org_scope=true" + ``` + + The response includes `device_code`, `user_code`, `verification_uri_complete`, `expires_in` (600 seconds), and + `interval` (5 seconds). + +2. Open `verification_uri_complete` in a browser. It is a path such as `/console/device?user_code=...`, relative to + `https://opencode.ai`. The person signs in, picks a workspace, and approves. + +3. Poll for the token every `interval` seconds with the same `client_id`. + + ```bash + curl --fail-with-body "${CONSOLE_URL}/auth/device/token" \ + --data "grant_type=urn:ietf:params:oauth:grant-type:device_code" \ + --data "device_code=..." \ + --data "client_id=my-cli" + ``` + + Until approval the response is `400` with `authorization_pending`. On success it returns `access_token`, + `refresh_token`, `expires_in`, and `org_id`. + +4. Refresh before the access token expires. The workspace binding is preserved. + + ```bash + curl --fail-with-body "${CONSOLE_URL}/auth/device/token" \ + --data "grant_type=refresh_token" \ + --data "refresh_token=..." \ + --data "client_id=my-cli" + ``` + +Each refresh token can be used once. Reusing an old refresh token revokes the whole session. + +## Workspace config + +`GET /api/v2/config` returns the providers and models available to the workspace in the OpenCode V2 +[config](/config) format. OpenCode loads it after `/connect`. + +```bash +curl --fail-with-body "${CONSOLE_URL}/api/v2/config" \ + --header "Authorization: Bearer ${SERVICE_API_KEY}" +``` + +```json +{ + "providers": { + "opencode": { + "name": "OpenCode", + "env": ["OPENCODE_CONSOLE_TOKEN"], + "package": "aisdk:@ai-sdk/openai-compatible", + "settings": { + "baseURL": "https://opencode.ai/inference/openai/v1", + "apiKey": "{env:OPENCODE_CONSOLE_TOKEN}" + }, + "headers": { "x-opencode-org-id": "org_..." }, + "models": { + "kimi-k2.6": { "name": "Kimi K2.6" } + } + } + } +} +``` + +| Field | Description | +| ----------------------- | -------------------------------------------------------------------------------- | +| `providers` | Console, Go, and connected providers, each with its gateway settings and models. | +| `websearch` | Hosted [web search](/console/websearch), for members when enabled. | +| `mcp` | The Console MCP server, for members. | +| `experimental.policies` | Workspace [policy](/policies#console) statements. | + +Every key permission level and member role can read the config. + +## Errors + +Errors return JSON with a `_tag` naming the error. + +```json +{ "_tag": "Forbidden" } +``` + +| Status | Meaning | +| ------ | ---------------------------------------------------------------------------------------- | +| `400` | `OrgRequired`: a user token was sent without `x-org-id`. | +| `401` | Missing, invalid, expired, or revoked credential. | +| `403` | Wrong workspace, missing permission, or an **Inference only** key on a Console endpoint. | +| `404` | The workspace does not exist or was deleted. | diff --git a/services/www/src/docs/content/console/inference.mdx b/services/www/src/docs/content/console/api/inference.mdx similarity index 95% rename from services/www/src/docs/content/console/inference.mdx rename to services/www/src/docs/content/console/api/inference.mdx index f119838e1201..e5f2cae01925 100644 --- a/services/www/src/docs/content/console/inference.mdx +++ b/services/www/src/docs/content/console/api/inference.mdx @@ -18,7 +18,7 @@ curl -X POST "https://opencode.ai/inference/openai/v1/chat/completions" \ ## Authentication -Replace `` with a service account key created in the [Console](https://opencode.ai/console). Paid models +Replace `` with a [service account key](/console/api#service-accounts) created in the [Console](https://opencode.ai/console). Paid models require the header; free chat models can be called without it. ```text diff --git a/services/www/src/docs/content/console/byok.mdx b/services/www/src/docs/content/console/api/providers.mdx similarity index 55% rename from services/www/src/docs/content/console/byok.mdx rename to services/www/src/docs/content/console/api/providers.mdx index f364e0b430e2..8850096d3666 100644 --- a/services/www/src/docs/content/console/byok.mdx +++ b/services/www/src/docs/content/console/api/providers.mdx @@ -1,11 +1,11 @@ --- -title: "BYOK" -description: "Call your own provider connections through the Console gateway with a Console key." +title: "Providers API" +description: "Call the providers connected to your workspace through the Console gateway with a Console key." --- -Bring your own key (BYOK) connects a provider account you already pay for to your workspace. Console stores the -provider credential and gives each connection one gateway URL. Members and integrations call that URL with a Console -key and never handle the provider secret. +Every [provider](/console/providers) connected to your workspace is served through the Console gateway at its own +URL. OpenCode uses it automatically after `/connect`; call it directly to use the same providers from your own tools. +Console adds the provider credential before forwarding, so the provider secret never leaves the workspace. ```bash curl -X POST "https://opencode.ai/inference/custom/conn_.../chat/completions" \ @@ -17,29 +17,18 @@ curl -X POST "https://opencode.ai/inference/custom/conn_.../chat/completions" \ }' ``` -## Connect a provider +## Provider URL -1. In the [Console](https://opencode.ai/console), open **Providers** and click **Connect Provider**. -2. Pick a provider from the catalog and paste its API key, or click **Add Custom Provider** for any other endpoint. -3. Copy the **Console API URL** from the provider page. +Copy the **Console API URL** from the provider's page under **Providers**. ```text https://opencode.ai/inference/custom/ ``` -Catalog providers come with their models preconfigured. Custom providers need a few more fields: - -| Field | Description | -| ---------- | --------------------------------------------------------------------------------- | -| Base URL | Where Console forwards requests, for example `https://api.deepseek.com/v1`. | -| API schema | Chat Completions, Responses API, Anthropic Compatible, or Google Generative AI. | -| Auth mode | Bearer, API key header, or Custom header, plus the credential to send. | -| Models | The model IDs members can request, with optional pricing used for usage tracking. | - ## Authentication -Replace `` with a service account key created in Console. Console swaps it for the connection's credential -before forwarding, so the provider secret stays in the workspace. +Replace `` with a [service account key](/console/api#service-accounts) created in Console. Console swaps it for +the connection's credential before forwarding. ```text Authorization: Bearer @@ -53,7 +42,7 @@ Console API URL. Append the provider's API path to the Console API URL. Console forwards the request to the connection's base URL and returns the provider response unchanged. -| API schema | Path | +| Format | Path | | -------------------- | --------------------------------- | | Chat Completions | `/chat/completions` | | Responses API | `/responses` | @@ -116,16 +105,7 @@ curl -X POST "https://opencode.ai/inference/custom/conn_.../models/gemini-3.1-pr }' ``` -## Use in OpenCode - -Members do not need the gateway URL. Connections appear as providers in OpenCode for everyone who connects to the -workspace with `/connect`, and `/models` lists their enabled models. - -```text -/connect -``` - -## Usage and limits +## Usage -The provider bills you for the tokens. Console records every request and, using the pricing configured on the model, -counts it toward workspace and member monthly limits. +Requests count toward [budgets](/console/budgets) using the pricing set on each model. The provider +bills you for the tokens. diff --git a/services/www/src/docs/content/console/billing.mdx b/services/www/src/docs/content/console/billing.mdx new file mode 100644 index 000000000000..5b70a55a714e --- /dev/null +++ b/services/www/src/docs/content/console/billing.mdx @@ -0,0 +1,84 @@ +--- +title: "Billing" +description: "Add credits, set up auto-recharge, manage payment methods, and download invoices in OpenCode Console." +--- + +Console is free for any team size, with no seat fees. You pay only for usage, from prepaid credits that cover the +whole workspace. Owners and admins manage billing in **Settings › Billing**. + +Usage through [your own providers](/console/providers) is billed by the provider, not by Console. + +## Add a payment method + +1. Open **Settings › Billing**. +2. Under **Payment methods**, click **Add**. +3. Choose a method and finish the Stripe setup. + +Supported payment methods: + +- Card +- Link +- Alipay +- UPI +- WeChat Pay + +Use **⋯ › Make default** to choose the method for automatic charges. Removing a method can stop auto-recharge and Go +renewals that use it. + +## Add credits + +1. Under **Credits**, click **Add credits**. +2. Pick $10, $50, or $100, or choose **Other** and enter an amount. +3. Choose a payment method and click **Confirm and pay**. + +A processing fee of 4.6% + $0.31 is added on top, so a $50 purchase costs $52.61 and the full $50 is added to the +balance. + +## Auto-recharge + +Auto-recharge buys credits when the balance runs low. + +1. Under **Auto-recharge**, click **Add rule**. +2. Set the balance that triggers a charge and the amount to add. +3. Click **Save**. + +Auto-recharge charges the default payment method, including the processing fee. If a charge fails, auto-recharge +turns off until you set it up again. + +## Check your balance + +The **Credits** card on **Overview** shows the balance for owners and admins. + +## When credits run out + +Paid requests fail with HTTP `402` once the balance reaches zero. The balance never goes negative. + +```text +Upstream request failed: Insufficient account funds +``` + +## Invoices + +Every payment appears under **Invoices** with its status and a link to **Download invoice** or **View receipt**. + +| Entry | Created by | +| ---------------- | ------------------ | +| Balance top-up | Adding credits | +| Automatic top-up | Auto-recharge | +| Go subscription | Subscribing to Go | +| Go renewal | Monthly Go renewal | +| Monthly Usage | Invoiced billing | + +## Invoiced billing + +Workspaces with a credit agreement can be invoiced monthly instead of buying credits. Contact support to set it up. + +- Usage draws on a credit limit instead of a prepaid balance. +- The invoice for each month is issued on the 1st (UTC) and is due 14 days later. +- Open invoices have a **Pay now** button. +- Requests fail with HTTP `402` when the credit limit is reached or an invoice is overdue. + +## Go + +[OpenCode Go](/console/go) subscriptions use the same payment methods and appear in the same invoice list. Turn on +**Extra usage** on the **Overview** credits card to pay from credits once a Go limit is reached. diff --git a/services/www/src/docs/content/console/budgets.mdx b/services/www/src/docs/content/console/budgets.mdx index 0e0ec33e5148..3dc446a5d1a1 100644 --- a/services/www/src/docs/content/console/budgets.mdx +++ b/services/www/src/docs/content/console/budgets.mdx @@ -1,98 +1,86 @@ --- -title: "Budgets API" -description: "Read effective monthly budgets for every workspace member and manage each member's custom budget." +title: "Budgets" +description: "Cap monthly spend for a workspace, its members, and its service accounts." --- -Read effective monthly budgets for every workspace member and manage each member's custom budget from an integration. +Budgets cap how much a workspace spends each month. Owners and admins set them from the **Budget limits** panel on +the **Members** and **Keys** pages. -## Quick start +## Budget levels -Create a service account API key with **All** permissions in the [Console](https://opencode.ai/console). -Inference-only keys cannot access budget data or change limits. +| Budget | Applies to | Where to set it | +| ----------------------- | ------------------------------------------- | -------------------------------------------------- | +| Workspace | Combined spend of everyone in the workspace | **Members** or **Keys › Monthly workspace budget** | +| Default user | Each member without a custom limit | **Members › Monthly default user budget** | +| Custom user | One member | **Members** table or member page | +| Default service account | Each service account without a custom limit | **Keys › Monthly default service account budget** | +| Custom service account | One service account | Service account page | -```bash -export CONSOLE_URL="https://opencode.ai/console" -export SERVICE_API_KEY="oc_sk_..." -``` +A request must fit under both the workspace budget and the person's own budget. Without any budget, spend is +unlimited. -List member budgets: +## Workspace budget -```bash -curl --fail-with-body \ - "${CONSOLE_URL}/api/v1/budgets/members" \ - --header "Authorization: Bearer ${SERVICE_API_KEY}" \ - --header "Accept: application/json" -``` +The workspace budget blocks requests for everyone once the workspace reaches it. -## List member budgets +1. Open **Members** or **Keys**. +2. In **Budget limits**, click **Monthly workspace budget**. +3. Enter a **Workspace limit** in USD and click **Save**. -```text -GET /api/v1/budgets/members -``` +## Member budgets -The response includes every current member, ordered by email. A limit with source `custom` is a member override; -source `default` is inherited from the workspace default. A null limit and source mean the member is unlimited. - -```json -[ - { - "user_id": "user_...", - "email": "alice@example.com", - "limit_micro_cents": "7525000000", - "spent_micro_cents": "1250000000", - "exceeded": false, - "resets_at": "2026-10-01T00:00:00.000Z", - "source": "custom", - "updated_at": "2026-09-03T12:00:00.000Z" - } -] -``` +The default user budget applies to every member who has no custom limit. Set it under **Monthly default user budget**. -Monetary response fields are decimal strings in microcents so integrations do not lose precision. There are -100,000,000 microcents per US dollar. Spend and reset timestamps cover the current UTC calendar month. `updated_at` is -null when there is no custom member override. +Give one member a custom limit from either place: -## Set a custom budget +- Click the **Limit** cell in their **Members** row and enter an amount. +- Open the member and click **Set User Budget** under **Monthly Budget**. -```text -PUT /api/v1/budgets/members/:user_id -``` +Custom limits are highlighted in the Members table. Clear a custom limit to return the member to the default; the +member page then shows **Using Default**. -Set a $75.25 monthly budget for one member: +## Service account budgets -```bash -curl --fail-with-body --request PUT \ - "${CONSOLE_URL}/api/v1/budgets/members/user_..." \ - --header "Authorization: Bearer ${SERVICE_API_KEY}" \ - --header "Content-Type: application/json" \ - --data '{"budget_dollars":75.25}' -``` +Service accounts work the same way. Set **Monthly default service account budget** on the **Keys** page, or open a +service account and click **Set Service Account Budget**. + +## Amounts and resets + +- Amounts are in US dollars with up to two decimal places. +- Budgets reset on the 1st of each month at 00:00 UTC. +- A `$0` budget blocks all spend that counts toward budgets. + +## What counts -`budget_dollars` accepts a non-negative US-dollar amount with at most two decimal places. The PUT is idempotent and -returns HTTP 204. Use the member ID returned by the list operation. +| Spend | Counts toward budgets | +| ------------------------------------------------------------------- | ---------------------------- | +| Paid Console models | Yes | +| Models on [your own providers](/console/providers) with a price set | Yes, at the configured price | +| [Web search](/console/websearch) | Yes | +| Free models | No | +| [Go](/console/go) usage within the plan | No | +| Go extra usage paid from credits | Yes | -## Return to the workspace default +## When a budget is reached + +New requests fail with HTTP `429` until the budget resets or an admin raises it. The response does not say which +budget was reached. ```text -DELETE /api/v1/budgets/members/:user_id +Upstream request failed: Account budget exceeded ``` -Remove the custom override: +Budgets are checked when a request starts. Requests already in progress finish, so spend can end slightly above the +limit. -```bash -curl --fail-with-body --request DELETE \ - "${CONSOLE_URL}/api/v1/budgets/members/user_..." \ - --header "Authorization: Bearer ${SERVICE_API_KEY}" -``` +## Track spend + +Each member sees their own budget on **Overview**: the amount left, the amount spent, and the reset date. -Deleting an override does not delete the member. The member inherits the workspace default budget afterward, or -becomes unlimited when the workspace has no default. Repeating the request is safe and returns HTTP 204. +Owners and admins of workspaces with more than one member also see **Usage**. It breaks down cost by day, model, and +person, and the **Export usage** button downloads daily totals for the last 7, 30, or 90 days as CSV. -## Errors +## Automate budgets -| Status | Meaning | -| ------ | -------------------------------------------------------- | -| `400` | Invalid member ID or budget amount. | -| `401` | Missing, invalid, expired, or revoked service API key. | -| `403` | The API key does not have permission to manage budgets. | -| `404` | The member is not in the workspace bound to the API key. | +Use the [Budgets API](/console/api/budgets) to read every member's budget and set custom limits from your own +tools. diff --git a/services/www/src/docs/content/console/go.mdx b/services/www/src/docs/content/console/go.mdx index 8712852f7606..c9c303241d0b 100644 --- a/services/www/src/docs/content/console/go.mdx +++ b/services/www/src/docs/content/console/go.mdx @@ -5,9 +5,9 @@ description: "Reliable access to open coding models with two usage tiers." OpenCode Go gives you reliable access to popular open coding models, with two monthly plans: -| Plan | Price | Included usage | -| ---- | ----- | -------------- | -| **Go** | **$10/month** | Lower-cost access to the models below | +| Plan | Price | Included usage | +| ----------- | ------------- | ------------------------------------------- | +| **Go** | **$10/month** | Lower-cost access to the models below | | **Go Plus** | **$40/month** | Higher usage limits across the models below | Go works like any other provider in OpenCode. You subscribe to OpenCode Go and get your API key. It's **completely optional** and you don't need it to use OpenCode. @@ -29,7 +29,10 @@ The service is designed primarily for international users and provides stable gl /models ``` -Only one member per workspace can subscribe to OpenCode Go or Go Plus. + + Go and Go Plus are for workspaces with a single member, such as the **Personal** workspace created when you sign up. A + workspace with a Go subscription cannot invite members. + The current list of models includes: @@ -66,7 +69,6 @@ The current list of models includes: The list of models may change as we test and add new ones. - ## Where can I use it? OpenCode Go is designed for [OpenCode](https://opencode.ai) and other coding agents @@ -343,7 +345,6 @@ If you also have credits in your Console balance, you can enable the **Use balan option in the console. When enabled, Go will fall back to your [pay-as-you-go balance](/console/models#pricing) after you've reached your usage limits instead of blocking requests. - ### Why some models have lower usage With Go, the included monthly usage varies by model. diff --git a/services/www/src/docs/content/console/index.mdx b/services/www/src/docs/content/console/index.mdx index 7903e91fb47e..43988b1c82a0 100644 --- a/services/www/src/docs/content/console/index.mdx +++ b/services/www/src/docs/content/console/index.mdx @@ -3,14 +3,29 @@ title: "Intro" --- The [OpenCode Console](https://opencode.ai/console) is an optional service that provides additional benefits to -using OpenCode particularly as a team +using OpenCode, on your own or as a team. -- Inference for both proprietary and open source models -- LLM Gateway for connecting your own providers -- Usage tracking and budget controls +- [Workspaces](/console/workspaces) for sharing access with your [team](/console/members) +- [Inference](/console/models) for both proprietary and open source models +- [Providers](/console/providers) for connecting your own provider accounts through the Console gateway +- Usage tracking and [budget](/console/budgets) controls - Deploy team wide policies to control OpenCode behavior -- Web search -- OpenCode Go, $10 subscription for open source model access +- [Web search](/console/websearch) +- [OpenCode Go and Go Plus](/console/go), $10 and $40 monthly subscriptions for open source model access + +## Get started + +You don't need a team to use the Console. Every account starts with a **Personal** workspace where you are the only +member. + +1. Sign in to the [Console](https://opencode.ai/console). +2. Subscribe to [Go](/console/go), add [credits](/console/billing#add-credits), or connect a [provider](/console/providers). +3. Run `/connect` in OpenCode and choose the workspace. +4. Optionally, [invite](/console/members#invite-members) your team. + +```text +/connect +``` ## Policies diff --git a/services/www/src/docs/content/console/members.mdx b/services/www/src/docs/content/console/members.mdx new file mode 100644 index 000000000000..b095deb1e412 --- /dev/null +++ b/services/www/src/docs/content/console/members.mdx @@ -0,0 +1,67 @@ +--- +title: "Members" +description: "Invite people to an OpenCode Console workspace, manage their roles, and remove them." +--- + +Owners and admins manage people from the **Members** page. Each row shows the member's role, join date, monthly +usage, and budget limit. + +## Invite members + +1. Open **Members** and click **Invite Members**. +2. Add one or more email addresses. Separate them with spaces, commas, or semicolons, or paste a list. +3. Click **Send invitations**. + +Each person receives an email titled **Join Acme Inc. on OpenCode** with a **Join workspace** button. + +Invitations expire after 7 days. Everyone joins as **Member**; [change their role](#change-a-role) after they join. + + + Workspaces with an [OpenCode Go](/console/go) subscription cannot invite members. Create a separate workspace for your + team. + + +Members can also join automatically: + +- [SSO](/console/sso#automatic-membership) adds people on your verified email domains when they first sign in. +- [Directory sync](/console/scim) adds and removes people as you assign them in your identity provider. + +## Accept an invitation + +The invitee must sign in with the email address the invitation was sent to. There are two ways to accept: + +- Click **Join workspace** in the invitation email, then sign in or create an account. +- Sign in to the Console, open the workspace menu, and click **Join** under **Pending invitations**. + +If they are signed in with a different account, Console asks them to **Sign out and continue** with the invited email. + +## Manage pending invitations + +Pending invitations appear in the Members table as **Pending · Expires** followed by the date, or **Expired**. + +| Action | How | +| ------ | ----------------------------------------------------------------------------------------- | +| Resend | **⋯ › Resend invitation**. Sends a new link valid for 7 days; the old link stops working. | +| Revoke | **⋯ › Remove...**. The link stops working immediately. | + +## Change a role + +Open the role menu in a member's row and pick **Member**, **Admin**, or **Owner**. + +You can only grant roles up to your own, and the workspace always keeps at least one owner. See +[Roles](/console/workspaces#roles). + +## Remove a member + +1. Click **⋯ › Remove...** in the member's row. +2. Confirm with **Remove member**. + +Access is revoked immediately, and you can invite them again later. Their past usage stays in the workspace's reports. + +Service accounts and their API keys belong to the workspace, so removing the member who created them does not revoke +them. Revoke keys from **Keys** if needed. See [Service accounts](/console/api#service-accounts). + +## Member details + +Click a member to see their monthly budget, models and clients they use, usage charts, and request logs. From here +you can set their [budget](/console/budgets#member-budgets) and export their usage as CSV. diff --git a/services/www/src/docs/content/console/models.mdx b/services/www/src/docs/content/console/models.mdx index ca8825172f46..a6e66de8caad 100644 --- a/services/www/src/docs/content/console/models.mdx +++ b/services/www/src/docs/content/console/models.mdx @@ -381,33 +381,9 @@ For subscription models, see [Go privacy](/console/go#privacy). ## For teams -You can invite teammates, assign roles, and curate the models your team uses. - - - Managing workspaces is currently free for teams as part of the beta. More pricing details will be shared later. - - -### Roles - -Invite teammates to your workspace and assign roles: - -- **Admin:** Manage models, members, API keys, and billing. -- **Member:** Manage only their own API keys. - -Admins can also set monthly spending limits for each member to keep costs under control. - -### Model access - -Admins can enable or disable specific models for the workspace. Requests made to a disabled model return an error. - -For example, you can disable a model that collects data so members of your workspace cannot use it. - -### Bring your own key - -You can use your own OpenAI or Anthropic API keys while still accessing other models through Console. Tokens used -with your own keys are billed directly by the provider. - -For example, if your organization already has an OpenAI API key, you can use it instead of the one Console provides. +Share Console models with your team from a [workspace](/console/workspaces). Owners and admins can +[invite members](/console/members), choose which models are enabled from the **Models** tab, set +[budgets](/console/budgets), and connect [their own providers](/console/providers). ## Background diff --git a/services/www/src/docs/content/console/providers.mdx b/services/www/src/docs/content/console/providers.mdx new file mode 100644 index 000000000000..ca0e4004aad5 --- /dev/null +++ b/services/www/src/docs/content/console/providers.mdx @@ -0,0 +1,124 @@ +--- +title: "Providers" +description: "Connect your own model provider accounts to an OpenCode Console workspace and choose which models members can use." +--- + +Connect provider accounts you already pay for, such as Anthropic, OpenAI, or AWS Bedrock, and share their models +with everyone in the workspace. Console stores the credential and serves each provider through its gateway, so members +use the models without ever seeing the provider key. The same gateway is available to your own tools through the +[Providers API](/console/api/providers). + +Owners and admins manage providers from the **Providers** tab. Members get the enabled models in OpenCode after +running `/connect`. + +## Connect a provider + +1. Open **Providers** and click **Connect Provider**. +2. Pick a provider from the catalog and enter its API key. +3. Optionally click **Test connection**, then click **Save**. + +The catalog includes Anthropic, OpenAI, Google, xAI, DeepSeek, Mistral, Groq, OpenRouter, and many more. Catalog +providers come with their models preconfigured. + +### Cloud providers + +Cloud providers need a few extra details. + +| Provider | Details | +| --------------------- | ------------------------------------- | +| Azure | Resource name and API key | +| AWS Bedrock | Region and API key | +| Google Vertex AI | Region and service account JSON | +| Cloudflare AI Gateway | Account ID, Gateway ID, and API token | +| Databricks | Workspace URL and token | + +### Custom providers + +Click **Add Custom Provider** to connect any other endpoint, then add its models with **Add Model**. + +| Field | Description | +| ---------- | ------------------------------------------------------------------------------- | +| Base URL | Where Console forwards requests, for example `https://api.deepseek.com/v1`. | +| Format | Chat Completions, Responses API, Anthropic Compatible, or Google Generative AI. | +| Auth mode | Bearer, API key header, or Custom header. | +| Credential | The key Console sends to the provider. | + +## Choose models + +Open a provider to see its models. Only enabled models are available to members. + +- Use the **Enabled** toggle to turn a model on or off. +- Turn on **New models** to enable models the provider adds in the future. + +## Edit models + +Click a model to edit it. Changes are saved when you close the panel. + +| Section | What you can change | +| ------------- | --------------------------------------------------------------- | +| General | Display name, API ID, tools support, input and output types | +| Variants | Variants with their own headers or body | +| Configuration | Default variant, request headers and body, token limits | +| Cost Tiers | Input, output, cache read, and cache write prices per 1M tokens | + +### Custom pricing + +Catalog models start with the provider's list price. If you have negotiated pricing, for example a discount on your +OpenAI contract, override the prices under **Cost Tiers** so usage reports and [budgets](/console/budgets) match what +you actually pay. + +| Field | List price | Your price | +| ---------------- | ---------- | ---------- | +| Input price | $2.50 | $2.00 | +| Output price | $15.00 | $12.00 | +| Cache read price | $0.25 | $0.20 | + +Prices you change are highlighted on the provider page. Use **Restore default value** on a field, or **⋯ › Restore...** +on the model, to return to the list price. + +Add a **Context** tier when a model charges more above a context size, for example for prompts over 200K tokens. + +### Custom models + +Click **Add Model** to add a model the catalog doesn't include, with its **Display name** and **Model ID**. Use +**⋯ › Duplicate...** on an existing model to start from its settings. + +## OpenCode models + +The **Models** tab manages the [models](/console/models) Console provides, which are paid from workspace credits. It +works like a provider page: + +- Turn individual models on or off. +- Turn **Free models** off to block free models for the workspace. +- Turn **New models** on to enable new Console models automatically. + +Disable the whole provider from **⋯ › Disable** to use only your own providers. + +## Use in OpenCode + +Members run `/connect` and choose the workspace. Each enabled provider appears as the workspace name followed by the +provider name, and `/models` lists its enabled models. + +```text +Acme Inc. / Anthropic +``` + +Turn on **Managed providers only** in **Settings › General** to restrict OpenCode to the workspace's providers for +everyone. + +## Disable or remove + +Open the provider's **⋯** menu: + +- **Disable** hides the provider and its models from members but keeps its settings. +- **Remove...** deletes the provider and its models. The dialog shows who used it recently, and offers + **Disable instead**. + +To rotate a key, click the credential on the provider page and enter the new one. + +## Billing + +The provider bills you for tokens; Console does not charge credits for them. Console still records each request and +its cost using the model's pricing, so usage reports and [budgets](/console/budgets) include it. + +To call a provider from your own tools instead of OpenCode, use the [Providers API](/console/api/providers). diff --git a/services/www/src/docs/content/console/scim.mdx b/services/www/src/docs/content/console/scim.mdx new file mode 100644 index 000000000000..82b5c66f147a --- /dev/null +++ b/services/www/src/docs/content/console/scim.mdx @@ -0,0 +1,91 @@ +--- +title: "Directory Sync" +description: "Add and remove workspace members automatically from Okta, Microsoft Entra ID, or any SCIM 2.0 identity provider." +--- + +Directory sync (SCIM 2.0) adds people to the workspace when you assign them in your identity provider, and removes +their access when you unassign them. Roles stay managed in the Console. + +```text +https://opencode.ai/console/scim/v2 +``` + +## Before you start + +- Set up [SSO](/console/sso) for the workspace. +- [Verify](/console/sso#verify-email-domains) every email domain your people sign in with. Directory sync only adds + people on a verified domain; invite anyone else from [Members](/console/members). + +## Create a token + +1. Open **Settings › Security** and click **Set up** under **Directory sync**. +2. Copy the **SCIM base URL** and the token. The token is shown only once, so store it in a secrets manager. + +Your identity provider sends the token on every request. + +```text +Authorization: Bearer +``` + +## Connect your identity provider + +### Okta + +1. Add the **SCIM 2.0 Test App (Header Auth)** app. +2. Set the base URL, and enter `Bearer ` followed by the token in **API Token**. +3. Enable **Create Users**, **Update User Attributes**, and **Deactivate Users**. Leave **Import Groups** and password + sync off. + +### Microsoft Entra ID + +1. In your enterprise app, open **Provisioning** and set the mode to **Automatic**. +2. Enter the base URL as **Tenant URL** and the token as **Secret Token**. +3. Assign users and groups, then start provisioning. + +### Other providers + +Use a SCIM 2.0 app with header token authentication, pointed at the base URL. Console supports the `/Users` and +`/Groups` endpoints. + +Assign one test person first. **Directory sync** shows **Connected to your identity provider** after the first +request. + +## What syncs + +| In your identity provider | In the Console | +| ------------------------- | --------------------------------------------------------------------------------- | +| Assign a person | Added as **Member**. Existing members keep their role. | +| Update a name | Profile updated. | +| Unassign or deactivate | Access suspended and shown as **Deactivated**. API keys they created are revoked. | +| Reassign | Access restored. Revoked keys stay revoked. | +| Delete | Removed from the workspace. Their account and other workspaces are unaffected. | + +- Roles and email addresses are not changed by directory sync. +- The last owner cannot be deactivated or deleted. +- Workspaces with a [Go](/console/go) subscription cannot add members through directory sync. + +## Groups + +Push groups to tag their members, for example with Okta **Push Groups** or Entra group assignment. Assign the people +before pushing their groups. + +```text +Platform Admins → platform-admins +``` + +Each group tags its members with a tag named after the group. Under **Settings › Security › Group tags** you can +rename a tag, point several groups at one tag, or stop tagging a group. Leaving a group removes its tag. + +## Rotate the token + +1. Click **New token** and install it in your identity provider. +2. Wait until the new token shows a last use. +3. Revoke the old token. + +Revoking a token stops future updates but does not change existing members. Deleting the SSO connection revokes all +tokens. + +## SSO and directory sync + +Once a workspace has issued a token, SSO no longer [adds members automatically](/console/sso#automatic-membership). +The directory decides who belongs, even if the token is later revoked. diff --git a/services/www/src/docs/content/console/sso.mdx b/services/www/src/docs/content/console/sso.mdx new file mode 100644 index 000000000000..686fb363fbfd --- /dev/null +++ b/services/www/src/docs/content/console/sso.mdx @@ -0,0 +1,91 @@ +--- +title: "SSO" +description: "Sign in to an OpenCode Console workspace through your identity provider with OIDC or SAML." +--- + +Single sign-on (SSO) sends workspace members through your company's identity provider when they sign in. Owners and +admins set it up in **Settings › Security**, and it's included with every workspace. + +| Protocol | Providers | +| -------------- | -------------------------------------------------------------------------------------- | +| OpenID Connect | Google Workspace, Microsoft Entra ID, Okta, Auth0, Ping Identity, or any OIDC provider | +| SAML 2.0 | Google Workspace, Microsoft Entra ID, Okta, or any SAML provider | + +Each workspace has one SSO connection. + +## Set up OIDC + +1. Open **Settings › Security**, click **Configure SSO**, and choose **OpenID Connect** and your provider. +2. Create an app in your provider by following the steps shown, with the `openid`, `email`, and `profile` scopes. +3. Enter the **Issuer URL**, or your tenant or domain, plus the **Client ID**, **Client Secret**, and a + **Display Name**, then click **Save**. +4. Copy the **Callback URL** from the connection into your provider's allowed redirect URIs. + +```text +https://opencode.ai/console/auth/sso/ssoconn_.../callback +``` + +Console checks that the issuer is reachable when you save. SSO is active as soon as the connection is saved. + +## Set up SAML + +1. Open **Settings › Security**, click **Configure SSO**, and choose **SAML 2.0** and your provider. +2. Copy the **ACS URL** and **SP Entity ID** into your provider. Custom providers can use the **SP Metadata URL** or + download the XML instead. +3. Add your provider's metadata by URL, XML upload, or paste. You can also enter the **IdP Entity ID**, **IdP SSO + URL**, and **IdP Certificate** by hand. +4. Review the details and click **Activate SSO**. + +```text +ACS URL: https://opencode.ai/console/auth/sso/ssoconn_.../callback +SP Entity ID: https://opencode.ai/console/auth/sso/ssoconn_.../metadata +``` + +Your provider must sign the response or the assertion, and send the user's email as an `email` attribute or as the +NameID. + +## Verify email domains + +People who sign in to the [Console](https://opencode.ai/console) with an email on a verified domain are sent to your +identity provider. Once SSO is active, click **Add domain** under **Email domains**, enter your domain, and publish +the TXT record shown. + +```text +Name: _opencode-console-challenge.example.com +Type: TXT +Value: oc-verify=... +``` + +Click **Verify Domain** once the record is published. DNS changes can take a while to propagate. Each domain can +belong to only one workspace. + +## SSO enforcement + +Once a workspace has SSO, admins and members must sign in through it to open the workspace, and Console redirects +them automatically. Connecting OpenCode with `/connect` follows the same rule. + +Owners can also sign in without SSO, so a misconfigured provider cannot lock the workspace out of its settings. + +## Automatic membership + +People on a verified domain join the workspace as **Member** the first time they sign in through SSO. They are not +added automatically when: + +- They have a pending invitation. The invitation is used instead. +- The workspace uses [directory sync](/console/scim), which decides membership. +- The workspace has a [Go](/console/go) subscription. + +Invitations to an SSO workspace send the invitee to your identity provider when they open the link. + +## Existing accounts + +If someone already has a Console account with the same email, Console asks them to sign in to it once to link SSO. +Invited people and people added by directory sync are linked automatically. + +## Edit or delete + +Click **Edit** on the connection to change its details. Leave the secret or certificate blank to keep the current +one. To switch between OIDC and SAML, delete the connection and create a new one. + +Delete the connection from **⋯ › Delete...**. Members go back to their other sign-in methods, and directory sync stops +with its tokens revoked. Email domains are kept. diff --git a/services/www/src/docs/content/console/websearch.mdx b/services/www/src/docs/content/console/websearch.mdx index f16db32eb709..68bfea8f3a6a 100644 --- a/services/www/src/docs/content/console/websearch.mdx +++ b/services/www/src/docs/content/console/websearch.mdx @@ -1,9 +1,9 @@ --- -title: "Websearch" -description: "Hosted websearch for OpenCode through Console." +title: "Web Search" +description: "Hosted web search for OpenCode through Console." --- -Console provides hosted Websearch to connected OpenCode v2 users. A workspace owner or admin enables it once for the workspace, without giving members a separate search provider key. +Console provides hosted web search to connected OpenCode v2 users. A workspace owner or admin enables it once for the workspace, without giving members a separate search provider key. Each successful search costs **$0.01** and counts toward the workspace balance and member spending limits. @@ -37,8 +37,8 @@ See the [Websearch guide](/websearch) to configure permissions or disable the to Console charges **$0.01** after a search returns a valid result set. Failed and rate-limited searches are not charged. -Websearch appears separately from model usage in **Usage**, **My Activity**, member activity, invoices, and CSV exports. Workspace and member monthly spending limits include Websearch charges. +Web search appears separately from model usage in **Usage**, **My Activity**, member activity, invoices, and CSV exports. Workspace and member monthly spending limits include web search charges. ## Privacy -Hosted Websearch has zero data retention. Console and its hosted search provider process each query and its results without storing their contents. +Hosted web search has zero data retention. Console and its hosted search provider process each query and its results without storing their contents. diff --git a/services/www/src/docs/content/console/workspaces.mdx b/services/www/src/docs/content/console/workspaces.mdx new file mode 100644 index 000000000000..460e5cac4d8e --- /dev/null +++ b/services/www/src/docs/content/console/workspaces.mdx @@ -0,0 +1,87 @@ +--- +title: "Basics" +description: "Create, switch, rename, and delete OpenCode Console workspaces, and understand member roles." +--- + +A workspace holds everything in the [Console](https://opencode.ai/console): members, credits, budgets, providers, +policies, and service accounts. Usage and billing are tracked per workspace. + +A workspace can have a single member. You can use credits, [your own providers](/console/providers), budgets, and [Go](/console/go) on your own, +and [invite members](/console/members) only when you need to. + +## Your first workspace + +Console creates a workspace named **Personal** when you sign up, with you as its owner and only member. If you sign +up from an invitation, you join the inviting workspace instead and no Personal workspace is created. + +## Create a workspace + +1. Open the workspace menu in the top bar. +2. Click **Create Workspace**. +3. Enter a **Workspace name** and click **Create**. + +You become the owner of the new workspace. + +## Switch workspaces + +Pick another workspace from the workspace menu. Console keeps you on the same page, so switching from +`/acme/members` opens the other workspace's Members page. + +Pending invitations appear at the top of the same menu. See [Members](/console/members#accept-an-invitation). + +## Connect OpenCode + +Run `/connect` in OpenCode and choose the workspace in the browser. OpenCode then uses that workspace's models, +policies, and budgets. + +```text +/connect +``` + +Run `/connect` again to switch OpenCode to another workspace. Workspace [policies](/policies#console) are replaced +with the new workspace's, and cleared when you disconnect. + +## Roles + +Every member has one role. New members always join as **Member**. + +| Role | Can do | +| ------ | -------------------------------------------------------------------------------------------------------------------- | +| Member | Use OpenCode, see their own usage, logs, and budget. | +| Admin | Everything a member can, plus manage members, billing, budgets, providers, policies, service accounts, and settings. | +| Owner | Everything an admin can, plus grant the Owner role and delete the workspace. | + +Members only see **Overview**, **Logs**, **Leaderboard** when it is visible to members, and **Settings › Account**. + +### Role rules + +- A workspace can have several owners, and always keeps at least one. +- You cannot assign a role higher than your own, so only owners can make someone an owner. +- You cannot change your own role. + +### Transfer ownership + +1. As an owner, open **Members** and set the new owner's role to **Owner**. +2. Ask the new owner to change your role to **Admin** or **Member**. + +## Delete a workspace + +Only owners can delete a workspace, and only when they belong to at least one other workspace. + +1. Open **Settings › General** and click **Delete workspace**. +2. Tick every acknowledgment. +3. Click **Delete workspace** to confirm. + +Deletion is immediate and cannot be undone: + +- Members lose access right away. +- All service account API keys and pending invitations are revoked. +- Auto-recharge stops. +- An active Go subscription ends. +- Any remaining credit balance is forfeited. + +Deletion is blocked while a payment is processing. Try again in a few minutes. + +## Leave a workspace + +Members cannot remove themselves. Ask an owner or admin to [remove you](/console/members#remove-a-member). diff --git a/services/www/src/docs/lib/navigation.ts b/services/www/src/docs/lib/navigation.ts index 24f0561b339d..9b216f5c50ac 100644 --- a/services/www/src/docs/lib/navigation.ts +++ b/services/www/src/docs/lib/navigation.ts @@ -137,16 +137,29 @@ export const docsSections: DocsSection[] = [ items: [ { title: "Intro", slug: "console" }, { title: "Models", slug: "console/models" }, - { title: "Websearch", slug: "console/websearch" }, + { title: "Providers", slug: "console/providers" }, + { title: "Web Search", slug: "console/websearch" }, { title: "Go", slug: "console/go" }, ], }, { - title: "API", + title: "Workspace", items: [ - { title: "Inference", slug: "console/inference" }, - { title: "BYOK", slug: "console/byok" }, + { title: "Basics", slug: "console/workspaces" }, + { title: "Members", slug: "console/members" }, + { title: "SSO", slug: "console/sso" }, + { title: "SCIM", slug: "console/scim" }, { title: "Budgets", slug: "console/budgets" }, + { title: "Billing", slug: "console/billing" }, + ], + }, + { + title: "API", + items: [ + { title: "Overview", slug: "console/api" }, + { title: "Inference", slug: "console/api/inference" }, + { title: "Providers", slug: "console/api/providers" }, + { title: "Budgets", slug: "console/api/budgets" }, ], }, ],