Documentation

AI Proxies is a single HTTP/SOCKS5 gateway in front of four egress products. There is no SDK to install: you authenticate with a proxy username and password, and every request can carry its own targeting flags.

Paid accounts only. There is no free tier. An account exists from signup, but proxy credentials are generated by the control plane only after a payment is confirmed. Until then the API answers 402 payment_required on every provisioning endpoint.

Quickstart

Buy a plan from the dashboard. Once payment clears you get an API key, a proxy username and a proxy password.

# 1. export the proxy URL
export PROXY_URL="http://USERNAME:PASSWORD@gate.aiproxies.dev:8000"

# 2. make a request
curl -x "$PROXY_URL" https://httpbin.org/ip

# 3. confirm the exit IP
curl -s -x "$PROXY_URL" https://api.ipify.org

Every response through the gateway carries the exit IP in X-AIP-IP, the resolved country in X-AIP-Country, and the session id (when pinned) in X-AIP-Session.

Billing & provisioning

Signing up creates an account and returns an API key, but no proxy credentials. Credentials are generated the moment a payment is confirmed, by one of:

StatusMeaningProxy access
pending_paymentAccount exists, payment not confirmedBlocked — 402
activePaid, credentials provisionedAllowed
suspendedCanceled subscription or AUP actionBlocked — 401

Provisioning is idempotent: a webhook retry, a refresh and a confirm call all converge on the same credentials and never rotate them.

Enterprise and invoicing. Enterprise plans are set up by sales. Operators can activate an account by hand once an invoice clears, using POST /api/admin with { "action": "activate", "accountId": "acc_…" }.

Authentication

Signing in

The dashboard accepts either your API key or a single-use sign-in link emailed to the address on the account. Request one with POST /api/auth/magic-link; the response is always 202 so the endpoint cannot be used to probe which emails have accounts. Links expire after 15 minutes, work once, and requests are throttled to one per address per minute.

Exchange the token from the link with POST /api/auth/exchange, which returns your existing API key (sealed at rest with AES-256-GCM, so it can be handed back without storing it in plaintext). A sign-in alert email is sent every time this succeeds.

Proxy credentials

The proxy username encodes targeting. The password is a per-account secret you can rotate from the dashboard at any time — rotating invalidates the old password immediately and does not affect your API key.

http://user-country-us-session-ab12-product-res:PASSWORD@gate.aiproxies.dev:8000
socks5://user-country-de:PASSWORD@gate.aiproxies.dev:1080

Control API

The control API is used by the dashboard and by your own tooling. Authenticate with the API key as a bearer token. Keys are shown once at creation and stored only as a SHA-256 hash.

curl https://aiproxies.dev/api/me \
  -H "Authorization: Bearer sk_live_..."

Gateway endpoint

ProductProtocolHostPort
All (HTTP/HTTPS)HTTP CONNECTgate.aiproxies.dev8000
All (SOCKS5)SOCKS5gate.aiproxies.dev1080
Dedicated ISPHTTP / SOCKS5isp.aiproxies.dev8000 / 1080

Region-specific entry points (us-gate, eu-gate, ap-gate) exist for latency-sensitive workloads and accept the same credentials.

Username flags

Flags are dash-separated, lowercase, and order-independent. Unknown flags are rejected with auth_failed rather than ignored, so a typo cannot silently change your egress.

FlagValuesExampleNotes
country-ISO 3166-1 alpha-2country-deDefaults to random if omitted
region-Provider region coderegion-bavariaResidential only
city-Lowercase city slugcity-berlinAvailability varies
asn-AS numberasn-3320Residential only
session-[a-z0-9]{1,32}session-ab12Pins one IP for 30 min
product-res · isp · mob · dcproduct-ispDefaults to res
sticky-minutes, 1–30sticky-10Overrides session TTL

Flags are additive. A request with country-us-session-ab12-product-isp exits from a US ISP address and keeps that address across requests until the session expires.

Header flags

When the client cannot express a username (some frameworks mangle special characters), send the same values as request headers. Headers win over username flags.

X-AIP-Country: jp
X-AIP-City: tokyo
X-AIP-Session: ab12
X-AIP-Product: res

Sticky sessions

Sessions are named, not allocated: the first request for a session id claims an exit IP, and subsequent requests reuse it until the TTL expires or POST /api/sessions/{id}/release is called. There is no hard cap on how many sessions a key can create, but concurrent in-flight connections are capped by plan.

Control API

