# Provider credentials

Workspace owners and admins store the Credentials Sensei runs each provider on. A workspace can hold several auth methods per provider, and one of them is active at a time. To store a key or change the active method, send `PUT /api/organizations/{workspaceId}/ai-provider` with an `operation`. Any member can read the Credentials, with every secret masked.

| Method | Path                                                                          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| GET    | `/api/organizations/{workspaceId}/ai-provider`                                | Read the workspace credentials and active auth method per provider, with every login of claude_code, codex and muse_code oldest first. Secrets are masked.                                                                                                                                                                                                                                                                                                                                                                                                               |
| PUT    | `/api/organizations/{workspaceId}/ai-provider`                                | Store or switch workspace credentials. The body is one of the operation variants. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| DELETE | `/api/organizations/{workspaceId}/ai-provider?provider=&authMethod=&loginId=` | Remove the credentials of one auth method, or with loginId one login of claude_code, codex or muse_code. Which methods a provider takes is not in the schema. Admins only.                                                                                                                                                                                                                                                                                                                                                                                               |
| GET    | `/api/organizations/{workspaceId}/ai-provider/claude-usage?fresh=&loginId=`   | Read the session and weekly utilization of the workspace's Claude login: the one in use, or the one loginId names. 400 when the workspace holds no such Claude login or it needs reconnecting.                                                                                                                                                                                                                                                                                                                                                                           |
| GET    | `/api/organizations/{workspaceId}/ai-provider/codex-usage?fresh=&loginId=`    | Read the session and weekly utilization of the workspace's Codex login: the one in use, or the one loginId names. 400 when the workspace holds no such Codex login or it needs reconnecting.                                                                                                                                                                                                                                                                                                                                                                             |
| GET    | `/api/organizations/{workspaceId}/ai-provider/coding-plan-usage?fresh=`       | Read the session and weekly utilization of the workspace's GLM Coding Plan. 400 when the workspace holds no Coding Plan.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| GET    | `/api/organizations/{workspaceId}/ai-provider/deepseek-usage?fresh=`          | Read the balance of the workspace's DeepSeek API key, one amount per currency, in place of usage windows. 400 when the workspace holds no DeepSeek API key.                                                                                                                                                                                                                                                                                                                                                                                                              |
| GET    | `/api/organizations/{workspaceId}/ai-provider/google`                         | Read saved workspace Gemini methods and selection. Secrets are masked.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| PUT    | `/api/organizations/{workspaceId}/ai-provider/google`                         | Validate and save a workspace Gemini API key without selecting it. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| DELETE | `/api/organizations/{workspaceId}/ai-provider/google`                         | Remove both workspace Gemini methods and clear selection. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| PUT    | `/api/organizations/{workspaceId}/ai-provider/google/method`                  | Select a saved workspace Gemini method with its selection revision. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| DELETE | `/api/organizations/{workspaceId}/ai-provider/google/method`                  | Remove one workspace Gemini method. Removing the selected method leaves none selected. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| GET    | `/api/organizations/{workspaceId}/ai-provider/google/usage?fresh=&loginId=`   | Read the session and weekly utilization of the workspace's Antigravity sign-in, whichever Gemini method is selected: its stored reading, from its latest turn or a live read, while that is under 5 minutes old, and otherwise a live read from Google with the sign-in's own token, stored on the sign-in. When the live read fails it is the stored reading, and null before there is one. A read never changes the selected method or a limit. 400 when the workspace holds no such sign-in or it needs reconnecting.                                                 |
| GET    | `/api/organizations/{workspaceId}/ai-provider/grok-usage?fresh=&loginId=`     | Read a workspace SuperGrok login's weekly usage: its stored reading while under five minutes old, otherwise a live read with its saved access token. A failed live read returns the stored reading, or null before one exists. A free reading begun at least fifteen minutes after a limit may lift that unchanged mark. An xAI API key has no reading. 400 when the named login is absent or needs reconnecting.                                                                                                                                                        |
| POST   | `/api/organizations/{workspaceId}/ai-provider/help-request`                   | Ask the workspace owners and admins to fix a provider. Repeated requests within one hour notify them once.                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| GET    | `/api/organizations/{workspaceId}/ai-provider/kimi-code-usage?fresh=`         | Read the session and monthly utilization of the workspace's Kimi Code. 400 when the workspace holds no Kimi Code key.                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| POST   | `/api/organizations/{workspaceId}/ai-provider/login/antigravity`              | Start workspace Antigravity sign-in. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| POST   | `/api/organizations/{workspaceId}/ai-provider/login/antigravity/cancel`       | Cancel workspace Antigravity sign-in. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| POST   | `/api/organizations/{workspaceId}/ai-provider/login/antigravity/complete`     | Complete workspace Antigravity sign-in. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| POST   | `/api/organizations/{workspaceId}/ai-provider/logins/recheck`                 | Re-check usage for the workspace's logins of one provider (including SuperGrok on xai) at their limit, without waiting for their reset: every login of the provider, or the one loginId names. Admins only. Returns cleared, stillAtLimit and unreadable counts and retryAt, the earliest remaining reset, or null.                                                                                                                                                                                                                                                      |
| GET    | `/api/organizations/{workspaceId}/ai-provider/muse-usage?fresh=&loginId=`     | Read the session and weekly utilization of the workspace's Muse Code login: the one in use, or the one loginId names. It is the stored reading, from the login's latest turn, its sign-in, its last usage limit or a live read, while that is under 5 minutes old, and otherwise a live read from Meta; when the live read fails it is the stored reading, and null before there is one. A usage-limit reading holds only the window that hit the limit, at 100%. 400 when the workspace holds no such Muse Code login or it needs reconnecting.                         |
| GET    | `/api/organizations/{workspaceId}/ai-provider/token-usage`                    | Read the tokens Sensei spent on the workspace's Credentials, per Provider and per login or key method, over the last 7 days, the last 30 days and everything recorded: input (uncached), cache read, cache write and output, kept apart. Each total gives its recorded items, how many reported no counts (missing, never added as 0), how many made no model call and how many are still in progress. Covers only work run through Sensei since recording began, from firstStartedAt; members' own Subscriptions and Sensei are never included. Owners and admins only. |
| POST   | `/api/organizations/{workspaceId}/provider-login/claude`                      | Start a Claude login for the workspace: open the returned url in a browser, then pass the code it shows and loginToken to complete within 15 minutes. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                       |
| POST   | `/api/organizations/{workspaceId}/provider-login/claude/complete`             | Finish a Claude login with the loginToken from start and the code from the browser (code, code#state, or the whole callback URL). A refused code answers 200 with authenticated false. Admins only.                                                                                                                                                                                                                                                                                                                                                                      |
| POST   | `/api/organizations/{workspaceId}/provider-login/codex`                       | Start a Codex login for the workspace: enter userCode at verificationUrl in a browser, then call complete with loginToken until it answers authenticated. Admins only.                                                                                                                                                                                                                                                                                                                                                                                                   |
| POST   | `/api/organizations/{workspaceId}/provider-login/codex/complete`              | Poll a Codex login with the loginToken from start: authenticated false until the code is approved in the browser, so repeat every intervalSeconds; restart true means start again. Admins only.                                                                                                                                                                                                                                                                                                                                                                          |
| POST   | `/api/organizations/{workspaceId}/provider-login/muse`                        | Start a Muse Code login for the workspace: open verificationUrl in a browser and approve userCode, then call complete with loginToken until it answers authenticated. Admins only.                                                                                                                                                                                                                                                                                                                                                                                       |
| POST   | `/api/organizations/{workspaceId}/provider-login/muse/complete`               | Poll a Muse Code login with the loginToken from start: authenticated false until the code is approved in the browser, so repeat every intervalSeconds; restart true means start again. The first login makes muse_code the active method. Admins only.                                                                                                                                                                                                                                                                                                                   |

In the web app this is Settings > your workspace > AI Providers. To connect your own Claude, Codex, GLM Coding Plan, Kimi Code or DeepSeek API access instead, see [Account](https://kosuke.ai/docs/endpoint-reference/account.md). Which of the two runs a given session is explained on [AI providers](https://kosuke.ai/docs/workspace/ai-providers.md).

## Read the workspace's Credentials

Read each provider's stored auth methods and which one is active.

```bash
curl -s https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/ai-provider \
  -H "Authorization: Bearer $KOSUKE_API_KEY"
```

```json
{
  "data": {
    "defaultModel": null,
    "providers": {
      "anthropic": {
        "activeAuthMethod": "claude_code",
        "selectable": true,
        "authMethods": {
          "api_key": { "configured": true, "maskedApiKey": "sk-ant-...9f2c", "authenticatedAt": "2026-08-11T14:02:31.000Z" },
          "aws_bedrock": { "configured": false },
          "claude_code": {
            "configured": true,
            "email": "ops@acme.dev",
            "authenticatedAt": "2026-09-20T07:45:12.000Z",
            "logins": [
              { "id": "3d7a1f52-9c4e-4b08-a6e1-5f2b8c9d0e47", "label": "ops@acme.dev", "status": "available", "needsReauth": false, "exhaustedUntil": null, "authenticatedAt": "2026-09-20T07:45:12.000Z" }
            ]
          }
        }
      },
      "openai": {
        "activeAuthMethod": "api_key",
        "selectable": true,
        "authMethods": {
          "api_key": { "configured": true, "maskedApiKey": "sk-proj...41ab", "authenticatedAt": "2026-08-11T14:05:03.000Z" },
          "codex": { "configured": false, "logins": [] }
        }
      },
      "zai": {
        "activeAuthMethod": null,
        "selectable": false,
        "authMethods": { "coding_plan": { "configured": false } }
      },
      "moonshot": {
        "activeAuthMethod": null,
        "selectable": false,
        "authMethods": { "kimi_code": { "configured": false } }
      },
      "deepseek": {
        "activeAuthMethod": null,
        "selectable": false,
        "authMethods": { "deepseek_api": { "configured": false } }
      }
    }
  }
}
```

| Field | Meaning |
| --- | --- |
| `activeAuthMethod` | The method this provider runs on, or `null` when none is active. |
| `selectable` | `true` when the active method works. A login that needs reconnecting makes it `false`. |
| `authMethods.<method>.configured` | Sensei holds this method's key or login. |
| `maskedApiKey` | The first 7 and last 4 characters of a stored key. |
| `email` | The account behind a Claude Code or Codex login. |
| `needsReauth` | Present and `true` when a Claude Code or Codex login needs reconnecting. |
| `region` | The AWS region of a Bedrock key. |
| `logins` | Every Claude Code or Codex login of the method, oldest first. The oldest login wins a tie when usage is close. Each has `id`, `label`, `status`, `needsReauth`, `exhaustedUntil` and `authenticatedAt`. `label` is the account email. |
| `logins[].status` | `available`, `limit_reached` or `reconnect_required`. `exhaustedUntil` is set only on `limit_reached`. |

`defaultModel` is the Workspace Default Model when its provider can run, otherwise the model Sensei would choose from the first usable provider, and `null` only when no provider can run. `savedDefaultModel` is the Workspace Default Model as saved, and `hasSavedDefaultModel` says whether one is saved. A member's own Default Model is on [Account](https://kosuke.ai/docs/endpoint-reference/account.md).

In the CLI, run `kosuke providers get <workspaceId>`.

## Store a key or switch the active method

Set `operation` to one of these values. Owners and admins only. `default_model` with a `model` field sets the Workspace Default Model and answers `400 BAD_REQUEST` when that model’s provider cannot run.

| `operation` | Auth method | Other fields |
| --- | --- | --- |
| `anthropic_api_key` | Anthropic API key | `anthropicApiKey`. Leave it out to switch back to the key already stored. |
| `anthropic_aws_bedrock` | Anthropic on AWS Bedrock | `region`, required. `bedrockApiKey`, which you leave out to reuse the stored key. `validationModel`, an optional [model value](https://kosuke.ai/docs/endpoint-reference/models.md) to test the key against. |
| `anthropic_claude_code` | Claude Code login | None. Makes a stored login active. Connect the login first, as below. |
| `openai_api_key` | OpenAI API key | `openaiApiKey`. Leave it out to switch back to the key already stored. |
| `openai_codex` | Codex login | None. Makes a stored login active. Connect the login first, as below. |
| `zai_coding_plan` | GLM Coding Plan | `codingPlanKey`. Leave it out to switch back to the key already stored. |
| `moonshot_kimi_code` | Kimi Code | `kimiCodeKey`. Leave it out to switch back to the key already stored. |
| `deepseek_deepseek_api` | DeepSeek API | `deepseekApiKey`, a key from the [DeepSeek Platform](https://platform.deepseek.com/api_keys). Leave it out to switch back to the key already stored. |

Sensei tests a new key with one call to the provider before it keeps it. A refused key answers `400 BAD_REQUEST` with the provider's reason. A DeepSeek API key with an empty balance passes the test and is stored. A key that passes is stored and becomes the active method at once. `validationModel` only picks the model for that test and defaults to `anthropic:opus__xhigh`.

```bash
curl -s -X PUT https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/ai-provider \
  -H "Authorization: Bearer $KOSUKE_API_KEY" \
  --json '{ "operation": "openai_api_key", "openaiApiKey": "'"$OPENAI_API_KEY"'" }'
```

The response has the same body as the read above. Existing sandboxes that run that provider on the workspace's Credentials receive the change. A sandbox running on a member's Subscription keeps that Subscription.

In the CLI, run `kosuke providers set <workspaceId> --body '{"operation":"anthropic_claude_code"}'`.

## Connect a Claude Code login

A Claude Code login takes two calls and one visit to Claude in a browser. Owners and admins only.

1. Start the login.

   ```bash
   curl -s -X POST https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/provider-login/claude \
     -H "Authorization: Bearer $KOSUKE_API_KEY"
   ```

   ```json
   { "data": { "url": "https://claude.com/cai/oauth/authorize?code=true&client_id=...", "loginToken": "a3f9c2...e81d" } }
   ```

2. Open `url` in a browser, sign in to Claude and authorize. The page shows a code.
3. Within 15 minutes, send the code with the `loginToken`. `code` takes the code, the code with its `#state` suffix, or the whole callback URL.

   ```bash
   curl -s https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/provider-login/claude/complete \
     -H "Authorization: Bearer $KOSUKE_API_KEY" \
     --json '{ "loginToken": "'"$LOGIN_TOKEN"'", "code": "'"$CODE"'" }'
   ```

   ```json
   { "data": { "authenticated": true, "email": "ops@acme.dev" } }
   ```

4. Read the answer. A refused code still answers `200`. With `authenticated: false`, `message` says why. When `restart` is also `true`, go back to step 1. Otherwise paste the code again.
5. Make the login the active method with `PUT /api/organizations/{workspaceId}/ai-provider` and `{ "operation": "anthropic_claude_code" }`. A finished login is stored, and it stays inactive until you do.

In the CLI, run `kosuke providers logins start <workspaceId> --provider claude_code`, then `kosuke providers logins complete <workspaceId> --login-token <token> --code <code> --provider claude_code`.

## Connect a Codex login

A Codex login uses a device code that you enter on OpenAI's site. Owners and admins only.

1. Start the login.

   ```bash
   curl -s -X POST https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/provider-login/codex \
     -H "Authorization: Bearer $KOSUKE_API_KEY"
   ```

   ```json
   {
     "data": {
       "userCode": "WXYZ-1234",
       "verificationUrl": "https://auth.openai.com/codex/device",
       "intervalSeconds": 5,
       "loginToken": "a3f9c2...e81d"
     }
   }
   ```

2. Open `verificationUrl` in a browser, sign in with the ChatGPT account and enter `userCode`.
3. Poll every `intervalSeconds` with the `loginToken`.

   ```bash
   curl -s https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/provider-login/codex/complete \
     -H "Authorization: Bearer $KOSUKE_API_KEY" \
     --json '{ "loginToken": "'"$LOGIN_TOKEN"'" }'
   ```

4. Read the answer. `{ "authenticated": false }` means the code is not approved yet, so poll again. `authenticated: true` comes with the account `email`. `restart: true` means the code expired or OpenAI refused it, so go back to step 1.
5. Make the login the active method with `PUT /api/organizations/{workspaceId}/ai-provider` and `{ "operation": "openai_codex" }`.

In the CLI, run `kosuke providers logins start <workspaceId> --provider codex`, then `kosuke providers logins complete <workspaceId> --login-token <token> --provider codex`.

## Remove Credentials

Delete the stored key or login of one auth method. Owners and admins only. The route answers `204`.

| `provider` | `authMethod` values |
| --- | --- |
| `anthropic` | `api_key`, `aws_bedrock`, `claude_code` |
| `openai` | `api_key`, `codex` |
| `zai` | `coding_plan` |
| `moonshot` | `kimi_code` |
| `deepseek` | `deepseek_api` |

```bash
curl -s -X DELETE "https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/ai-provider?provider=openai&authMethod=api_key" \
  -H "Authorization: Bearer $KOSUKE_API_KEY"
```

Removing the active method leaves the provider with no active method. Its `activeAuthMethod` reads `null` until you switch to another one.

In the CLI, run `kosuke providers delete <workspaceId> --provider openai --auth-method api_key`.

## Check usage

Read how much of its limits a Claude Code login, a Codex login, a GLM Coding Plan or a Kimi Code key has used, or the balance of a DeepSeek API key. Any member can read it, whether or not the method is active.

```bash
curl -s https://app.kosuke.ai/api/organizations/$WORKSPACE_ID/ai-provider/claude-usage \
  -H "Authorization: Bearer $KOSUKE_API_KEY"
```

```json
{
  "data": {
    "session": { "utilization": 42, "resetsAt": "2026-09-30T14:00:00.000Z" },
    "week": { "utilization": 18, "resetsAt": "2026-10-04T09:00:00.000Z" },
    "fetchedAt": "2026-09-30T11:37:05.000Z"
  }
}
```

`session` is the 5-hour window and `week` the 7-day window. `utilization` is a percentage from 0 to 100. Either window is `null` when the provider reports none. Kimi Code has no weekly window, so its `week` is always `null` and its monthly window is in `month`. Sensei keeps an answer for up to 5 minutes, so `fetchedAt` says how fresh it is.

| Route | Reads |
| --- | --- |
| `GET /api/organizations/{workspaceId}/ai-provider/claude-usage` | The Claude Code login. |
| `GET /api/organizations/{workspaceId}/ai-provider/codex-usage` | The Codex login. |
| `GET /api/organizations/{workspaceId}/ai-provider/coding-plan-usage` | The GLM Coding Plan. |
| `GET /api/organizations/{workspaceId}/ai-provider/kimi-code-usage` | The Kimi Code key. |
| `GET /api/organizations/{workspaceId}/ai-provider/deepseek-usage` | The DeepSeek API key's balance. |

A DeepSeek API key is paid as you go and has no windows. Its `session` and `week` are `null`, and `balance` carries the key's balance instead.

```json
{
  "data": {
    "session": null,
    "week": null,
    "balance": { "available": true, "amounts": [{ "currency": "USD", "total": "12.40" }] },
    "fetchedAt": "2026-09-30T11:37:05.000Z"
  }
}
```

`balance.available` is `false` when the balance is too low to run a turn. `balance.amounts` holds one entry per currency the account holds, `USD` or `CNY`, with `total` as a decimal string. Sensei does not add the currencies together.

In the CLI, run `kosuke providers usage get <workspaceId> --provider claude_code`, and `codex`, `coding-plan`, `kimi-code` or `deepseek` in place of `claude`.

## Errors

| Status | Code | When |
| --- | --- | --- |
| 400 | `BAD_REQUEST` | The provider refused the key. You left out a key and none is stored. You picked a login method before connecting the login. The `validationModel` has no Bedrock equivalent, or the `default_model` provider cannot run. The `provider` and `authMethod` pair is invalid. A usage route found no login, GLM Coding Plan, Kimi Code or DeepSeek API key, or a login that needs reconnecting. |
| 400 | `VALIDATION_ERROR` | The body fails the schema, such as an unknown `operation` or an empty `code`. |
| 403 | `FORBIDDEN` | You are not a member of the workspace, or you are a member calling a route for owners and admins. |
| 503 | `SERVICE_UNAVAILABLE` | OpenAI could not start a Codex login, or the provider did not return usage. Try again. |

The full list is in [Responses and errors](https://kosuke.ai/docs/api/errors.md).

## Next steps

- Connect your own Subscription with [Account](https://kosuke.ai/docs/endpoint-reference/account.md).
- Check what members can run with [Workspaces](https://kosuke.ai/docs/endpoint-reference/workspaces.md).
- Read whose credentials run what on [AI providers](https://kosuke.ai/docs/workspace/ai-providers.md).
