Nov 8, 2026 · 4 · News

Claude Code sends your email address to websites

Claude Code sends your email address to websites

I’ll research this topic first to get the facts right before writing.## Claude Code sends your email address to websites

A developer using Claude Code on version 2.1.318 noticed something unsettling: websites contacted by the coding agent were receiving the user’s email address in the HTTP User-Agent header. The report described the consequence in unusually practical terms—dozens of scam emails a day, apparently triggered because the address was now visible to sites the tool visited.

The issue is narrow, but it exposes a much broader question for developers using AI agents: when an assistant can browse the web, run commands, read local configuration, and call third-party APIs, where exactly does your account information end up?

The important distinction is that this was not primarily a model behavior. The email address was being added by the Claude Code client as part of request metadata. The underlying model may never have explicitly placed the address into a prompt, and it may never have “decided” to share it. Claude Code still made an outbound request that included identifying information.

That distinction matters because changing models does not automatically fix the problem. The data path is often determined by the agent runtime, HTTP client, proxy configuration, and tool implementation—not by whether the underlying model is Opus, Sonnet, GPT, or Gemini.

What actually happened

The reported behavior was associated with Claude Code 2.1.318. When the tool made web requests, it included the signed-in user’s account email in the User-Agent header. The header is a conventional place for clients to describe themselves:

User-Agent: ClaudeCode/2.1.318 (email@example.com)

A User-Agent is not a secret header. Web servers, reverse proxies, CDN edge nodes, analytics systems, and request logs routinely receive and retain it. It can also be exposed to sites visited by the agent, including search providers, package registries, documentation sites, and any URL that the tool fetches.

The practical consequence is not limited to a cosmetic privacy violation. An email address becomes a durable identifier. It can be correlated with requests, associated with an account, included in marketing databases, used for targeted advertising, or harvested for phishing. The original report’s mention of scam email is particularly important: sharing an address does not merely create a theoretical disclosure. It can make a user’s address visible to an ecosystem that already has incentives to abuse it.

The issue discussion also pointed to a privacy protection introduced around version 2.1.317. The change asks before a web or shell tool operation would transmit an account email address to the network. In other words, the eventual mitigation was to add a consent boundary around a value that should not have been treated as harmless metadata.

That fix is more significant than simply removing one string from one header. It establishes a useful principle: an identifier should not cross a trust boundary merely because the tool framework considers it useful for attribution.

Why it happened

In practice, email-related identifiers tend to enter coding environments through several channels:

# Git identity
git config --global user.email

# Environment variables
env | grep -i email

# Claude Code account metadata
# Depending on the installation and login method

A developer may reasonably expect git config user.email to be used for Git commits. It is much less reasonable to expect it to be attached automatically to arbitrary web searches performed by an AI coding assistant.

The likely failure mode was a convenience feature becoming a default data flow. A client-side author may have wanted to identify Claude Code requests to help servers debug abuse, distinguish traffic, or support enterprise attribution. That is understandable. The mistake was treating an account email as a harmless technical identifier without evaluating where the request would go.

This is a common gotcha in agentic software: a value that is useful in one context becomes dangerous when the same process reuses it in another. A telemetry client may need a user ID. An authentication request may need an account identifier. A web request usually does not.

Why developers should care about AI APIs

The issue is not limited to users who browse the web interactively. Any production system that combines a model with external tools should assume that tool metadata can leak beyond the model provider.

Consider a typical coding agent pipeline:

User request
    ↓
Claude Code / agent runtime
    ↓
Model API
    ↓
Tool decision
    ↓
WebFetch, shell, browser, package manager, MCP server
    ↓
Third-party service

A model provider may receive only the conversation and tool schemas. But the local agent may make the final request to an external service, and that request can contain:

The key security boundary is therefore not just “model versus API.” It is “trusted application code versus every downstream destination.”

This is especially relevant for developers using AI APIs in CI/CD, support systems, coding agents, and internal tools. A prompt can be carefully scrubbed for secrets, while the surrounding HTTP client quietly adds an identifier. Or a developer may use a sanitized model endpoint but route the agent’s tool calls through a third-party service that logs headers.

A useful threat model has three layers:

LayerWhat may be exposedKey question
Model APIPrompt, context, tool schemas, model outputWhat is sent to the provider?
Agent runtimeSession state, local environment, credentials, account metadataWhat does the client add automatically?
Tool destinationsHeaders, URLs, logs, cookies, request bodiesWhat does each third party receive?

A privacy review that stops at the model API is incomplete.

Does a different model solve it?

No. The model choice may affect reasoning quality, latency, cost, and tool-use reliability, but it does not control whether Claude Code, Codex, Gemini CLI, or another agent wrapper adds your email to a User-Agent header.

The current model families make this distinction clearer because they support different combinations of capability and cost:

ModelPractical role in an agent workflowDoes model choice directly fix an email-leaking HTTP header?
Claude Fable 5.1High-capability work with a large context windowNo
Claude Opus 5.5Complex reasoning, architecture, and difficult multi-step tasksNo
Claude Sonnet 5Balanced performance for routine coding-agent workloadsNo
Claude Haiku 4.5Lower-latency or lower-cost handling of simple tasksNo
GPT-6 Astra / GPT-6 SolAlternative agent and application workflows with different tool ecosystemsNo
Gemini 3Multimodal and Google-centered application integrationsNo

A stronger model may produce better code, but it cannot sanitize a request made after the model returns a tool call. Likewise, a cheaper model does not make an unsafe client safe. The relevant architecture is:

# The model proposes a tool call
tool_call = model.generate(...)

# The runtime constructs the outbound request
headers = {
    "User-Agent": build_user_agent(user),
    "Authorization": f"Bearer {token}",
}

response = requests.get(
    tool_call["url"],
    headers=headers,
    timeout=30,
)

The disclosure occurs in build_user_agent(user). The model selected the destination, but the client supplied the identifying value.

For teams that need to route requests across Claude, GPT, and Gemini models, using an API gateway or aggregation layer can simplify policy enforcement. AI Prime Tech is useful in that context for cheaper Claude/GPT/Gemini API access, especially when requests are normalized through one integration. The point is not that aggregation automatically provides privacy; it is that a single layer can enforce rules such as stripping User-Agent values, blocking sensitive headers, and recording destination-specific audit logs.

How to check and protect your environment

Start by identifying every email-like value in the agent environment:

git config --global user.email || true
git config user.email || true
env | grep -Ei '(^|_)(email|user|account|identity)' || true

Then inspect actual outbound requests rather than relying only on configuration files. A local proxy is a practical way to observe headers:

# Example: run the agent through a local proxy
HTTPS_PROXY=http://127.0.0.1:8888 claude

# Or use a custom HTTP client in a test harness
python - <<'PY'
import requests

response = requests.get(
    "https://example.com",
    headers={"User-Agent": "ClaudeCode/test email@example.com"},
    timeout=10,
)
print(response.status_code)
PY

In a controlled test, inspect the request in a proxy log or with a local debugging server. The goal is to verify that no account email appears in:

User-Agent
Referer
X-Forwarded-For
Custom X-* headers
Query strings
Cookie values

For production teams, the stronger controls are:

  1. Use a generic User-Agent. Send a product name and version, not an account identity.
  2. Keep credentials scoped. Use short-lived tokens and separate tokens for each destination.
  3. Block accidental secret propagation. Maintain a denylist for email addresses, API keys, and organization identifiers.
  4. Log destinations, not payloads. Record the hostname, method, status, and timestamp before retaining request bodies.
  5. Apply tool-specific policies. A package registry, browser search, and internal API may need different headers and retention rules.
  6. Test the agent, not just the model. Include privacy assertions in integration tests.

A simple test can be added to a CI pipeline:

def test_outbound_headers_do_not_contain_account_email():
    headers = build_headers(user_email="developer@example.com")
    serialized = " ".join(f"{key}: {value}" for key, value in headers.items())

    assert "developer@example.com" not in serialized
    assert "email" not in serialized.lower()

The larger lesson

The Claude Code email disclosure is easy to describe as a header bug. That description is accurate, but incomplete. The deeper issue is that agentic software increasingly has two identities: the model’s context and the client’s metadata.

Even a perfectly prompted model can’t prevent the surrounding program from leaking information. Conversely, a sanitized prompt can still travel alongside an identifying header. Developers need to evaluate the full request path, including tool wrappers and third-party destinations.

The most effective fix is not merely “don’t send the email.” It is to make data minimization the default: an agent should send only what the destination requires, and should ask—or avoid the operation—before crossing a boundary with an account identifier.

Practical takeaways

C

Claude API publishes this blog. Articles are drafted with AI assistance; check version-specific details such as model IDs, prices and limits against the official documentation before relying on them.

Get cheaper Claude API access

One API key for Claude Opus 4.8, Sonnet 4.6, Haiku 4.5, Fable 5, plus GPT & Gemini — up to 80% off official pricing, pay-as-you-go.

Get Your API Key →
AI Prime Tech is an independent third-party API gateway. Claude™ and Anthropic® are trademarks of Anthropic, PBC. No affiliation or endorsement is implied.