MethodPathPurpose
POST/api/auth/magic-linkEmail a single-use sign-in link (always 202)
POST/api/auth/exchangeTrade a sign-in token for the account's API key
POST/api/signupCreate an account in pending_payment; returns the API key once
POST/api/checkoutStart or restart a Stripe Checkout session for the account's plan
POST/api/checkout/confirmVerify a Stripe session id and provision on success
GET/api/meAccount, plan, status, usage and (once paid) proxy credentials
POST/api/rotateRotate the proxy password (active accounts only)
GET/api/proxiesGateway list for the account's plan (active accounts only)
POST/api/usageReport metered traffic (gateway → control plane)
POST/api/webhooks/stripeSigned Stripe events; activates on payment, suspends on cancellation
POST/api/leadContact sales / enterprise request

All responses are JSON. Errors use { "error": "code", "message": "human readable" } with a matching HTTP status.

Webhook

POST /api/webhooks/stripe verifies the Stripe-Signature header against the raw request body with a 5-minute tolerance. It handles checkout.session.completed, invoice.paid (renewals), invoice.payment_failed (dunning email) and customer.subscription.deleted (suspends the account). Valid signatures always receive 200, including for event types the service ignores, so Stripe stops retrying.

Email

Every state change sends a transactional email: account created with the checkout link, payment confirmed with credentials and a first-request snippet, payment failed, plan canceled, account suspended, password rotated, sign-in link, sign-in alert, and lead notifications. Delivery goes through Resend when RESEND_API_KEY is set; otherwise emails are written to an outbox and logged, which is how local development and the test suite read sign-in links.

Error codes

CodeStatusMeaningRetry?
auth_failed407Bad username flags or rotated passwordNo
payment_required402Account has no active plan; credentials not provisionedNo — complete payment
quota_exceeded402Request or bandwidth cap reachedNo — raise the cap
geo_unavailable422No peer matches the requested targetingNo — widen targeting
blocked403Target rejected the exit IP; gateway already retried onceYes, with a new session
target_timeout504Target did not respond within 30 sYes, once
concurrency_limited429In-flight connections exceed planYes, with backoff
upstream_error502Peer failed mid-requestYes

Through the proxy, the code is duplicated in the X-AIP-Error response header and in the JSON body when the target is HTTPS. Branch on the code, never on the HTML.

Usage metering

curl https://aiproxies.dev/api/me \
  -H "Authorization: Bearer sk_live_..."

{
  "accountId": "acc_9f2c",
  "status": "active",
  "plan": { "name": "Starter", "price": 49, "quota": 200000 },
  "usage": { "requests": 148, "gb": 0.31 },
  "limits": { "requestsPerMonth": 200000, "gbPerMonth": 10, "concurrency": 20 },
  "proxy": { "username": "user-product-res", "host": "gate.aiproxies.dev" }
}

While an account is in pending_payment, proxy is null and paymentRequired is true. Counters are near real-time (under 60 s lag).

Tool schema

Give the model one tool instead of a proxy string. This schema works with the OpenAI, Anthropic and Gemini function-calling formats with no changes.

{
  "name": "egress_fetch",
  "description": "Fetch a URL through a chosen egress region and return the status, final URL, body and exit IP.",
  "input_schema": {
    "type": "object",
    "properties": {
      "url": { "type": "string", "description": "Absolute https URL" },
      "country": { "type": "string", "description": "ISO 3166-1 alpha-2, e.g. de" },
      "product": { "type": "string", "enum": ["res", "isp", "mob", "dc"] },
      "session": { "type": "string", "description": "Reuse an id to keep the same exit IP" }
    },
    "required": ["url"]
  }
}

Return a compact object — {status, finalUrl, exitIp, error, body} — so the model reasons over results, not connection details. Keep the body truncated (for example 8 KB) to protect the context window.

Agent patterns

Rotate per request, pin per task

Use no session flag for broad discovery calls and a deterministic session id (task id, or hash of the seed URL) for multi-step flows such as login → cart → checkout. A pinned session that succeeds is worth keeping for the whole task.

Retry with intent

Cap before you ship

Set the per-key request ceiling just above your expected task cost. The gateway returns 402 instead of billing, which turns a runaway loop into a handled failure.

Rate limits

PlanConcurrent connectionsRequests / minControl API
Starter201,200120 / min
Scale20012,000600 / min
EnterpriseCustomCustomCustom

Rate-limit responses include Retry-After. The control API is rate-limited per key, not per IP.

Logging & privacy

Request bodies, response bodies, headers and target content are never stored. We retain connection metadata — key, timestamp, exit IP, bytes, hostname, status — for 24 hours for abuse handling and billing reconciliation, then delete it. Privacy policy · Acceptable use

Questions about a specific integration? support@aiproxies.dev.