Skip to content

Instantly share code, notes, and snippets.

@cedws
Last active March 20, 2026 00:14
Show Gist options
  • Select an option

  • Save cedws/3a24b2c7569bb610e24aa90dd217d9f2 to your computer and use it in GitHub Desktop.

Select an option

Save cedws/3a24b2c7569bb610e24aa90dd217d9f2 to your computer and use it in GitHub Desktop.

Anthropic API notes for the Claude Code OAuth flow

This flow does not start from a manually created Console API key. It starts from Anthropic's Claude Code OAuth flow, then uses the returned OAuth access token as the credential for subsequent Anthropic API requests.

Endpoints and scope

  • Authorisation endpoint: https://claude.ai/oauth/authorize
  • Token endpoint: https://console.anthropic.com/v1/oauth/token
  • Redirect URI: https://console.anthropic.com/oauth/code/callback
  • Claude Code OAuth client ID: 9d1c250a-e61b-44d9-88ed-5944d1962f5e
  • PKCE method: S256
  • Scope: org:create_api_key user:profile user:inference

PKCE flow

Use the OAuth 2.0 authorisation code flow with PKCE.

  1. Generate a cryptographically random PKCE verifier.
  2. Base64url-encode it without padding.
  3. Hash the verifier with SHA-256.
  4. Base64url-encode that hash without padding to produce the PKCE challenge.
  5. Set state to the same random base64url value used for the verifier in this flow.
  6. Send the user to the Anthropic authorisation endpoint.
  7. After the user signs in and approves access, collect the returned authorisation code.
  8. Exchange that code, together with the original verifier, at the token endpoint.
  9. Persist the returned access token, refresh token, and expiry metadata.
  10. Refresh the token when it is close to expiry.

For this Claude Code style flow, the browser callback is not redirected to a local server. The redirect target is Anthropic's hosted callback URL, so a CLI implementation can ask the user to copy the returned code back into the client.

For a compatible implementation:

  • Start with 32 cryptographically random bytes.
  • Base64url-encode them without = padding.
  • Use that encoded string as the code_verifier.
  • Compute SHA-256(code_verifier).
  • Base64url-encode that hash without = padding.
  • Use that encoded hash as code_challenge.
  • Use the original code_verifier value as state.

The verifier produced this way is typically a 43-character base64url string.

Authorisation request parameters

The authorisation request needs:

  • code=true
  • response_type=code
  • client_id=9d1c250a-e61b-44d9-88ed-5944d1962f5e
  • redirect_uri=https://console.anthropic.com/oauth/code/callback
  • scope=org:create_api_key user:profile user:inference
  • code_challenge=<base64url-without-padding of SHA-256(code_verifier)>
  • code_challenge_method=S256
  • state=<same base64url random value used as code_verifier>

Keep the original code_verifier and state from this step. They are needed for the token exchange.

Token exchange request

Exchange the authorisation code at https://console.anthropic.com/v1/oauth/token.

The exchange request needs:

  • grant_type=authorization_code
  • code
  • code_verifier
  • client_id=9d1c250a-e61b-44d9-88ed-5944d1962f5e
  • redirect_uri=https://console.anthropic.com/oauth/code/callback
  • state when the returned value includes it

The token response should be treated as an OAuth token set. At minimum, store:

  • access_token
  • refresh_token
  • expires_in
  • expires_at

The access token is the credential used for later Anthropic API calls in this flow.

Token refresh request

Refresh uses the same token endpoint with:

  • grant_type=refresh_token
  • refresh_token
  • client_id=9d1c250a-e61b-44d9-88ed-5944d1962f5e

When a refresh succeeds, replace the stored access token, refresh token, and expiry metadata with the newly returned values.

Headers for the token endpoint

Requests to the OAuth token endpoint need:

  • Content-Type: application/json
  • User-Agent: anthropic

Headers for Anthropic API calls

For authenticated Anthropic requests in this flow, send:

  • x-api-key: <OAuth access token>
  • anthropic-version: 2023-06-01
  • Content-Type: application/json

For the Claude Code style integration shown in these commits, also send:

  • anthropic-dangerous-direct-browser-access: true
  • x-app: cli
  • user-agent: claude-cli/<version> (external, cli)
  • anthropic-beta: oauth-2025-04-20,claude-code-20250219

Messages requests in this flow also enable beta mode on the request URL.

If you use additional Anthropic beta features, append those beta names rather than replacing the Claude Code OAuth beta values.

Tool naming requirement

For Claude Code style tool use, tool names need a cc_ prefix on the wire.

This applies to:

  • tool definitions sent in the request
  • explicit tool-choice names
  • tool_use message blocks
  • tool_result message blocks

Responses can then be normalised back to the unprefixed tool names for the rest of your application.

Operational notes

  • This is a specialised Claude Code OAuth flow, not the normal Anthropic Console API-key flow.
  • Treat both access and refresh tokens as secrets.
  • Refresh the token before or when it expires.
  • The OAuth-derived access token is used in place of a manually generated Anthropic API key for requests made in this manner.
  • Keep this path separate from standard Anthropic API-key integrations. The linked OpenCode PR suggests other clients are removing Claude Code-specific betas from their generic Anthropic provider paths.

Suggested libraries

Python

  • OAuth/PKCE: Authlib

TypeScript

  • OAuth/PKCE: openid-client

Java

  • OAuth/PKCE: Nimbus OAuth 2.0 / OIDC SDK

Go

  • OAuth/PKCE: golang.org/x/oauth2

Ruby

  • OAuth/PKCE: oauth2

C#

  • OAuth/PKCE: IdentityModel.OidcClient

PHP

  • OAuth/PKCE: league/oauth2-client
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment