🌐 OmniRoute Proxy Guide
Bypass geographic blocks, protect your identity, and route AI traffic through any proxy — with zero configuration complexity.
OmniRoute includes a full-featured proxy management system that lets you route upstream AI provider traffic through HTTP, HTTPS, or SOCKS5 proxies. Whether you’re in a blocked region, need IP rotation, or want stealth fingerprinting — this guide covers everything.
Table of Contents
Section titled “Table of Contents”- Why Use Proxies?
- Architecture Overview
- 4-Level Proxy System
- Proxy Registry (CRUD)
- 1proxy Free Marketplace
- Proxy Rotation
- Anti-Detection & Stealth
- Upstream Proxy Modes
- Dashboard UI
- API Reference
- Environment Variables
- Troubleshooting
Why Use Proxies?
Section titled “Why Use Proxies?”Many AI providers restrict access by geographic region. Developers in Russia, China, Iran, Cuba, Turkey, and other countries encounter errors like:
unsupported_country_region_territoryEven outside blocked regions, proxies are useful for:
| Use Case | Description |
|---|---|
| Geographic bypass | Access OpenAI, Anthropic, Codex, Copilot from blocked countries |
| IP rotation | Distribute requests across multiple IPs to avoid rate limiting |
| Privacy | Hide your real IP from upstream providers |
| Compliance | Route traffic through specific jurisdictions |
| Testing | Simulate requests from different regions |
Architecture Overview
Section titled “Architecture Overview”┌───────────────────────────────────────────────────────────────┐│ OmniRoute Server ││ ││ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ ││ │ Proxy │ │ Proxy │ │ Proxy │ ││ │ Registry │───▶│ Dispatcher │───▶│ Fetch (undici) │ ││ │ (SQLite) │ │ (cached) │ │ │ ││ └─────────────┘ └──────────────┘ └────────┬─────────┘ ││ ▲ │ ││ │ ▼ ││ ┌──────┴──────┐ ┌──────────────────┐ ││ │ 1proxy Sync │ │ Upstream │ ││ │ (free pool) │ │ Provider API │ ││ └─────────────┘ └──────────────────┘ │└───────────────────────────────────────────────────────────────┘Key Components
Section titled “Key Components”| Component | File | Role |
|---|---|---|
| Proxy Registry | src/lib/db/proxies.ts |
CRUD for proxy entries + scope assignments |
| Proxy Dispatcher | open-sse/utils/proxyDispatcher.ts |
Creates undici ProxyAgent/SOCKS dispatchers with caching |
| Proxy Fetch | open-sse/utils/proxyFetch.ts |
Wraps fetch() with proxy dispatcher injection |
| Settings Route | src/app/api/settings/proxy/route.ts |
Legacy proxy config API (GET/PUT/DELETE) |
| Management Route | src/app/api/v1/management/proxies/route.ts |
Registry CRUD API (GET/POST/PATCH/DELETE) |
| 1proxy DB | src/lib/db/oneproxy.ts |
Free proxy marketplace persistence |
4-Level Proxy System
Section titled “4-Level Proxy System”OmniRoute supports proxy configuration at four independent scopes, resolved in priority order:
Priority Resolution Order (highest → lowest):
1. 🔵 Account/Connection Proxy → per API key / OAuth connection 2. 🟡 Provider Proxy → per provider (e.g., all OpenAI traffic) 3. 🟠 Combo Proxy → per combo/routing configuration 4. 🟢 Global Proxy → all traffic, all providersHow Resolution Works
Section titled “How Resolution Works”When OmniRoute sends a request to an upstream provider, it calls resolveProxyForConnectionFromRegistry() which checks each level in order:
- Account-level — Is there a proxy assigned to this specific connection ID?
- Provider-level — Is there a proxy assigned to this provider (e.g.,
openai)? - Global-level — Is there a global proxy configured?
- No proxy — Direct connection to the provider.
The first match wins. This means you can set a global proxy as a fallback but override it for specific providers or connections.
What Gets Proxied
Section titled “What Gets Proxied”| Traffic Type | Proxied? | Notes |
|---|---|---|
| Chat completions | ✅ | All /v1/chat/completions requests |
| Embeddings | ✅ | /v1/embeddings |
| Image generation | ✅ | /v1/images/generations |
| Audio (TTS/STT) | ✅ | /v1/audio/* |
| OAuth token exchange | ✅ | Solves unsupported_country_region_territory |
| Connection tests | ✅ | “Test Connection” button uses proxy |
| Token refresh | ✅ | Background OAuth renewal |
| Model sync | ✅ | Model listing and discovery |
Proxy Registry (CRUD)
Section titled “Proxy Registry (CRUD)”The proxy registry is a SQLite table (proxy_registry) that stores all your proxies. Each proxy has:
| Field | Type | Description |
|---|---|---|
id |
UUID | Unique identifier |
name |
String | Human-readable label |
type |
String | Protocol: http, https, socks5 |
host |
String | Proxy hostname or IP |
port |
Integer | Port number |
username |
String | Auth username (encrypted at rest) |
password |
String | Auth password (encrypted at rest) |
region |
String | Geographic region label |
notes |
String | Free-text notes |
status |
String | active or inactive |
source |
String | manual or oneproxy |
Creating a Proxy
Section titled “Creating a Proxy”Via Dashboard:
- Go to Settings → Proxy
- Click Add Proxy
- Fill in the type, host, port, and optional auth credentials
- Save
Via API:
curl -X POST http://localhost:20128/api/v1/management/proxies \ -H "Content-Type: application/json" \ -d '{ "name": "US Proxy", "type": "http", "host": "proxy.example.com", "port": 8080, "username": "user", "password": "pass", "region": "US" }'Updating a Proxy
Section titled “Updating a Proxy”curl -X PATCH http://localhost:20128/api/v1/management/proxies \ -H "Content-Type: application/json" \ -d '{ "id": "proxy-uuid-here", "host": "new-proxy.example.com", "port": 9090 }'Note: Credentials are preserved unless you explicitly send non-empty replacements. Sending empty strings for
username/passwordwill keep the stored values.
Deleting a Proxy
Section titled “Deleting a Proxy”# Fails if proxy is assigned to any scopecurl -X DELETE "http://localhost:20128/api/v1/management/proxies?id=proxy-uuid"
# Force delete (removes assignments too)curl -X DELETE "http://localhost:20128/api/v1/management/proxies?id=proxy-uuid&force=1"Listing Proxies
Section titled “Listing Proxies”curl "http://localhost:20128/api/v1/management/proxies?limit=50&offset=0"Assigning Proxies to Scopes
Section titled “Assigning Proxies to Scopes”# Assign to global scopecurl -X PUT http://localhost:20128/api/settings/proxy \ -H "Content-Type: application/json" \ -d '{"level": "global", "proxy": {"type":"http","host":"proxy.example.com","port":8080}}'
# Assign to a specific providercurl -X PUT http://localhost:20128/api/settings/proxy \ -H "Content-Type: application/json" \ -d '{"level": "provider", "id": "openai", "proxy": {"type":"socks5","host":"socks.example.com","port":1080}}'
# Assign to a specific connection/keycurl -X PUT http://localhost:20128/api/settings/proxy \ -H "Content-Type: application/json" \ -d '{"level": "key", "id": "connection-uuid", "proxy": {"type":"http","host":"key-proxy.com","port":3128}}'Resolving Effective Proxy
Section titled “Resolving Effective Proxy”Check which proxy would be used for a given connection:
curl "http://localhost:20128/api/settings/proxy?resolve=connection-uuid"Returns the resolved proxy with its level (account, provider, or global) and source.
Bulk Assignment
Section titled “Bulk Assignment”Assign one proxy to multiple providers or connections at once:
curl -X POST http://localhost:20128/api/v1/management/proxies/bulk-assign \ -H "Content-Type: application/json" \ -d '{ "scope": "provider", "scopeIds": ["openai", "anthropic", "codex"], "proxyId": "proxy-uuid" }'Import/Export
Section titled “Import/Export”Proxies are included in the Backup/Restore system. When you export your OmniRoute configuration:
- Go to Dashboard → Settings → Backup
- Click Export — proxy registry and assignments are included
- To restore, click Import and upload the backup file
The proxy registry also supports upsert by host+port — if you import a proxy that already exists (same host and port), it updates instead of creating a duplicate.
Legacy Migration
Section titled “Legacy Migration”If you configured proxies in an older version (pre-registry), OmniRoute automatically migrates them:
Legacy key_value store → proxy_registry + proxy_assignmentsThis happens once on first startup after upgrade. Use migrateLegacyProxyConfigToRegistry({ force: true }) to re-run.
1proxy Free Proxy Marketplace
Section titled “1proxy Free Proxy Marketplace”OmniRoute integrates with the 1proxy community platform to provide access to hundreds of free, validated proxies from around the world. This is perfect for users who don’t have their own proxy infrastructure.
How It Works
Section titled “How It Works”┌─────────────┐ Sync ┌─────────────────┐ Rotate ┌──────────┐│ 1proxy API │ ────────────▶ │ proxy_registry │ ────────────▶ │ Provider ││ (external) │ up to 500 │ source=oneproxy │ by quality │ API │└─────────────┘ proxies └─────────────────┘ └──────────┘- Sync — OmniRoute fetches validated proxies from the 1proxy API
- Store — Proxies are saved in the same
proxy_registrytable withsource = 'oneproxy' - Filter — Filter by protocol, country, quality score
- Rotate — Pick the best proxy using quality, random, or sequential strategies
- Auto-degrade — Failed proxies get their quality score reduced; below threshold → marked inactive
Syncing Proxies
Section titled “Syncing Proxies”Via Dashboard:
- Go to Settings → 1proxy tab
- Click “Sync Now”
- View stats: total proxies, active count, average quality, by-country breakdown
Via API:
# Trigger synccurl -X POST http://localhost:20128/api/settings/oneproxy \ -H "Content-Type: application/json" \ -d '{}'
# Response:# { "success": true, "added": 127, "updated": 45, "failed": 2, "total": 172 }Filtering Proxies
Section titled “Filtering Proxies”# Filter by protocolcurl "http://localhost:20128/api/settings/oneproxy?protocol=socks5"
# Filter by countrycurl "http://localhost:20128/api/settings/oneproxy?countryCode=US"
# Filter by minimum quality scorecurl "http://localhost:20128/api/settings/oneproxy?minQuality=80"
# Combine filterscurl "http://localhost:20128/api/settings/oneproxy?protocol=http&countryCode=DE&minQuality=70"Proxy Quality Scores
Section titled “Proxy Quality Scores”Each 1proxy proxy comes with metadata:
| Field | Description |
|---|---|
qualityScore |
0-100 rating from 1proxy validation |
latencyMs |
Measured network latency |
anonymity |
transparent, anonymous, or elite |
googleAccess |
Whether the proxy can access Google services |
countryCode |
Two-letter ISO country code |
lastValidated |
Timestamp of last validation |
Quality scores are dynamically adjusted:
- Failed requests reduce the score by 10 points
- Score drops to ≤10 → proxy is marked
inactive - Inactive proxies are excluded from rotation
Rotation Strategies
Section titled “Rotation Strategies”# Rotate by quality (best proxy first) — defaultcurl -X POST http://localhost:20128/api/settings/oneproxy/rotate \ -H "Content-Type: application/json" \ -d '{"strategy": "quality"}'
# Random rotationcurl -X POST http://localhost:20128/api/settings/oneproxy/rotate \ -d '{"strategy": "random"}'
# Sequential (least recently validated first)curl -X POST http://localhost:20128/api/settings/oneproxy/rotate \ -d '{"strategy": "sequential"}'Circuit Breaker
Section titled “Circuit Breaker”The 1proxy sync has a built-in circuit breaker:
- After 5 consecutive sync failures, further sync attempts are blocked
- Reset with:
resetOneproxyCircuitBreaker()or restart the server - Sync status is available at
GET /api/settings/oneproxy?action=status
Clearing 1proxy Proxies
Section titled “Clearing 1proxy Proxies”# Delete a single 1proxy proxycurl -X DELETE "http://localhost:20128/api/settings/oneproxy?id=proxy-uuid"
# Clear ALL 1proxy proxies (manual proxies are untouched)curl -X DELETE "http://localhost:20128/api/settings/oneproxy?clearAll=1"Anti-Detection & Stealth
Section titled “Anti-Detection & Stealth”OmniRoute doesn’t just route traffic through a proxy — it makes the traffic look legitimate:
TLS Fingerprint Spoofing
Section titled “TLS Fingerprint Spoofing”Uses wreq-js to generate browser-like TLS fingerprints, bypassing bot detection systems that flag non-browser TLS handshakes.
CLI Fingerprint Matching
Section titled “CLI Fingerprint Matching”The CLI Fingerprint Toggle (Settings → Security) reorders HTTP headers and JSON body fields to match the exact signature of native CLI binaries (Claude Code, Codex, etc.). This works on top of the proxy:
Your IP (blocked) → Proxy IP (US) → Provider API + TLS spoof + CLI fingerprintYou get both IP masking and request authenticity simultaneously.
Proxy IP Preservation
Section titled “Proxy IP Preservation”Color-coded badges in the dashboard show which proxy level is active:
| Badge | Level | Meaning |
|---|---|---|
| 🟢 | Global | All traffic goes through this proxy |
| 🟡 | Provider | Only this provider’s traffic is proxied |
| 🔵 | Connection | This specific key/account uses this proxy |
The badge also shows the resolved proxy IP for verification.
Upstream Proxy Modes
Section titled “Upstream Proxy Modes”For providers that use the CLIProxyAPI pattern, OmniRoute supports three upstream proxy modes:
| Mode | Description |
|---|---|
native |
OmniRoute handles proxy routing directly (default) |
cliproxyapi |
Delegates to an external CLIProxyAPI instance |
fallback |
Tries native first, falls back to CLIProxyAPI |
Configure per-provider:
curl -X PUT "http://localhost:20128/api/upstream-proxy/openai" \ -H "Content-Type: application/json" \ -d '{"mode": "native", "enabled": true}'Dashboard UI
Section titled “Dashboard UI”Settings → Proxy Tab
Section titled “Settings → Proxy Tab”- Global proxy configuration (set once for all traffic)
- Per-provider proxy overrides
- Per-connection proxy assignments
- Connection test through configured proxy
- Color-coded badges showing active proxy level
Settings → 1proxy Tab
Section titled “Settings → 1proxy Tab”- Sync Now button to fetch free proxies
- Stats cards: Total, Active, Avg Quality, Last Sync
- Filters: Protocol, Country Code, Min Quality
- Proxy table with host, protocol, country, quality score, latency, anonymity, Google access
- Sync status panel with success/failure tracking and consecutive failure count
- Clear All to remove all 1proxy entries
API Reference
Section titled “API Reference”Proxy Settings API
Section titled “Proxy Settings API”| Method | Endpoint | Description |
|---|---|---|
GET |
/api/settings/proxy |
Get full proxy config |
GET |
/api/settings/proxy?level=global |
Get global proxy |
GET |
/api/settings/proxy?level=provider&id=openai |
Get provider proxy |
GET |
/api/settings/proxy?resolve=connectionId |
Resolve effective proxy |
PUT |
/api/settings/proxy |
Update proxy config |
DELETE |
/api/settings/proxy?level=provider&id=openai |
Remove proxy at level |
Proxy Registry API
Section titled “Proxy Registry API”| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/management/proxies |
List all proxies |
GET |
/api/v1/management/proxies?id=uuid |
Get proxy by ID |
GET |
/api/v1/management/proxies?id=uuid&where_used=1 |
Get proxy assignments |
POST |
/api/v1/management/proxies |
Create proxy |
PATCH |
/api/v1/management/proxies |
Update proxy |
DELETE |
/api/v1/management/proxies?id=uuid |
Delete proxy |
DELETE |
/api/v1/management/proxies?id=uuid&force=1 |
Force delete |
POST |
/api/v1/management/proxies/bulk-assign |
Bulk assign |
GET |
/api/v1/management/proxies/assignments |
List assignments |
GET |
/api/v1/management/proxies/health |
Proxy health stats |
Tunnels API
Section titled “Tunnels API”For exposing your OmniRoute instance to the public internet (Cloudflare/ngrok/Tailscale) instead of routing outbound through a proxy, see TUNNELS_GUIDE.md. The tunnel REST API lives under /api/tunnels/{cloudflared,ngrok,tailscale}/* and is orthogonal to the outbound proxy chain documented above.
1proxy API
Section titled “1proxy API”| Method | Endpoint | Description |
|---|---|---|
GET |
/api/settings/oneproxy |
List 1proxy proxies |
GET |
/api/settings/oneproxy?action=stats |
Get stats + sync status |
GET |
/api/settings/oneproxy?action=status |
Get sync status only |
POST |
/api/settings/oneproxy |
Trigger sync |
POST |
/api/settings/oneproxy/rotate |
Rotate to next proxy |
DELETE |
/api/settings/oneproxy?id=uuid |
Delete one |
DELETE |
/api/settings/oneproxy?clearAll=1 |
Clear all |
Upstream Proxy API
Section titled “Upstream Proxy API”| Method | Endpoint | Description |
|---|---|---|
GET |
/api/upstream-proxy/:providerId |
Get upstream proxy config |
PUT |
/api/upstream-proxy/:providerId |
Set upstream proxy mode |
DELETE |
/api/upstream-proxy/:providerId |
Remove upstream proxy config |
Environment Variables
Section titled “Environment Variables”| Variable | Default | Description |
|---|---|---|
ENABLE_SOCKS5_PROXY |
true |
Enable SOCKS5 proxy support (default true in .env.example) |
Troubleshooting
Section titled “Troubleshooting”“SOCKS5 proxy is disabled”
Section titled ““SOCKS5 proxy is disabled””Set ENABLE_SOCKS5_PROXY=true in your .env file and restart.
“socket hang up” errors through proxy
Section titled ““socket hang up” errors through proxy”This is normal with cheap proxies that drop idle connections. OmniRoute already handles this by:
- Disabling keep-alive on proxy connections (
keepAliveTimeout: 1) - Disabling pipelining (
pipelining: 0) - Caching dispatchers to avoid repeated handshakes
If it persists, try a different proxy or use the 1proxy rotation feature.
“unsupported_country_region_territory” during OAuth
Section titled ““unsupported_country_region_territory” during OAuth”Make sure the proxy is configured before starting the OAuth flow. OmniRoute routes OAuth token exchange through the configured proxy. Set a global or provider-level proxy first, then connect.
Proxy not being used
Section titled “Proxy not being used”Check the resolution order:
- Verify with
GET /api/settings/proxy?resolve=your-connection-id - Check if the proxy
statusisactive(notinactive) - Ensure the proxy assignment scope matches your connection
1proxy sync failing
Section titled “1proxy sync failing”Check the sync status:
curl "http://localhost:20128/api/settings/oneproxy?action=status"If consecutiveFailures >= 5, the circuit breaker has tripped. Restart the server to reset, or wait for manual reset.
Database Schema
Section titled “Database Schema”proxy_registry Table
Section titled “proxy_registry Table”CREATE TABLE proxy_registry ( id TEXT PRIMARY KEY, name TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'http', host TEXT NOT NULL, port INTEGER NOT NULL, username TEXT DEFAULT '', password TEXT DEFAULT '', region TEXT, notes TEXT, status TEXT DEFAULT 'active', source TEXT NOT NULL DEFAULT 'manual', -- 'manual' or 'oneproxy' quality_score INTEGER, -- 0-100 (1proxy only) latency_ms INTEGER, -- milliseconds (1proxy only) anonymity TEXT, -- transparent/anonymous/elite google_access INTEGER DEFAULT 0, -- can access Google? (1proxy) last_validated TEXT, -- ISO timestamp (1proxy) country_code TEXT, -- ISO 2-letter code (1proxy) created_at TEXT NOT NULL, updated_at TEXT NOT NULL);proxy_assignments Table
Section titled “proxy_assignments Table”CREATE TABLE proxy_assignments ( id INTEGER PRIMARY KEY AUTOINCREMENT, proxy_id TEXT NOT NULL REFERENCES proxy_registry(id), scope TEXT NOT NULL, -- 'global', 'provider', 'account', 'combo' scope_id TEXT, -- provider ID, connection ID, or combo ID created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(scope, scope_id));Proxy Health Checking (v3.8.16+)
Section titled “Proxy Health Checking (v3.8.16+)”OmniRoute’s proxy fast-fail mechanism (src/lib/proxyHealth.ts) detects dead proxies in <2s via a quick TCP connection check, then caches the result to avoid per-request overhead.
How It Works
Section titled “How It Works”Request ──▶ ProxyHealthCache.get(url) │ ├─ Cache hit + fresh? ──▶ return cached status │ └─ Cache miss / stale? ──▶ TCP connect to host:port (timeout: FAST_FAIL_TIMEOUT_MS) ──▶ cache for HEALTH_CACHE_TTL_MS ──▶ return resultWithout this, a dead proxy would block every request for the full PROXY_TIMEOUT_MS (default 30s) before failing.
Tunable Environment Variables
Section titled “Tunable Environment Variables”| Variable | Default | Purpose |
|---|---|---|
PROXY_FAST_FAIL_TIMEOUT_MS |
2000 |
TCP connection timeout per health check |
PROXY_HEALTH_CACHE_TTL_MS |
30000 |
How long a health result is cached |
Recommended values:
| Scenario | Fast-fail timeout | Cache TTL | Reasoning |
|---|---|---|---|
| High-throughput API gateway | 1500ms | 60000ms | Aggressive fail-fast, longer cache to reduce checks |
| Geo-distributed nodes | 3000ms | 15000ms | Slower networks need more time; shorter cache for fast failover |
| Dev / testing | 1000ms | 10000ms | Quick iteration on local proxies |
| Stealth / anti-detection | 2500ms | 45000ms | Avoid rapid probing that could trigger rate limits |
Inspecting Proxy Health
Section titled “Inspecting Proxy Health”import { getAllProxyHealthStatuses, invalidateProxyHealth } from "omniroute/proxyHealth";
const statuses = getAllProxyHealthStatuses();for (const s of statuses) { console.log(`${s.proxyUrl} → healthy=${s.healthy}, stale=${s.stale}`);}
// Force re-check a specific proxyinvalidateProxyHealth("http://user:pass@203.0.113.7:8080");The stale flag is true when the cache entry has exceeded HEALTH_CACHE_TTL_MS and the next request will trigger a fresh check.
Per-Proxy Type Defaults
Section titled “Per-Proxy Type Defaults”The health check uses sensible defaults based on the URL scheme:
| Scheme | Default port |
|---|---|
http:// |
8080 |
https:// |
443 |
socks5:// / socks5h:// |
1080 |
Custom ports in the URL (http://host:9999) always take precedence over the scheme default.
Proxy Analytics & Observability
Section titled “Proxy Analytics & Observability”OmniRoute tracks per-proxy usage to help operators diagnose routing patterns, latency spikes, and recurring failures.
What’s Tracked
Section titled “What’s Tracked”For every request through a configured proxy, OmniRoute records:
| Metric | Description |
|---|---|
proxy_url |
Full proxy URL (with auth credentials masked) |
provider |
Upstream provider ID (openai, anthropic, etc.) |
latency_ms |
Total round-trip time including proxy handshake |
connect_ms |
TCP connect time only |
status |
HTTP status code from upstream |
error |
Error class if request failed |
timestamp |
ISO 8601 UTC |
Accessing the Data
Section titled “Accessing the Data”# Recent proxy eventscurl -H "Authorization: Bearer $OMNIROUTE_KEY" \ "http://localhost:20128/api/usage/proxy-logs?limit=100"The real endpoint is /api/usage/proxy-logs (see src/app/api/usage/proxy-logs/route.ts). This endpoint supports:
GET /api/usage/proxy-logs— retrieve proxy logsDELETE /api/usage/proxy-logs— clear all proxy logs
Aggregate stats can be queried directly from the proxy_logs table via SQL if needed. The dashboard UI may offer aggregate views.
Common Patterns
Section titled “Common Patterns”Detect a flapping proxy (alternates between success/failure):
SELECT proxy_url, COUNT(*) AS total, SUM(CASE WHEN status >= 500 THEN 1 ELSE 0 END) AS errors, ROUND(100.0 * SUM(CASE WHEN status >= 500 THEN 1 ELSE 0 END) / COUNT(*), 1) AS error_pctFROM proxy_logsWHERE timestamp > datetime('now', '-1 hour')GROUP BY proxy_urlHAVING error_pct > 5ORDER BY error_pct DESC;Find slow proxies (p95 latency > 2s):
WITH ranked AS ( SELECT proxy_url, latency_ms, PERCENT_RANK() OVER (PARTITION BY proxy_url ORDER BY latency_ms) AS pct FROM proxy_logs WHERE timestamp > datetime('now', '-24 hour'))SELECT proxy_url, latency_msFROM rankedWHERE pct >= 0.95ORDER BY latency_ms DESC;Rotation Strategy Decision Tree
Section titled “Rotation Strategy Decision Tree”When multiple proxies are assigned to a scope, OmniRoute uses a rotation strategy to pick which one to use for each request. The strategy is configured at the scope level (global, per-provider, per-account, per-combo).
Available Strategies
Section titled “Available Strategies”| Strategy | When to use | Trade-off |
|---|---|---|
quality (default) |
Production with mixed-quality proxies | Favors high-rated proxies; may starve low-rated ones |
random |
Load distribution, privacy | Even distribution; ignores quality signals |
sequential |
Debugging, deterministic testing | Cycles through proxies in order; easy to reason about |
Decision Tree
Section titled “Decision Tree” Do you have quality scores for your proxies? │ ┌───────────┴───────────┐ │ │ YES NO │ │ Are all proxies │ roughly equal │ in quality? │ │ │ ┌────┴────┐ │ │ │ │ YES NO Use │ │ `random` │ │ (even spread │ │ builds quality │ │ data over time) │ │ │ Use `quality` │ (best for │ mixed quality) │Use `random`(spread loadevenly)Automatic Failure Exclusion for Your Own Proxies
Section titled “Automatic Failure Exclusion for Your Own Proxies”The 1proxy marketplace pool already auto-degrades failed proxies on its own (see
Proxy Quality Scores). For
proxies you added to the registry, the background health scheduler
(src/lib/proxyHealth/scheduler.ts) provides the same “exclude a dead member from
the chain automatically” behavior, without deleting anything:
# .env — soft-disable a proxy after 3 consecutive failed probes, re-enable it# automatically once it starts answering probes again.PROXY_AUTO_DISABLE=truePROXY_AUTO_REMOVE_AFTER=3How it fits into a multi-proxy chain:
- The scheduler probes every registered proxy every
PROXY_HEALTH_INTERVAL_MS(default 10 min; minimum 1 min). - After
PROXY_AUTO_REMOVE_AFTERconsecutive conclusive failures (a real connection failure — a timeout or the probe target’s own 5xx never counts, see Proxy Health Checking), the proxy’sstatusis set todead. deadis one of the statuses the alive-status filter used by pool/rotation resolution excludes, so a scope’s rotation (round-robin / random / sticky / latency — see Rotation Strategy Decision Tree) immediately stops handing that proxy to new requests. No other proxies in the pool are affected, and the whole pool never silently falls back to a direct connection — see the 4-Level Proxy System fail-closed guard.- The scheduler keeps probing
deadproxies on the same interval. The next successful probe flipsstatusback toactiveand it re-enters rotation — no manual re-add required.
This is deliberately opt-in and non-destructive: by default the scheduler only
counts and logs failures (see policy C in decision.ts), and PROXY_AUTO_DISABLE
never deletes a row — that is what the separate, more aggressive
PROXY_AUTO_REMOVE flag is for. If both are set to true, PROXY_AUTO_REMOVE
wins (a proxy about to be deleted has no use for a soft-disable in between). See
the Environment Config reference for the full
variable list.
📖 Related documentation:
- User Guide — General setup and configuration
- API Reference — Full API documentation
- Environment Config — All environment variables
HagiCode
HagiCode is an agentic coding workspace: structured workflows, multi-agent execution, and Hero Dungeon views turn ideas into shipped software.
Turn ideas into polished, usable software with a smarter, faster, and more enjoyable agentic coding workflow.

- SmartStructured workflows turn intent into an executable path from idea to shipped change.
- EfficientMulti-agent workflows keep research, implementation, and review moving in parallel.
- FunHero Dungeon interfaces make long coding sessions visual, collaborative, and rewarding.