Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is incorrect. There are no separate "private Claude Code endpoints."

I reverse engineered this over the past week. Both Claude Code and regular API users hit the same endpoint: https://api.anthropic.com/v1/messages

The only difference is the auth method - OAuth bearer token (sk-ant-oat01-...) vs API key (sk-ant-api03-...). The "blocking" is request body fingerprinting on the server side.

Here's what a working Claude Code request looks like:

  {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 32000,
    "stream": true,
    "metadata": {
      "user_id": "user_<sha256>_account_<uuid>_session_<uuid>"
    },
    "system": [
      {"type": "text", "text": "You are a Claude agent, built on Anthropic's Claude Agent SDK."},
      {"type": "text", "text": "<~12KB of instructions>"}
    ],
    "tools": [
      {"name": "Task", ...},
      {"name": "Bash", ...},
      // 17 tools total, PascalCase names
    ],
    "messages": [...]
  }
And here's what OpenCode sends (blocked):

  {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 16000,
    "temperature": 0,           // Claude Code doesn't send this
    "stream": true,
                                // no metadata.user_id - required
    "system": [
      {"type": "text", "text": "You are OpenCode, an interactive CLI..."}
    ],
    "tools": [
      {"name": "bash", ...},    // lowercase, wrong schema
      {"name": "edit", ...},
      // 11 tools total
    ],
    "messages": [...]
  }
The API validates at least 5 things:

(1) system prompt must start with "You are a Claude agent, built on Anthropic's Claude Agent SDK."

(2) tools must match Claude Code's exact 17 tool definitions with PascalCase names

(3) headers must include anthropic-beta, x-app: cli, and claude-cli user-agent

(4) metadata.user_id must be present in a specific format

(5) temperature field must be absent.

Fail any of these:

  400 | This credential is only authorized for use with Claude Code
        and cannot be used for other API requests.
It's bypassable though. I wrote a local proxy that lets OpenCode (and other third-party clients) work with a Max subscription. The approach: run legit Claude Code through the proxy once to capture its exact request format - the full system prompt, all 17 tool schemas, headers. Cache that. Then when OpenCode sends a request, the proxy swaps its templates with Claude Code's cached ones, adds the required headers/metadata, and strips temperature. The OAuth token is already on disk at ~/.claude/.credentials.json (written by "claude login") - the proxy just reads it for each request.

Same endpoint, same request size, just different templates. Returns 200. OpenCode works with Max subscription again.

It's not endpoint separation, it's request body validation. The OAuth token is tied to an expected request format, but the format can be mimicked.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: