App Proxy

Claude or ChatGPT Flagging "Unusual Activity" on a Proxy? Pin One Exit IP

The proxy works. Connections shows rows for claude.ai or chatgpt.com. The request returns a status code. Then the page hands you "We detect suspicious activity", "Access denied", a surprise phone-verification prompt, or a session that silently drops. This is not a timeout: traffic left your machine, and the exit IP got judged risky. Ports, Tun, and env vars have no leverage on that.

Base setup lives elsewhere on this site and is not repeated here: web and Desktop in Claude.ai / Desktop, terminal in Claude Code behind a proxy, ChatGPT web and unsupported_country in ChatGPT access. This page covers one thing: exit-IP quality, and how to pin it in Clash Verge.

Read the message before you touch the config

Every fix below assumes the path already works. Confirm that first: a request that returns any HTTP status from the target domain means egress is fine. If the request never reaches the domain—no connection rows, a spinner that times out—this is a routing problem, not an IP-reputation problem, and the table in the next section will mislead you. Fix egress, then come back.

Separate "path is broken" from "exit is flagged"

The two call for opposite actions — one wants a config change, the other wants a stable exit and a pause. Three data points tell them apart.

What you see Connections Class Action
Spinner, connection timeout No rows for the domain Path never opened Check Tun / system proxy / port — do not swap nodes
unsupported_country_region_territory (403) Rows, 403 returned Exit region unsupported Move to a supported-region node
Access denied / Error 1020 Rows, rejected at the edge Exit IP blocklisted Another node in the same region
Error 1015 Rows, 429-class IP rate limited Stop for ~10 minutes, no retry storm
Unusual Activity Detected Rows, page renders fine IP reputation + session anomaly Pin one exit, then re-login on a clean session
Logged out, phone verification Rows, exit IP differs across requests Session crossed IPs Disable auto-switching for AI domains

OpenAI's own troubleshooting article puts "disable VPNs or proxies that might route your traffic through flagged IPs" at the top of the suspicious-activity section. Read that backwards and it is useful: the vendor is telling you the prompt is usually about the exit IP, not your account.

What AI services read off your exit IP

Risk scoring looks at a bundle of correlated signals, and a shared node trips several at once.

  • Range type. Datacenter and residential ranges are cleanly separated in public databases. Datacenter exits are not banned outright, but they carry a higher scrutiny weight — identical behaviour triggers verification sooner.
  • Account density per IP. Dozens of users behind one exit means someone eventually runs automation, and that history attaches to the range. Your normal chat lands in the same correlation bucket.
  • Exit region vs account region. An account registered with a US number that normally exits in the US, suddenly arriving from Singapore, is an impossible-travel event. Occasional means re-verification; repeated cross-region hopping reads as credential compromise.
  • IP churn inside a session. The one you most likely caused yourself. Early requests in a conversation leave via exit A, later ones via exit B, and the server sees the session relocate mid-flight.
  • Dense retries after a rejection. Every node swap is a fresh IP presenting the same credential. That shape is indistinguishable from credential-stuffing probes.

Put together: a 180 ms node you never leave is safer for AI services than a pool of 60 ms nodes that reselects itself. Latency and IP reputation are independent axes, and latency testing only measures the first one.

Dedicated vs shared: the lever you actually control

Among the signals above, range type and account density are the only two a provider's plan choice shifts. A node marketed as native-IP or dedicated carries a single tenant's reputation instead of a hundred; it will not be on a blocklist from someone else's automation. That does not make it immune—a dedicated IP that you then churn across regions loses the benefit—but it removes the part of the risk you cannot see. When the same-region shared node keeps triggering challenges after a week of clean use, the plan type, not the config, is the ceiling. Selection criteria live in choosing a provider.

url-test and fallback are manufacturing your problem

Auto-select groups exist to chase whatever is fastest. url-test probes on its interval and switches when the gap exceeds tolerance; fallback moves down the list when the current node fails a health check. Great for general browsing. On an AI session it produces this:

  1. You are mid-conversation, a scheduled probe moves the group to a node in another country, and your next message leaves from a new IP.
  2. The page either throws a challenge or bounces you to the login screen.
  3. You read that as node instability and click two more nodes — two more IP changes.

Load balancing hides the same trap. load-balance defaults to consistent-hashing, which maps a destination address to a fixed member and looks stable enough. But the mihomo docs note that domain targets are matched at the top-level-domain level, and a single AI session touches the app domain, static-asset domains, and the challenge domain — which can land on different members. round-robin rotates every new connection, so keep it away from AI traffic entirely.

If you genuinely want to spread across a few nodes, mihomo offers sticky-sessions: requests sharing the same source and target address go to the same member, with the mapping cached for about ten minutes before reassessment. That is closer to real session affinity than hashing, but ten minutes is still shorter than a long working session. For actual stability, use a select group with one node you chose by hand.

Pin one exit for AI domains in Clash Verge

Add a manual group, route AI domains into it by rule, and make sure that rule sits above the provider's own ruleset. Where you do it depends on your version. In v1.6.x the Merge config accepted append keys such as prepend-proxy-groups and prepend-rules. Since v1.7.x, Merge was renamed Extended Configuration and the official docs state it only overrides/merges config keys — list values like proxy-groups and rules get replaced wholesale, and prepend/append moved into the per-profile visual editor (official Extend docs). On current builds: right-click the profile you use, choose Edit Proxy Groups, and add a group in the prepend area:

  - name: AI-Fixed
    type: select
    proxies:
      - US-A-01
      - US-A-02
      - JP-B-03

Then right-click the same profile, choose Edit Rules, and put these into the prepend area (one per line; the editor places them ahead of the subscription rules for you):

  - DOMAIN-SUFFIX,anthropic.com,AI-Fixed
  - DOMAIN-SUFFIX,claude.ai,AI-Fixed
  - DOMAIN-SUFFIX,claudeusercontent.com,AI-Fixed
  - DOMAIN-SUFFIX,openai.com,AI-Fixed
  - DOMAIN-SUFFIX,chatgpt.com,AI-Fixed
  - DOMAIN-SUFFIX,oaistatic.com,AI-Fixed
  - DOMAIN-SUFFIX,oaiusercontent.com,AI-Fixed
  - DOMAIN-SUFFIX,challenges.cloudflare.com,AI-Fixed

Three things people miss. The names under proxies must exist in your subscription — copying the placeholders above yields an empty group (see blank proxy groups). Static-asset and challenge domains belong in the same group as the app domain, otherwise the page body arrives from exit A while the challenge script arrives from exit B and Cloudflare sees two origins. After saving, reselect the profile or reconnect the core so the edit applies; editor entry points and rule precedence are covered in Merge custom rules. If you prefer code, the equivalent path is an Extended Script: inside main(config), spread the new group into config['proxy-groups'] and the new lines into config.rules.

When you really do need to spread across two or three same-region nodes, add a sticky group in the same Edit Proxy Groups editor:

  - name: AI-Sticky
    type: load-balance
    strategy: sticky-sessions
    url: https://www.gstatic.com/generate_204
    interval: 600
    lazy: true
    proxies:
      - US-A-01
      - US-A-02

Stretch interval to cut background probing, and keep lazy: true so it does not test while idle. List AI-Sticky as a candidate inside AI-Fixed, but keep a single hand-picked node as the daily default and fall back to the sticky group only when that node clearly degrades. Rule ordering and routing syntax: rules and routing.

Confirm the pin actually took effect

Saving the override changes nothing until the core reloads, and a silent precedence bug can leave your rules dead. Verify rather than assume:

  1. Reselect the profile (or toggle the core off/on) so the prepend rules load.
  2. Open Connections, clear the list, then send one message in the AI tool.
  3. Read the rule column on that row. It should read your AI-Fixed group, not GEOIP or MATCH.
  4. Run the trace loop and confirm a single stable ip= across six samples (the same command appears in the challenge-loop guide: human verification loops).

If the rule column shows the catch-all, the prepend did not land ahead of the subscription rules—re-check the editor order in Merge custom rules.

Filter clean nodes out of the subscription you already have

No new purchase required. Test one node for a full twenty minutes before judging it — clicking five nodes in a minute only measures the churn you just created.

  1. Select one node manually, open the service in a private window, and complete a full login plus one message.
  2. If it passes, stay on that node and work normally for twenty minutes, watching for challenges or dropped sessions.
  3. On an Access denied, note the node name, mark it unusable, and move to another in the same region.
  4. Keep the two or three nodes that stayed clean across two separate days, and put only those in proxies.
  5. Prefer the region your account was registered in. A US account on a US exit beats a lower-latency Japanese exit.

If nothing in the subscription survives twenty minutes, that is provider exit quality and config cannot fix it. Selection criteria and when to switch providers: choosing a provider. Smaller, less oversold plans and lines explicitly marketed as native-IP or dedicated tend to behave better here than high-volume budget shared nodes.

Once you are already flagged, work in this order

Sequence matters more than any single step. Leave time between them instead of stacking them.

  1. Stop. No retries, no node swaps. A retry storm after a rejection feeds IP churn and repeated failed authentications into the model together.
  2. Classify the message. Use the table above to rule out the 403 region block and the 1020 blocklist first — both are exit-side and have nothing to do with your account.
  3. Pin one exit. Hand-select one of the nodes you filtered, and confirm AI domains resolve to the select group with auto-switching off on that path.
  4. Enter on a clean session. Clear cookies and site data for that domain, disable ad-blocking and privacy extensions, and log in again from a private window. A session that already crossed IPs is itself the anomaly; reusing it just repeats the signal.
  5. Wait. IP-level rate limits and temporary rejections expire on their own — Cloudflare's 1015 is exactly that. Coming back hours later beats knocking continuously.
  6. Then use the official channel. Claude: sign in and file the appeal form; when an organization is paused for unusual activity, the restricted screen offers "Request a review"; Usage Policy warnings go to [email protected]. ChatGPT: the Help Center troubleshooting article tells you to report the issue if you are not running bots or automation. Send the account email, the verbatim error, and a factual use-case description.

These waste your time or make things worse: node-hopping on retry (a new IP knocking with the same credential each time), switching to Global mode so even more domains ride the same dirty IP, reinstalling the client (local config has no bearing on IP reputation), and dropping interval to 30 seconds hoping to find a working node faster — that just rotates your exit twice a minute. Flipping between Tun and system proxy belongs to the path layer, covered in Tun for AI tools.

What this page does not fix

Stating the boundary saves you wasted attempts. If an account was disabled for policy violations, no configuration change reverses it. Anthropic support lists repeated Usage Policy violations, account creation from an unsupported location, and Terms of Service violations side by side as ban reasons; the last two are facts fixed at signup and are unrelated to whichever node you use today. Whether an appeal succeeds is the platform's call, and no proxy setup improves those odds.

Also out of scope: rotating multiple accounts to stretch quota, registering accounts for regions the provider does not serve, and third-party tooling that impersonates an official client's request signature. Those either breach the terms outright or are themselves ban triggers, and there is no meaningful appeal afterwards.

This page covers exactly one case: you are a compliant free or paid user whose traffic gets misread as risky because a shared exit IP is dirty or unstable. Pin the exit, pick clean IPs, and stop letting the config generate churn on your behalf. Latest builds are in the download center, and remember to refresh the subscription once after editing the override.

Pinning an exit needs a client with policy groups

A dedicated group for AI domains, with auto-switching disabled, lives in the config layer. Grab the latest Clash Verge Rev from the download center, then apply the Merge override below.