10 KiB
title, version, lastUpdated
| title | version | lastUpdated |
|---|---|---|
| Providers — Claude Web | 3.8.49 | 2026-07-14 |
Providers — Claude Web
claude-web
claude-web sends OpenAI-format chat requests through an authenticated claude.ai
browser session. The executor normalizes the supplied cookie, resolves one authenticated
organization, prepares conversation state, selects a direct or browser transport, and
strictly translates the upstream SSE response. The orchestration is in
open-sse/executors/claude-web.ts:320.
New to Web Cookie providers?
Read
docs/getting-started/WEB-COOKIE-GUIDE.mdfor the general setup process, authentication guidance, limitations, and troubleshooting before following this provider-specific guide.
Model catalog
The provider registry currently exposes exactly these seven static model IDs
(open-sse/config/providers/registry/claude/web/index.ts:11):
| Model ID | Display name |
|---|---|
claude-fable-5 |
Claude Fable 5 (web) |
claude-opus-4-8 |
Claude Opus 4.8 (web) |
claude-sonnet-5 |
Claude Sonnet 5 (web) |
claude-haiku-4-5-20251001 |
Claude Haiku 4.5 (web) |
claude-opus-4-7 |
Claude Opus 4.7 (web) |
claude-opus-4-6 |
Claude Opus 4.6 (web) |
claude-sonnet-4-6 |
Claude Sonnet 4.6 (web) |
Dynamic model discovery is not implemented for this provider. The list above is the runtime catalog.
Credentials and organization resolution
Supply either the full claude.ai Cookie header or a bare session value. Bare values are
normalized to sessionKey; other cookies are preserved if supplied. The executor accepts the
cookie through cookie or apiKey and
reads optional deviceId and orgId values from the connection data
(open-sse/executors/claude-web.ts:72).
If orgId is absent, the executor calls GET https://claude.ai/api/organizations and uses the first
organization returned by the authenticated Claude Web session
(open-sse/executors/claude-web.ts:141). It fails closed when no valid organization is
returned, reports rejected session authorization as 401, and distinguishes a Cloudflare
challenge from an authentication failure.
Conversation operations
The optional top-level claude_web object is strict. Unknown fields are rejected. Its
accepted fields are defined in open-sse/executors/claude-web/session.ts:50:
| Field | Meaning |
|---|---|
operation |
completion by default; use retry for a retry turn |
conversation_id |
Explicit UUID for an existing conversation |
parent_message_uuid |
Explicit UUID for the parent assistant message |
timezone |
Valid IANA time-zone name |
locale |
Structurally valid locale |
tool_states |
Optional account tool-state array, limited to 128 entries |
Prepared requests use one of two upstream endpoints
(open-sse/executors/claude-web.ts:203):
- A new or follow-up turn posts to
POST https://claude.ai/api/organizations/{orgId}/chat_conversations/{conversationId}/completion. - A retry posts to
POST https://claude.ai/api/organizations/{orgId}/chat_conversations/{conversationId}/retry_completion.
A new turn includes create_conversation_params. A cached or explicitly linked follow-up
includes parent_message_uuid and omits create_conversation_params. Retry requires both
conversation and parent-message state and sends no prompt
(open-sse/executors/claude-web/session.ts:254). New conversations open the authenticated
UI at /new; cached or explicitly linked follow-ups open the exact conversation page
(open-sse/executors/claude-web/session.ts:324).
Conversation state is an in-memory cache keyed by a SHA-256 account scope and the canonical
caller transcript. Entries expire after 30 minutes and the cache is capped at 5,000 entries
(open-sse/executors/claude-web/session.ts:12). State is committed only after the strict
stream parser observes message_stop; process restarts discard it. On a cache miss, a
multi-message request is serialized into one recovery prompt instead of silently dropping
earlier messages.
Locale and time zone use this precedence: request claude_web value, connection value,
runtime value, then en-US for locale or UTC for time zone
(open-sse/executors/claude-web/session.ts:218).
Tools and request payloads
Direct requests transform only structurally valid OpenAI function tools supplied by the
caller. There is no fabricated static default tool list
(open-sse/executors/claude-web/payload.ts:102).
Browser requests instead capture the authenticated UI request and retain its account tools,
tool states, and personalized styles. Prepared conversation, model, reasoning, prompt, and
message UUID fields still override the captured request
(open-sse/executors/claude-web/browserTransport.ts:175). Browser templates are scoped by a
hash of account, organization, cookie, locale, and time zone and expire after 30 minutes
(open-sse/executors/claude-web/browserTransport.ts:11,
open-sse/executors/claude-web/browserTransport.ts:158). When a direct request has no caller
tools, it can reuse that scoped template; explicit caller tools take precedence
(open-sse/executors/claude-web/browserTransport.ts:214).
Transport selection
The default path is sendClaudeWebDirect(), which calls tlsFetchClaude() with the configured
Chrome 146 profile and the supplied cookie (open-sse/services/claudeTlsClient.ts:23). It does
not launch a solver or manufacture a replacement cookie.
Set WEB_COOKIE_USE_BROWSER to 1, true, or on to make the account-scoped browser
adapter the primary transport. Set OMNIROUTE_BROWSER_POOL to one of the same values to
allow a recognized Cloudflare 403 challenge to fall back from direct transport to the
browser adapter (open-sse/executors/claude-web.ts:195). Other HTTP failures do not trigger
that fallback.
The browser adapter keeps cookies inside the same pooled Playwright context, uses the scoped
hashed key described above, and sends the completion from that context
(open-sse/executors/claude-web/browserTransport.ts:444). It never exports a browser-solved
cookie into the direct TLS client. Browser retries require a non-expired UI template bound to
the same actual Playwright context (open-sse/executors/claude-web/browserTransport.ts:467).
Browser response reads run incrementally in the authenticated page, honor request cancellation,
and cancel the upstream body as soon as it exceeds 16 MiB
(open-sse/executors/claude-web/browserTransport.ts:259).
The executor returns a redacted audit projection to the shared request logger: organization,
conversation and message UUIDs, prompt text, tool definitions, cookies, and device identifiers
are excluded (open-sse/executors/claude-web.ts:237,
open-sse/executors/claude-web.ts:252). Transport exceptions also return a generic connection
error rather than the thrown message.
SSE behavior
createClaudeWebResponse() handles LF or CRLF framing and multiline data: fields. It maps
text deltas to content, thinking deltas to reasoning_content, and known metadata events
to the claude_web response extension. Each metadata event is projected through its own field
allowlist (open-sse/executors/claude-web/stream.ts:37). The
conversation, parent-message, assistant-message, and operation metadata are also returned in
X-OmniRoute-Claude-Web-* headers (open-sse/executors/claude-web/stream.ts:364).
The parser fails closed on malformed JSON, upstream error events, unknown event types,
invalid ordering, content-block mismatches, or EOF before message_stop. Streaming output
emits one finish chunk and one [DONE]; buffered output uses the same parser. The parser treats
message_stop as terminal immediately, cancels trailing upstream data, and propagates
downstream cancellation to the upstream reader (open-sse/executors/claude-web/stream.ts:461,
open-sse/executors/claude-web/stream.ts:563). Unterminated SSE lines and accumulated events
are capped at 1 MiB (open-sse/executors/claude-web/stream.ts:17,
open-sse/executors/claude-web/stream.ts:62).
Files
| File | Purpose |
|---|---|
open-sse/config/providers/registry/claude/web/index.ts |
Static provider model registry |
open-sse/executors/claude-web.ts |
Executor orchestration |
open-sse/executors/claude-web/payload.ts |
Payload and tool transformation |
open-sse/executors/claude-web/session.ts |
Turn state and transcript cache |
open-sse/executors/claude-web/transport.ts |
Direct transport adapter |
open-sse/executors/claude-web/browserTransport.ts |
Account-scoped browser adapter |
open-sse/executors/claude-web/stream.ts |
Strict SSE translation |
open-sse/services/claudeTlsClient.ts |
Native TLS transport |
open-sse/services/browserPool.ts |
Pooled Playwright contexts |
Testing
Run the deterministic Claude Web suite without real credentials:
node --import tsx/esm --test tests/unit/claude-web-auto-refresh.test.ts tests/unit/claude-web-browser-transport.test.ts tests/unit/claude-web-executor-split.test.ts tests/unit/claude-web-live-alignment.test.ts tests/unit/claude-web-payload-runtime.test.ts tests/unit/claude-web-session.test.ts tests/unit/claude-web-sonnet5-registry-6209.test.ts tests/unit/claude-web-stream.test.ts tests/unit/claude-web-transport.test.ts tests/unit/claude-web.test.ts tests/unit/issue-6662-repro.test.ts
The Playwright-dependent cases in tests/unit/claude-web-auto-refresh.test.ts are explicitly
skipped. This repository does not currently define a credentialed Claude Web live-test
script, so those skipped cases are not runtime proof.
Setup
- Start OmniRoute with
npm run devor a built installation. - Open Dashboard → Providers → Add Provider.
- Select the Web Cookie category and Claude Web.
- Paste the full Cookie header copied from an authenticated
claude.airequest.