---
name: get-api-key
description: Obtain an Anthropic API key by calling the Console's internal API endpoints via browser_evaluate, falling back to screenshot-based browser automation if direct API calls fail.
---

# Get Anthropic API Key

Obtain an API key from the Anthropic Console (platform.claude.com) on behalf of the user. The browser-specialist calls Console API endpoints directly via `browser_evaluate` + `fetch()` — the browser's session cookies handle auth automatically. This is orders of magnitude faster than navigating pages and interpreting screenshots.

**Critical ordering rule:** Credits must be confirmed on the account before creating an API key. Keys created on a zero-balance account are permanently rejected by the Anthropic API — even after credits are added later.

**Auth model:** The Console uses an `httpOnly` session cookie (`sessionKey`) set during sign-in. Because it's `httpOnly`, JavaScript can't read it — but `fetch()` with `credentials: 'include'` sends it automatically. All API calls in the briefs below rely on this.

## Steps

1. **Show the browser.** Call `render-component` with:
   - `name: "browser-viewer"`
   - `data: { title: "Anthropic Console" }`

2. **Dispatch browser-specialist for sign-in check and billing assessment.** Use the Agent tool with `specialists:browser-specialist` as the subagent type. Brief:

   > Navigate to https://platform.claude.com/settings/billing. Wait for the page to load.
   >
   > Then use `browser_evaluate` to run this JavaScript:
   > ```js
   > (async () => {
   >   try {
   >     const orgsRes = await fetch('/api/organizations', { credentials: 'include', headers: { 'content-type': 'application/json' } });
   >     if (orgsRes.status === 401 || orgsRes.status === 403) return { status: 'SIGN_IN_REQUIRED' };
   >     const orgs = await orgsRes.json();
   >     const apiOrg = orgs.find(o => o.capabilities && o.capabilities.includes('api'));
   >     if (!apiOrg) return { status: 'NO_API_ORG', orgs: orgs.map(o => ({ name: o.name, capabilities: o.capabilities })) };
   >     const creditsRes = await fetch(`/api/organizations/${apiOrg.uuid}/prepaid/credits`, { credentials: 'include', headers: { 'content-type': 'application/json' } });
   >     if (!creditsRes.ok) return { status: 'BILLING_CHECK_FAILED', httpStatus: creditsRes.status };
   >     const credits = await creditsRes.json();
   >     return { status: 'OK', orgId: apiOrg.uuid, orgName: apiOrg.name, creditsCents: credits.amount, currency: credits.currency };
   >   } catch (e) { return { status: 'FETCH_ERROR', error: e.message }; }
   > })()
   > ```
   >
   > Report the result object exactly as returned. Do not interpret or summarize — pass the JSON back verbatim.

3. **Handle the billing result.**
   - `status: "OK"` with `creditsCents > 0`: Credits available. Note the `orgId` — it's needed for key creation. Proceed to step 6.
   - `status: "OK"` with `creditsCents === 0`: No credits. Proceed to step 5.
   - `status: "SIGN_IN_REQUIRED"`: Proceed to step 4.
   - `status: "NO_API_ORG"`: Tell the user: "Your Anthropic account doesn't have an API organization. Visit platform.claude.com and set up API access, then try again."
   - `status: "BILLING_CHECK_FAILED"` or `status: "FETCH_ERROR"`: The direct API call failed. Fall back to the screenshot-based billing check (step 2F).

4. **Sign-in required.** Tell the user: "Sign in to your Anthropic account in the browser. You can use Google sign-in or enter your email — Anthropic will send a verification email. Open the email in the same browser (open a new tab) to complete sign-in. If you don't have an account, create one — you will need to add credits before a key can be created." Wait for the user to confirm they have signed in. Then return to step 2 to re-check billing.

5. **No credits — guide the user.** Tell the user: "Your Anthropic account needs credits loaded before I can create an API key. Add credits or enable auto-top-up on the billing page. Let me know when you're done." Wait for confirmation, then re-dispatch the billing check (step 2). If credits are now present, proceed to step 6. If still no credits, repeat this step (maximum 3 attempts). After 3 attempts with no credits detected, tell the user: "Credits still not detected. You can add them at platform.claude.com/settings/billing and then ask me to create the API key again."

6. **Dispatch browser-specialist for key creation.** Use the Agent tool with `specialists:browser-specialist` as the subagent type. Include the `orgId` from step 3. Brief:

   > Use `browser_evaluate` to run this JavaScript (replace ORG_ID with the orgId from the billing check):
   > ```js
   > (async () => {
   >   try {
   >     const res = await fetch('/api/console/organizations/ORG_ID/workspaces/default/api_keys', {
   >       method: 'POST',
   >       credentials: 'include',
   >       headers: { 'content-type': 'application/json' },
   >       body: JSON.stringify({ name: 'Maxy' })
   >     });
   >     if (res.status === 401 || res.status === 403) return { status: 'SIGN_IN_REQUIRED' };
   >     if (!res.ok) return { status: 'CREATE_FAILED', httpStatus: res.status, body: await res.text() };
   >     const key = await res.json();
   >     if (!key.raw_key) return { status: 'NO_RAW_KEY', keyId: key.id };
   >     return { status: 'KEY_CREATED', rawKey: key.raw_key, keyName: key.name, keyId: key.id };
   >   } catch (e) { return { status: 'FETCH_ERROR', error: e.message }; }
   > })()
   > ```
   >
   > If the result has `status: "KEY_CREATED"`, call `api-key-store` with the `rawKey` value. Report the full result object back.
   >
   > If the result has any other status, report it back verbatim — do not attempt to navigate the Console UI.

7. **Handle the key creation result.**
   - `status: "KEY_CREATED"` and specialist confirms key was stored: proceed to step 9 (verify).
   - `status: "SIGN_IN_REQUIRED"`: this is unexpected since sign-in was handled during the billing check. Tell the user to sign in, wait for confirmation, then retry step 6 once. If it fails again, proceed to step 8 (fallback).
   - `status: "CREATE_FAILED"` or `status: "FETCH_ERROR"`: The direct API call failed. Fall back to the screenshot-based key creation (step 6F).
   - `status: "NO_RAW_KEY"`: The key was created but the response didn't include the full key value. Proceed to step 8 (manual fallback).

8. **Fallback.** Tell the user: "I could not extract the key automatically. Please copy it from the browser and paste it here in the chat." When the user pastes a key starting with `sk-ant-`, call `api-key-store` with it. Then proceed to step 9.

9. **Verify the key works.** Call the `api-key-verify` MCP tool. Handle each status:
   - `valid`: Confirm to the user — "API key stored and verified. Your public agent is ready."
   - `billing`: Credits were confirmed before key creation, so this is unexpected. Tell the user: "The key was stored but credits may not have propagated yet. Please wait a moment." Retry `api-key-verify` once after a brief pause. If still `billing`, tell the user: "Credits are not being detected yet. The key is stored — the public agent will start working once Anthropic recognises the credits on your account."
   - `auth_error`: The key was rejected. Tell the user: "The stored key was rejected by Anthropic. It may have been copied incorrectly. Let's try again." Return to step 6 (maximum 2 retries — if it fails 3 times total, tell the user to visit platform.claude.com/settings/keys in their own browser and paste the key manually).
   - `error`: Could not verify (network or Anthropic issue). Tell the user: "I couldn't verify the key right now — this is likely a temporary issue. The key is stored and should work once the connection is restored."

## Fallback Steps (screenshot-based)

These steps are used when `browser_evaluate` + `fetch()` fails. They replicate the original browser automation approach.

### Step 2F: Screenshot-based billing check

Dispatch browser-specialist with brief:

> Navigate to https://platform.claude.com/settings/billing. Take a screenshot to assess the page. Report what you see: Is there a credit balance shown? Does it say "Buy credits to get started"? Is a sign-in page shown instead? Report the billing status and any dollar amount visible. If sign-in is required, report "SIGN_IN_REQUIRED" and stop.

Handle the result the same as step 3, mapping the specialist's text observations to the structured statuses.

### Step 6F: Screenshot-based key creation

Dispatch browser-specialist with brief:

> Navigate to https://platform.claude.com/settings/keys. Take a screenshot to verify you are on the API Keys page. Create a new API key named "Maxy": find and click the "Create Key" button, fill the key name with "Maxy", submit the form. After creation, look for a string starting with sk-ant- on the page — Anthropic shows the key only once. If found, call api-key-store with the key. Report what happened. If sign-in is required, report "SIGN_IN_REQUIRED" and stop.

Handle the result the same as step 7.

## Important

- **`render-component` is required before any browser-specialist dispatch.** The browser-viewer component is what makes the VNC browser visible to the user. Without it, automation runs invisibly. Always call `render-component` with `name: "browser-viewer"` and confirm it renders before dispatching a browser-specialist subagent.
- **Credits before keys.** Never create an API key before confirming that credits are loaded on the account. A key created on a zero-balance account is permanently non-functional.
- The browser is visible to the user via VNC. They can see everything the specialist does.
- The user must sign in themselves — the specialist does not fill credentials.
- For email verification: tell the user to open the verification email in a new tab in the same VNC browser (not on their own device). This keeps the sign-in session in the same browser context.
- Anthropic shows the API key only once after creation. With the direct API approach, the `raw_key` is in the JSON response — but if the specialist fails to call `api-key-store` before its context ends, the key is lost and a new one must be created.
- If the browser-specialist is not available (not installed, Agent tool fails), skip the browser-viewer component entirely and tell the user to get a key from platform.claude.com in their own browser, then paste it in the chat.
- The Console URL `console.anthropic.com` redirects to `platform.claude.com`. All briefs use `platform.claude.com` to avoid redirect latency.

## API Reference

For the complete captured API surface (endpoint details, response schemas, auth mechanism), see `references/console-api.md`.
