User API
Buy plans, renew them and read your proxy credentials from your own code instead of clicking through the dashboard. Same account, same plans, same prices you see on the site.
https://catproxies.com/api/v1/userThis is your own account, automated. An API key does exactly what you can do yourself in the dashboard: browse the catalogue, buy a plan from your balance, read the credentials, renew it, rotate a password. It is not a reseller account, so there are no sub-customers and no separate panel. If you are looking to resell at wholesale prices, that is a different programme with its own reseller documentation. Everything you need for this API is on this page.
Authentication
Create a key under My Account, API Keys. Send it as a bearer token on every request.
Authorization: Bearer cp_your_api_key_here- Keys start with
cp_and stay visible in your dashboard, so you can always come back for one. - You can hold up to five. Disable one to pause it, or delete it to kill it for good. Either takes effect immediately.
- A key can spend your balance. Treat it like a password: keep it out of client-side code, public repositories and screenshots.
- Keys only reach the endpoints listed on this page. Your password, two-factor settings, sessions and account details are not reachable with a key at all.
How you pay
Everything bought through the API is paid from your account balance, so send "paymentMethod": "Balance" on purchases and renewals. There is no browser in the loop, so a card or crypto checkout has nowhere to go and is rejected rather than left half finished.
Top up on the Deposit Balance page, then check the figure with GET /account before a big run. Prices are the ordinary retail prices, and VAT is applied exactly as it is on the website.
Do not retry a purchase blindly. A purchase sets up a live plan and charges your balance, so it is not safe to repeat. If a call times out or you are unsure whether it landed, look for the order with GET /orders first. Retrying without checking can leave you paying for two plans.
Quick start
Buy a residential plan and read its credentials, end to end.
KEY="cp_your_api_key_here"
API="https://catproxies.com/api/v1/user"
# 1. Check the balance
curl -s -H "Authorization: Bearer $KEY" "$API/account"
# 2. Find a plan to buy
curl -s -H "Authorization: Bearer $KEY" \
"$API/packages?proxyType=v2resi&pageSize=50"
# 3. Buy it (paid from your balance)
curl -s -X POST "$API/purchase" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{ "packageId": "PACKAGE_ID_FROM_STEP_2", "paymentMethod": "Balance" }'
# 4. Read the credentials for the new plan
curl -s -H "Authorization: Bearer $KEY" "$API/orders/ORDER_ID_FROM_STEP_3"
# 5. Use them. The host is a fixed gateway per product, not part of the order:
# Standard Residential -> resi-us / resi-fr / resi-sg .catproxies.com
# See the per-product guide for the gateways, ports and targeting flags.
curl -x resi-us.catproxies.com:9000 \
-U "USERNAME-type-residential-country-us:PASSWORD" https://ipinfo.ioThe same thing in Python
import requests
KEY = "cp_your_api_key_here"
API = "https://catproxies.com/api/v1/user"
headers = {"Authorization": f"Bearer {KEY}"}
# Pick the cheapest Standard Residential plan
packages = requests.get(
f"{API}/packages",
headers=headers,
params={"proxyType": "v2resi", "pageSize": 50},
).json()["payload"]["packages"]
cheapest = min(packages, key=lambda p: p["price"])
# Buy it from the account balance
bought = requests.post(
f"{API}/purchase",
headers=headers,
json={"packageId": cheapest["id"], "paymentMethod": "Balance"},
).json()
if bought.get("type") == "error":
# If this is the "payment went through but setup did not finish" message,
# bought["payload"]["OrderId"] is your order. Never just retry the purchase.
raise SystemExit(bought["message"])
order_id = bought["payload"]["OrderId"]
# Read the proxy credentials
plan = requests.get(f"{API}/orders/{order_id}", headers=headers).json()
p = plan["payload"]["order"]["proxy"]
# Build a proxy URL. The host is the product's fixed gateway, not from the order.
GATEWAY = "resi-us.catproxies.com"
user = f"{p['username']}-type-residential-country-us"
proxy = f"http://{user}:{p['password']}@{GATEWAY}:9000"
print(requests.get("https://ipinfo.io", proxies={"http": proxy, "https": proxy}).json())And in Node
const KEY = "cp_your_api_key_here"
const API = "https://catproxies.com/api/v1/user"
const headers = { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" }
const call = async (path, init = {}) => {
const res = await fetch(`${API}${path}`, { ...init, headers })
const body = await res.json()
if (!res.ok || body.type === "error") throw new Error(body.message || res.statusText)
return body.payload
}
const { packages } = await call("/packages?proxyType=v2resi&pageSize=50")
const cheapest = packages.reduce((a, b) => (a.price < b.price ? a : b))
const { OrderId } = await call("/purchase", {
method: "POST",
body: JSON.stringify({ packageId: cheapest.id, paymentMethod: "Balance" }),
})
const plan = await call(`/orders/${OrderId}`)
const { username, password } = plan.order.proxy
// The host is the product's fixed gateway, not something the order carries.
const GATEWAY = "resi-us.catproxies.com"
console.log(`http://${username}-type-residential-country-us:${password}@${GATEWAY}:9000`)Rate limits
1000 requests per hour per key, on a rolling window. Every response carries the current state:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per hour |
X-RateLimit-Remaining | How many you have left |
X-RateLimit-Reset | When capacity comes back (ISO 8601) |
Go over and you get 429 with a Retry-After header. Back off rather than retrying in a tight loop.
Tighter limits on specific endpoints
These sit on top of the hourly budget and apply per account, not per key. Buying in bulk is the case that trips people up: put a short pause between orders rather than firing them off in parallel.
| Endpoint | Limit |
|---|---|
POST /purchase | 3 per minute |
POST /purchase/extend | 3 per minute |
POST /orders/:id/reset-password | 3 per minute |
Those three share one bucket. It is 3 requests a minute across all of them, counted per account rather than per key, and your own clicks in the dashboard count too. So buy, renew, rotate a password inside the same minute and the third or fourth call is refused with 429. Nothing is created or charged when that happens. Put a short pause between orders rather than firing them off in parallel.
Errors
Errors come back as JSON with a readable message, usually alongside "type": "error". Branch on the HTTP status, not on type. A few handled failures answer 200 with an error body, and a few 404s still carry "type": "response", so the status is the only reliable signal. One more thing worth coding for: a bad or inactive API key (401), an endpoint an API key may not use (403) and the hourly key budget (429) answer with a status and statusText body instead, so the readable text is in statusText and not message. Read both fields when you log an error.
| Status | Meaning | What to do |
|---|---|---|
400 | The request was wrong | Read message. Usually a missing or invalid field. |
401 | Bad or disabled key | Check the key, and that it is still active in your dashboard. |
403 | Not available to API keys | That endpoint is dashboard only. This page lists everything a key can reach. |
404 | Not found | The order or package id does not exist on your account. |
409 | A renewal is running or under review | Datacenter, IPv6 and Custom ISP renewals. Nothing was charged for this request. Read the message: wait for the running renewal, or contact us if it is under review. |
429 | Rate limited | Wait for Retry-After, then carry on. |
500 or 502 | Something went wrong on our side | Safe to retry a read. Do NOT blindly retry a purchase or a renewal: read the message first (see below), and check /orders or /orders/:id before sending it again. |
Messages worth handling
| Message | What it means |
|---|---|
| Insufficient balance | Top up on the Deposit Balance page and try again. Nothing was created. |
| Your payment went through and the order was created, but setting the plan up did not finish | The one message you must special-case. Your balance HAS been charged and the order exists; the payload carries its OrderId. Do not order again. We finish it or refund you. |
| Please add a name and address to complete your profile | Your account needs a name and address before it can buy anything, because invoices are generated per order. Fill it in once in the dashboard. |
| API orders are paid from your account balance | You sent a paymentMethod other than "Balance". |
| This plan type cannot be renewed at the moment | Plans on a retired product. Buy a new plan instead. |
| A renewal for this plan is already in progress | HTTP 409, Datacenter, IPv6 and Custom ISP. You sent a second renewal while the first was still running. It was not charged. Wait for the first to finish and check GET /orders/:id before renewing again. |
| This plan's last renewal is being checked by our team | HTTP 409, Datacenter, IPv6 and Custom ISP. An earlier renewal is under manual review. Nothing was charged for this request. Do not renew again yet; contact us. |
| Failed to extend proxy plan. Your balance has been refunded. | HTTP 500 on a renewal. Nothing happened and the money is back on your balance. Safe to try again later. |
| Your renewal payment went through, but we need to confirm it with a quick manual check | HTTP 500, Datacenter, IPv6 and Custom ISP. You WERE charged; our team applies the renewal within 24 hours or refunds it. Do NOT retry. A retry only gets the 409 above, so you cannot be charged twice. |
| You can only extend with a Datacenter plan of the same size | The packageId has a different IP count or bandwidth from your Datacenter plan. Pick one from GET /orders/:id/extend-options. |
| You can only renew this IPv6 plan with... | The packageId is the wrong kind for your IPv6 plan (unlimited vs bandwidth, or a different speed or length). Pick one from GET /orders/:id/extend-options. |
| An IPv6 plan can hold at most 5000 GB... | The bandwidth package would take your plan past 5000 GB in total. Nothing was charged. Pick a smaller one from GET /orders/:id/extend-options. |
| Please choose one of the available quantity options for this plan | Dedicated ISP. Your quantity must match one of the sizes the plan offers. |
| This city is out of stock right now / This carrier is out of stock in this city right now / Only 3 IPs are available for this choice right now | Custom ISP. Stock ran out since you read the catalog. Nothing was charged. Read GET /custom-isp/catalog (or /carriers) again and pick another city, carrier or a lower quantity. |
| You have no IP replacements left on this plan | Custom ISP. Every replacement bought with the plan has been used. |
| Package not found | On a Custom ISP purchase, send a packageId from GET /custom-isp/catalog, not the "customisp" marker from /packages. On a Datacenter or IPv6 renewal it means packageId is missing, unknown or no longer on sale. |
| Not enough IPs available | Datacenter. Read /packages/datacenterp-countries and allocate within the stock it reports. |
| Too many requests (HTTP 429) | The 3-per-minute bucket above. The exact wording differs between endpoints, so branch on the 429 status rather than the text. Nothing was created. |
| Rate limit exceeded | You have used your 1000 requests for this hour. |
{
"type": "error",
"message": "Insufficient balance",
"payload": {}
}Errors that come back from the proxy itself while you are using it, rather than from this API, are covered in each product guide below: 407 is bad credentials or an address that is not whitelisted, and 429 from a proxy means too many connections at once.
Products
Products and their proxyType
Every plan has a proxyType. Use it to filter the catalogue (/packages?proxyType=...) and to tell which product an order is. Each one has its own guide further down this page.
| Product | proxyType | Sold by | Renewable |
|---|---|---|---|
v2resi | Bandwidth (GB) | Yes | |
resix | Bandwidth (GB) | Yes | |
Isp | Per IP, 1 day to 3 months, by city | Yes | |
IspP | Per IP, per month | Yes | |
RotatingMobile | Bandwidth (GB) | Yes | |
DatacenterP | IPs plus a bandwidth pool | Yes | |
Ipv6p | Bandwidth, or unlimited with a speed cap | Yes |
Custom ISP plans, prices and cities come from GET /custom-isp/catalog, not from /packages.
Connecting, per product
Buying a plan is the same call for every product. What differs is the extra body the purchase needs, the gateway and the ports you connect to, and where the targeting flags go. Each guide below is complete on its own: find your product, and everything you need is in that one block.
GET /orders/:id gives you the credentials for a plan, as proxy.username and proxy.password. The host is a fixed gateway that belongs to the product, not to your order, and each guide lists them. Do not build your proxy string from proxy.server_ip: it is only populated on some products and is not the host you should connect to.
The exceptions are Custom ISP and Dedicated ISP, where every IP is its own line with its own host, port and login, all of which come from GET /generator/isp.
What can be renewed
Renewing keeps an existing plan alive rather than creating a new one, so the credentials stay the same. Not every product supports it right now.
| Product | Renewable | What to send |
|---|---|---|
| Yes | orderId, paymentMethod and the packageId of the size you want | |
| Yes | orderId, paymentMethod and the packageId of the size you want | |
| Yes | orderId, paymentMethod and the packageId of the size you want | |
| Yes | orderId and paymentMethod. It renews the same plan (same length, same IPs) at its per-IP price, plus the carrier fee per IP when the plan has a carrier. Add length to renew for another length, for example a 1-day plan for 1 month. IP replacements are not renewed. Check the cost of each length with GET /purchase/isp-extend-price. | |
| Yes | orderId and paymentMethod only. It renews the same IPs for another 30 days. | |
| Yes | orderId, paymentMethod and the packageId of a package with the same IPs and bandwidth; only the length may differ. Get it, and the exact price, from GET /orders/:id/extend-options. Renewing resets your data to the plan's full GB for the new term: any data you haven't used yet doesn't carry over, but your remaining days do. Add-ons are charged again at +25% each. | |
| Yes | orderId, paymentMethod and the packageId of a plan of the same kind, from GET /orders/:id/extend-options: for unlimited plans the unlimited package with the same speed and the same length, a bandwidth package for bandwidth plans (its GB are added, and the plan can hold at most 5000 GB in total). |
Whatever you send, the amount charged and the bandwidth or days added are always worked out on our side from the package itself, never from the request body. Anything else you put in the body is ignored.
Country, state and city lists
Where to get the list of places you can target, per product. Some are a live endpoint, some are one downloadable file, and two products have no list at all because the country you get is the gateway you connect to.
| Product | What you can target | Where the list comes from |
|---|---|---|
| Standard Residential | Country, US state, city, ASN | Live: GET /generator/budget/targeting-options?orderId=<your order>. Returns the countries available to your plan, with their states and cities. |
| Premium Residential | 196 countries, 50 US states, cities in 201 countries | Download: https://catproxies.com/files/premium_residential_x_targeting.json. It carries the whole reference in one file: countries, us_states and a cities map keyed by country code, plus the exact flag format and the ports. |
| Rotating Mobile | Country, region or state, city, carrier | Live, four endpoints: GET /generator/mobile-locations/countries, then /regions, /cities and /isps for the place you picked. Offline copy of the same tree: https://catproxies.com/files/mobile_targeting.json (242 countries). |
| Custom ISP | City, and optionally the carrier and UDP support, chosen when you buy | Live: GET /custom-isp/catalog?tier=...&udp=... lists the countries and cities in stock with IP counts. GET /custom-isp/carriers?location=... lists the carriers (ASNs) in one city. |
| Dedicated ISP | None | Pool based, so there is no country to choose and locations[] is empty. |
| Datacenter | US, CA, DE, GB, NL | Fixed set of five. Live stock per country: GET /packages/datacenterp-countries. You split your IPs across them at purchase with datacenterPData.country_proxies. |
| IPv6 | Worldwide, US, DE, GB, NL | Fixed set of five, and the country IS the gateway you connect to: ipv6-ww, ipv6-us, ipv6-de, ipv6-gb, ipv6-nl .catproxies.com. Same credentials on all of them. |
Things that trip people up
- Standard Residential: Values go on the USERNAME, lowercase, with no spaces or separators: -country-us-state-california-city-losangeles. It is scoped to your own order, so ask for it once at startup and cache it.
- Premium Residential: Values go on the PASSWORD, and the first flag joins with a dash while every one after it joins with an underscore. Multi-word cities have no separator at all: _city-losangeles.
- Rotating Mobile: Each entry is an object with a code and a name: use the code. Multi-word values join with a plus sign, so -city-los+angeles and -isp-at&t+wireless. The four endpoints share 60 requests per 10 minutes, so fetch them once and cache.
- Custom ISP: Send the city exactly as the catalog returns it ("Country - City") as ispData.location, and a carrier's asn as ispData.asn. Ask with the same tier and udp you will buy, since stock differs per tier and per UDP choice. Fixed at purchase; an IP replacement stays in the same city.
- Datacenter: The split must add up to exactly the IP count of the package. A worldwide rotating line only works on a plan that owns IPs in all five.
- IPv6: Nothing to buy per country and nothing to send: point at a different gateway and you are in a different country.
Standard Residential
v2resiReal home IPs, sold by the gigabyte.
What it is
Sold by bandwidth. Buy it with nothing but the packageId. One set of credentials covers every country and session; you choose where an IP comes from with flags on the username. A fresh IP on every request by default.
Buying
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "packageId": "PACKAGE_ID", "paymentMethod": "Balance" }'Proxy format and connecting
GET /orders/:id gives you proxy.username and proxy.password. The host is one of the three fixed regional gateways below: pick the one nearest your target for lower latency. The same credentials work on all of them. Ignore proxy.server_ip on this product; it is not set.
| Gateway | Rotating port | Sticky port |
|---|---|---|
| resi-us.catproxies.com (United States) | 9000 HTTP / 11000 SOCKS5 | 10000 HTTP / 12000 SOCKS5 |
| resi-fr.catproxies.com (Europe) | 9000 HTTP / 11000 SOCKS5 | 10000 HTTP / 12000 SOCKS5 |
| resi-sg.catproxies.com (Asia) | 9000 HTTP / 11000 SOCKS5 | 10000 HTTP / 12000 SOCKS5 |
Example
# From GET /orders/:id
# username: mtpeqbcevnemewc201120 password: jonxybfeuu
# Host: pick the gateway nearest your target from the table above1Rotating IP in the US, a new one on every request (HTTP port 9000)
curl -x resi-us.catproxies.com:9000 \
-U "mtpeqbcevnemewc201120-type-residential-country-us:jonxybfeuu" \
https://ipinfo.io2The same IP in Los Angeles for 30 minutes (sticky HTTP port 10000)
curl -x resi-us.catproxies.com:10000 \
-U "mtpeqbcevnemewc201120-type-residential-country-us-state-california-city-losangeles-lifetime-30-session-ab12:jonxybfeuu" \
https://ipinfo.io3SOCKS5, rotating, through the Europe gateway
curl -x socks5h://resi-fr.catproxies.com:11000 \
-U "mtpeqbcevnemewc201120-type-residential-country-de:jonxybfeuu" \
https://ipinfo.ioTargeting, appended to the username
Leave the password alone and append flags to the username. -type-residential is required; everything else is optional.
| Target | Flag | Value format |
|---|---|---|
| Type (required) | -type-residential | always include this |
| Country | -country-us | ISO-2 code, lowercase |
| State or region | -state-california | lowercase, no spaces |
| City | -city-losangeles | lowercase, no spaces or separators |
| ASN or carrier | -asn-7922 | ASN number only |
| Sticky session | -lifetime-30-session-ab12 | minutes (1 to 1440) plus any id of your choosing |
| UDP over SOCKS5 | -requireUdp-true | SOCKS5 only, on port 12000 |
- Without the sticky flags you get a new IP on every request. Add -lifetime-<minutes>-session-<id> to hold one IP, up to 1440 minutes (24 hours). Use a different session id per line to hold several sticky IPs at once.
- Valid countries, states, cities and ASNs come from GET /generator/budget/targeting-options?orderId=... Cache that list; it is large and changes rarely.
- If a very specific combination returns nothing, that spot is momentarily empty. Broaden the targeting: drop the city first, then the state.
Renewing
Yes. POST /purchase/extend with the orderId and the packageId of the size you want.
Good to know
| Where these hosts come from | These gateways are fixed, and the same list is on the plan page in your dashboard, which is always current. If we ever move a gateway the hostname stays the same, so build your proxy strings from the names above rather than resolving one to an IP and hard-coding that. |
| Bandwidth | proxy.bandwidth_left on GET /orders/:id is what you have left, in GB. When it hits zero the plan stops passing traffic even if the date has not been reached. |
| Authentication | Username and password only. There is no IP whitelist on this product. |
| Rotate the password | POST /orders/:id/reset-password. Targeting lives on the username here, so only the password half of your proxy strings changes. |
Premium Residential
resixA cleaner residential pool for the sites that keep blocking you.
What it is
Sold by bandwidth and bought exactly like Standard Residential, with nothing but the packageId. Two things differ: the flags go on the password rather than the username, and you pick your region by which gateway you connect to.
Buying
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "packageId": "PACKAGE_ID", "paymentMethod": "Balance" }'Proxy format and connecting
GET /orders/:id gives you proxy.username and proxy.password. The host is one of the regional gateways below, and unlike our other products the HTTP and SOCKS5 gateways are different names, so take the row for the protocol you want. The same credentials work on all of them, including the six dedicated ISP pools at the bottom of the table.
| Region | HTTP gateway | SOCKS5 gateway |
|---|---|---|
| Americas | presix.catproxies.com:6011 | presix-socks.catproxies.com:6014 |
| Europe | presix-eu.catproxies.com:6012 | presix-eu-socks.catproxies.com:6015 |
| Asia, Africa and Oceania | presix-asia.catproxies.com:6013 | presix-asia-socks.catproxies.com:6016 |
| ISP pool: United States | usax.catproxies.com:6000 | Not available (HTTP only) |
| ISP pool: United States (Tickets) | usax-tk.catproxies.com:6001 | Not available (HTTP only) |
| ISP pool: United Kingdom | ukx.catproxies.com:6003 | Not available (HTTP only) |
| ISP pool: Germany | dex.catproxies.com:6006 | Not available (HTTP only) |
| ISP pool: Germany (DTAG) | dex-dtag.catproxies.com:6007 | Not available (HTTP only) |
| ISP pool: Australia | aux.catproxies.com:6002 | Not available (HTTP only) |
Example
# From GET /orders/:id
# username: hftjvbtwgxxxceb205604 password: ngnstzylne
# Host: the gateway for your region and protocol, from the table above1Worldwide, rotating (bare password, Americas HTTP gateway)
curl -x presix.catproxies.com:6011 \
-U "hftjvbtwgxxxceb205604:ngnstzylne" https://ipinfo.io2UK, London, with the quality filter (Europe HTTP gateway). First flag joins with "-", the rest with "_".
curl -x presix-eu.catproxies.com:6012 \
-U "hftjvbtwgxxxceb205604:ngnstzylne-country-gb_city-london_streaming-1" \
https://ipinfo.io3Two different sticky IPs: one unique 8-character session id per line
curl -x presix.catproxies.com:6011 -U "hftjvbtwgxxxceb205604:ngnstzylne-country-us_session-a1b2c3d4_lifetime-1h" https://ipinfo.io
curl -x presix.catproxies.com:6011 -U "hftjvbtwgxxxceb205604:ngnstzylne-country-us_session-e5f6g7h8_lifetime-1h" https://ipinfo.io4SOCKS5 uses its own gateway name and port
curl -x socks5h://presix-socks.catproxies.com:6014 \
-U "hftjvbtwgxxxceb205604:ngnstzylne-country-us" https://ipinfo.io5Device targeting (best effort), always the LAST flag
curl -x presix-eu.catproxies.com:6012 \
-U "hftjvbtwgxxxceb205604:ngnstzylne-country-de_session-a1b2c3d4_lifetime-1h_device-windows" \
https://ipinfo.io6Dedicated ISP pool (UK): HTTP only, no country or other flags, sticky session optional
curl -x ukx.catproxies.com:6003 \
-U "hftjvbtwgxxxceb205604:ngnstzylne-session-a1b2c3d4_lifetime-1h" https://ipinfo.ioTargeting, appended to the password
Leave the username alone and append flags to the password. The first flag joins the password with a hyphen and every flag after it with an underscore. All of them are optional; a bare password gives you a worldwide IP.
| Target | Flag | Value format |
|---|---|---|
| Country | -country-us | ISO-2 code, lowercase. Leave it out for worldwide. |
| US state | _state-california | lowercase, no spaces (newyork). US only, and not with a city. |
| City | _city-losangeles | lowercase, no spaces. Needs a country, and not with a state. |
| Sticky session | _session-a1b2c3d4 | exactly 8 lowercase letters or digits. One id means one IP. |
| Session lifetime | _lifetime-1h | how long that IP is held: minutes or hours (30m, 1h, 24h), up to 168h |
| Quality filter | _streaming-1 | best effort cleaner IPs |
| Speed filter | _direct-1 | best effort lower latency |
| Auth filter | _skipispstatic-1 | best effort fewer blocks |
| Device | _device-windows | windows, android, ios, macos or linux. Best effort. Put it last. |
- Mind the joiners: the FIRST flag attaches to the password with a hyphen, every one after it with an underscore.
- City and state are mutually exclusive and both need a country. Use one or the other, never both.
- Without a _session- flag you get a fresh IP for every new connection (a connection your client keeps open keeps its IP). Add a unique 8-character session id per line, optionally with _lifetime-, to hold a batch of different sticky IPs.
- The three filters are best effort, not guarantees. Stacking several of them narrows the pool, so use only the one you actually need.
- Device targeting is best effort too. It asks for IPs from that type of device and most come back that way, but not all. It narrows the pool, so combining it with a city, a state or the filters (the speed filter the most) means more failed connections. Only the five listed values work: any other value makes the connection hang with no error.
- The dedicated ISP pools take no flags except a sticky session: send the bare password (rotating) or PASSWORD-session-a1b2c3d4_lifetime-1h. Country, city, state, filters and device do not apply there.
- Any city in the world can be asked for, but the pool moves, so a very small city may fall back to the wider region. Prefer larger cities.
Good to know
| Where these hosts come from | These gateways are fixed, and the same list is on the plan page in your dashboard, which is always current. If we ever move a gateway the hostname stays the same, so build your proxy strings from the names above rather than resolving one to an IP and hard-coding that. |
| Dedicated ISP pools | Six fast, country-locked ISP pools (United States, United States Tickets, United Kingdom, Germany, Germany DTAG, Australia) come with every Premium Residential plan, on the same login and bandwidth. They are part of Premium Residential, not the separate Dedicated ISP product. The host decides the pool and its country. They are HTTP only and take no targeting flags. They are also in the Dedicated ISP pool dropdown on the plan page. |
| Bandwidth | proxy.bandwidth_left on GET /orders/:id is what you have left, in GB. |
| Authentication | Username and password only. There is no IP whitelist on this product. |
| Rotate the password | POST /orders/:id/reset-password changes the BASE password only. Rebuild your strings with the new base and re-append the same flags, since targeting lives on the password here. |
Custom ISP
IspISP IPs in the city you pick, on the carrier you pick.
What it is
ISP proxies sold per IP, where you choose everything: the tier (Standard, or Clean Score with IPs that have a fraud score of 0), the plan length (1 day, 7 days, 1 month, 2 months or 3 months), the city, and if you want, the carrier and UDP support. You can also buy up to 5 IP replacements with the plan, to swap an IP later. Price = price per IP x IPs, plus the carrier fee per IP x IPs when you pick a carrier, plus replacements x the replacement price. VAT is added on top. The plans and cities come from GET /custom-isp/catalog, not from /packages. Optional: send a country instead of a city for IPs from any city in it, and ip2locationIsp (beta) to only get IPs that IP2Location marks as "ISP", a home or fixed internet line (checked right before delivery, no extra cost). If no IP can be delivered, the order retries by itself for about 12 minutes and is then refunded to your balance automatically.
Buying
1Plans, prices and cities in stock (tier=premium for Clean Score, udp=1 for UDP only)
curl "https://catproxies.com/api/v1/user/custom-isp/catalog?tier=standard" \
-H "Authorization: Bearer cp_your_api_key_here"plans.standard["1_month"].packageId, pricePerIp, minQty, maxQty, replacementPrice countries[].cities[].location, e.g. "United States - New York City"
2Optional: carriers in that city (same tier and udp as you will buy)
curl -G "https://catproxies.com/api/v1/user/custom-isp/carriers" \
--data-urlencode "location=United States - New York City" \
-H "Authorization: Bearer cp_your_api_key_here"carriers[].asn, e.g. 7922
3Buy 5 IPs on that carrier, with 2 IP replacements
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"packageId": "PACKAGE_ID_FROM_STEP_1",
"paymentMethod": "Balance",
"ispData": {
"quantity": 5,
"location": "United States - New York City",
"asn": 7922,
"udp": false,
"replacements": 2
}
}'Proxy format and connecting
GET /generator/isp?orderId=... returns one line per IP. Every line uses the same connection server and the same port, 1337, for both HTTP and SOCKS5. The plan has one password, and each line's login carries its IP, so build each proxy string from its own line. Pick the connection server with ®ion=: auto (the default) is the one closest to you, and connection_regions in the reply lists the others. The exit IP does not change with the region, only the route to it.
| Field | Meaning |
|---|---|
host | the connection server for the region you picked (the same on every line) |
port_http / port_socks | both 1337. HTTP, HTTPS and SOCKS5 all run on the same port. |
login / password | the login is different on every line (it carries the line's IP), the password is the same |
ip | the IP this line exits from. Send it to the replace endpoint to swap it. |
Example
# From GET /generator/isp?orderId=...®ion=us-east
# { "host": "us-east.isp.catproxies.com", "port_http": 1337, "port_socks": 1337,
# "login": "cpx8f31a2-203.0.113.24", "password": "Rk4pX9wq", "ip": "203.0.113.24" }1HTTP and HTTPS
curl -x us-east.isp.catproxies.com:1337 -U "cpx8f31a2-203.0.113.24:Rk4pX9wq" https://ipinfo.io2SOCKS5, same port
curl -x socks5h://us-east.isp.catproxies.com:1337 -U "cpx8f31a2-203.0.113.24:Rk4pX9wq" https://ipinfo.io# Proxy string format for tools that want host:port:login:password
# us-east.isp.catproxies.com:1337:cpx8f31a2-203.0.113.24:Rk4pX9wq3Swap 203.0.113.24 for a new IP in the same city (uses one replacement)
curl -X POST https://catproxies.com/api/v1/user/custom-isp/orders/ORDER_ID/replace \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "ip": "203.0.113.24" }'Targeting
There is nothing to append. The city, carrier and UDP choice are fixed when you buy, and each line is one fixed IP.
Renewing
Yes. POST /purchase/extend with just the orderId and paymentMethod, no packageId: it renews the same plan (same length, same IPs) at its per-IP price, plus the carrier fee per IP again when the plan has a carrier. To renew for another length, for example a 1-day plan for 1 month, add length ("1_day", "7_days", "1_month", "2_months" or "3_months"); options in GET /purchase/isp-extend-price lists the lengths and their prices. IP replacements are not renewed. Check the cost first with GET /purchase/isp-extend-price?orderId=... One renewal per plan at a time. If only some IPs could be renewed, the renewal still succeeds and our team completes the rest; do not renew again.
Good to know
| Tiers | standard is Standard. premium is Clean Score: the IPs are checked right before delivery and have a fraud score of 0 when you get them. clean_score on GET /generator/isp is true on these plans. |
| Do not check IPs through the proxy | We check every IP before delivery. Please do not visit IP check or fraud score sites (IPQS and similar) through the proxy: those sites log every visit, and it can raise the IP's fraud score. To check an IP, look it up from another device or a connection that is not using the proxy. |
| IP locations | Locations (country and city) are strictly based on the ipinfo.io database. Other IP databases can show a different city for the same IP. |
| location | Send the city exactly as the catalog returns it, as "Country - City". The catalog counts are at most a minute old, so the purchase checks stock again and refuses cleanly (nothing charged) when a city or carrier ran out. |
| Carrier (asn) | Optional. Take it from GET /custom-isp/carriers for the same city, tier and udp. It adds carrierFee per IP. Without it you get IPs from any carrier in that city. |
| IP replacements | 0 to 5, bought with the plan at its replacementPrice each. POST /custom-isp/orders/:id/replace with { ip } swaps that IP for a new one in the same city; the city and UDP support stay, but for now the carrier (ASN) can be different. Renewing keeps the same IPs. HTTP 202 with { checking: true } means the swap is still being confirmed: do not send it again. Replacements belong to that plan and are not added again when you renew. IP replacements can only be bought together with the order: they can't be added later, so choose how many you need when you buy. |
| Personal price and discounts | pricePerIp in the catalog already includes any launch discount and your personal price. Coupons are refused when either applies (customRate true, or promoPct above 0). |
| Authentication | Username and password only. There is no IP whitelist and no password reset on this product. |
| Just after buying | The reply can say settingUp while the IPs are placed, and GET /generator/isp can answer HTTP 202 { pending: true }. Wait a few seconds and ask again. Do not buy again. |
| Stock problems and errors | Sometimes a city or carrier runs out, or delivery fails. Stock is checked before you pay, so most of these are refused with nothing charged. If it fails after you paid, the plan shows as being set up and we retry it automatically: after about 1, 3, 6 and 11 minutes, then every 10 minutes for up to 6 hours. If it is still not delivered, or the result is unclear, our team checks whether the IPs were delivered and finishes the plan or refunds it within 24 hours. Do not buy again in the meantime. |
Dedicated ISP
IspPPrivate static IPs, nobody else on them.
What it is
Sold per IP, per month, and the IPs are yours alone rather than from a shared pool. There is no country to choose, and the term is a fixed 30 days. The quantity is not free-form: it has to match one of the sizes offered for the plan.
Buying
Dedicated ISP takes the quantity only, and that quantity must be one of the sizes the plan offers (see /packages).
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"packageId": "PACKAGE_ID",
"paymentMethod": "Balance",
"ispData": { "quantity": 5 }
}'Proxy format and connecting
GET /generator/isp?orderId=... returns one line per IP with its own host, port, login and password.
| Field | Meaning |
|---|---|
host | the IP address of that line |
port_http | HTTP and HTTPS port for that line |
port_socks | SOCKS5 port for that line, and UDP rides on it too. It is NOT the same number as port_http on this product, so always read this field. Connecting SOCKS5 to the HTTP port fails outright. |
login / password | credentials for that line only |
Example
# From GET /generator/isp?orderId=...
# { "host": "203.0.113.24", "port_http": 61234, "port_socks": 62234,
# "login": "ded_4f21ba", "password": "Kq7ZmTx2" }1HTTP and HTTPS on port_http
curl -x 203.0.113.24:61234 -U "ded_4f21ba:Kq7ZmTx2" https://ipinfo.io2SOCKS5, and UDP over SOCKS5, on port_socks. Same host, DIFFERENT port.
curl -x socks5h://203.0.113.24:62234 -U "ded_4f21ba:Kq7ZmTx2" https://ipinfo.ioTargeting
There is nothing to append. Each IP is a fixed address and the product is pool based, so there is no country flag either.
Renewing
Yes. POST /purchase/extend with just the orderId and paymentMethod: it renews the same number of IPs for another 30 days. Check the cost first with GET /purchase/isp-extend-price?orderId=...
Good to know
| Username and password only | There is no IP-authentication option on this product. |
| IP locations | Locations are strictly based on the ipinfo.io database. Other IP databases can show a different location for the same IP. |
| stale | stale: true on GET /generator/isp means the list is our last known good copy. The lines still work; call again shortly for a fresh list. |
| Just after buying | The lines are normally ready immediately. If the list comes back empty on the first call, give it a few seconds and ask again. |
| Allowed quantities | Only the sizes listed for the plan in GET /packages?proxyType=IspP are accepted. Anything else is refused with 'Please choose one of the available quantity options for this plan.' |
| Term | A fixed 30 days per purchase, whatever quantity you buy. |
Datacenter
DatacenterPA block of dedicated IPs plus a shared bandwidth pool.
What it is
One plan gives you a list of dedicated IPs and a shared GB pool for a fixed number of days, for example 100 IPs with 250 GB for 30 days. At purchase you decide how those IPs split across US, CA, DE, GB and NL. Every IP is its own proxy and they all share one username and password.
Buying
country_proxies must add up to EXACTLY the package's IP count. Check live stock first with GET /packages/datacenterp-countries.
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"packageId": "PACKAGE_ID",
"paymentMethod": "Balance",
"datacenterPData": {
"country_proxies": { "US": 60, "DE": 20, "GB": 20 },
"high_concurrency": false,
"high_priority": false,
"whitelisted_ips": false
}
}'Proxy format and connecting
GET /orders/:id returns proxy.username and proxy.password (shared by every IP) plus ip_list, grouped by country and then city. Flatten cities[].ips to get every address. The list is refreshed on each call. There are two ways to connect: STATIC, where you connect to one of your own IPs and always exit from it, and ROTATING, where you connect to a country gateway below, add -ttl-0 to the username and get a new IP from your plan on every new connection. The same credentials work on every IP and every gateway.
| Gateway | HTTP port | SOCKS5 port |
|---|---|---|
| dcww.catproxies.com (worldwide rotating, only on plans with all five countries) | 1338 | 1339 |
| dcus.catproxies.com (United States rotating) | 1338 | 1339 |
| dcca.catproxies.com (Canada rotating) | 1338 | 1339 |
| dcde.catproxies.com (Germany rotating) | 1338 | 1339 |
| dcgb.catproxies.com (United Kingdom rotating) | 1338 | 1339 |
| dcnl.catproxies.com (Netherlands rotating) | 1338 | 1339 |
| Any IP from your ip_list (static) | 1338 | 1339 |
Example
# From GET /orders/:id
# username: dcuser482913 password: dcpass91827
# ip_list -> 203.0.113.24, 203.0.113.57, ...
# rotating.endpoints -> { "US": "dcus.catproxies.com", "DE": "dcde.catproxies.com" }1STATIC: that exact IP every time
curl -x 203.0.113.24:1338 -U "dcuser482913:dcpass91827" https://ipinfo.io2ROTATING, United States: a new US IP from your plan on every new connection
curl -x dcus.catproxies.com:1338 -U "dcuser482913-ttl-0:dcpass91827" https://ipinfo.io3ROTATING, Germany
curl -x dcde.catproxies.com:1338 -U "dcuser482913-ttl-0:dcpass91827" https://ipinfo.io4ROTATING, worldwide (only on a plan that owns IPs in ALL FIVE countries)
curl -x dcww.catproxies.com:1338 -U "dcuser482913-ttl-0:dcpass91827" https://ipinfo.io5SOCKS5 on port 1339, static and rotating
curl -x socks5h://203.0.113.24:1339 -U "dcuser482913:dcpass91827" https://ipinfo.io
curl -x socks5h://dcus.catproxies.com:1339 -U "dcuser482913-ttl-0:dcpass91827" https://ipinfo.io# Proxy string format for tools that want host:port:user:pass
# static: 203.0.113.24:1338:dcuser482913:dcpass91827
# rotating: dcus.catproxies.com:1338:dcuser482913-ttl-0:dcpass91827Targeting, appended to the username
The country is decided by the address you connect to: one of your own IPs for static, or that country's gateway for rotating. The only flag is the one that turns a line from static into rotating.
| Target | Flag | Value format |
|---|---|---|
| Rotating | -ttl-0 | a new IP on every new connection, from your own IPs in that country |
- Without the flag you get that exact IP every time, which is the default.
- Only use a gateway for a country your plan has IPs in. A gateway for a country you did not buy answers 407.
- proxy.rotating.endpoints on GET /orders/:id gives the exact rotating host for each country of your plan. It is usually the gateway in the table above. It gives you a plain IP instead when your plan owns one of the gateway addresses, or in the US when all your US IPs sit behind just one of the two US addresses. Reading it from the API is the safest option.
- Do not use one of your own IPs as the rotating host. If an IP is whitelisted, a request through one of your own IPs is logged in by IP, the flag is ignored and you always get that IP.
- proxy.rotating.bound_ip_conflicts lists the countries where your plan owns the only gateway address. Rotating there keeps giving the same IP while an IP is whitelisted, so remove the whitelisted IP if you need rotating in that country. Static is not affected.
- Rotation happens per connection, not per request. If your client keeps the connection alive it will stay on one IP, so open a fresh connection per request (or send a Connection: close header) when you want a new IP each time.
Renewing
Yes. Check the price first with GET /orders/:id/extend-options, which lists the packages that qualify and the exact total for each. Then POST /purchase/extend with the orderId and the packageId of a Datacenter package with the same number of IPs and the same bandwidth as your plan; only the duration may differ. Renewing resets your data to the plan's full GB for the new term. Any data you haven't used yet doesn't carry over. Your remaining days do: the new term is added on top of your current end date. Add-ons you bought with the plan (high_concurrency, high_priority, extra whitelist slots) are charged again at +25% each. Read GET /orders/:id afterwards for the new end date. See Renewing a Datacenter or IPv6 plan below.
Renewing a Datacenter or IPv6 plan
Three calls: check the price, renew, then read the plan again for the new end date. The price check charges nothing, so call it as often as you like.
1Check the price. Charges nothing. renewable must be true. Pick one of options[] and note its package_id and total, and show note to whoever is paying.
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID/extend-options" \
-H "Authorization: Bearer cp_your_api_key_here"2Renew, paid from your balance (it must cover options[].total).
curl -X POST "https://catproxies.com/api/v1/user/purchase/extend" \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "orderId": "ORDER_ID", "packageId": "PACKAGE_ID_FROM_STEP_1", "paymentMethod": "Balance" }'payload.ExtendOrderId, payload.extendOrder.amount (what was charged)
3Read the plan again: proxy.expired_at is the new end date, proxy.bandwidth_left the data you now have.
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID" \
-H "Authorization: Bearer cp_your_api_key_here"- Renew before the end date. An expired plan cannot be renewed; buy a new one instead.
- Datacenter: renewing resets your data to the plan's full GB for the new term. Any data you haven't used yet doesn't carry over. Your remaining days do: the new term is added on top of your current end date. Only packages with the same number of IPs and the same bandwidth qualify, and add-ons are charged again at +25% each.
- If step 2 times out or you are not sure it landed, do step 3 before trying again. A renewal that went through has moved proxy.expired_at (and on an IPv6 bandwidth plan raised the data). Sending it again would renew, and charge, a second time.
- Two 500 messages mean opposite things. "Failed to extend proxy plan. Your balance has been refunded." means nothing happened: try again later. "Your renewal payment went through, but we need to confirm it with a quick manual check..." means you WERE charged and our team finishes it within 24 hours or refunds it: do not retry.
- One renewal per plan at a time: a second request while one is running gets a 409 and is not charged. Renewals share the 3-per-minute limit with purchases and password resets.
- Related: POST /orders/:id/reset-password rotates the password on both products, and GET /orders/:id/stats shows how the plan is being used.
Usage stats
GET /orders/:id/stats gives traffic and requests over time, a log of recent connections and your top sites. See Usage stats below.
Good to know
| Where these hosts come from | These gateways are fixed, and the same hosts are on the plan page in your dashboard. If we ever move a gateway the hostname stays the same, so build your proxy strings from the names above rather than resolving one to an IP and hard-coding that. |
| United States gateway | Your US IPs sit behind two addresses, each covering a part of your IPs, and dcus.catproxies.com holds all of them (Canada and Germany work the same way with dcca and dcde). Your machine picks one of them and keeps it for about a minute before it can switch, so within one minute you rotate through part of your IPs and over a few minutes through all of them. |
| Worldwide gateway | dcww.catproxies.com only works on a plan that owns IPs in all five countries (US, CA, DE, GB and NL). On a smaller plan it answers 407 whenever it lands on a country you did not buy, so use the per-country gateways instead. |
| country_proxies | Must total exactly the package's IP count. Allowed countries: US, CA, DE, GB and NL. Over-allocating a country fails the purchase, so read GET /packages/datacenterp-countries first. |
| Add-ons | high_concurrency (more parallel connections), high_priority (priority routing) and whitelisted_ips (3 whitelist slots instead of 1). Each one adds 25% to the price, so all three is +75%. All four keys must be present in datacenterPData. |
| Bandwidth | One shared GB pool across every IP in the plan. Track it with proxy.bandwidth_left on GET /orders/:id. |
| Errors from the proxy | 407 means wrong credentials or an address that is not whitelisted. 429 means you hit the plan's concurrent-connection limit, so lower your parallelism or buy with high_concurrency. |
| Rotate the password | POST /orders/:id/reset-password issues one new password shared by every IP. Swap it into all of your proxy strings. |
IPv6
Ipv6pThe cheapest way to make a very large number of requests.
What it is
Rotates through a very large pool of IPv6 addresses, with a fresh exit on every request by default. Two flavours in the catalogue: bandwidth plans with a GB pool and no speed cap, and unlimited plans with no GB cap and a speed cap in Mbps. Buying needs nothing but the packageId.
Buying
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "packageId": "PACKAGE_ID", "paymentMethod": "Balance" }'Proxy format and connecting
GET /orders/:id gives you proxy.username and proxy.password. The exit country is decided by which gateway you connect to, and the same credentials work on all of them.
| Gateway | HTTP port | SOCKS5 port |
|---|---|---|
| ipv6-ww.catproxies.com (worldwide) | 1338 | 1339 |
| ipv6-us.catproxies.com | 1338 | 1339 |
| ipv6-de.catproxies.com | 1338 | 1339 |
| ipv6-gb.catproxies.com | 1338 | 1339 |
| ipv6-nl.catproxies.com | 1338 | 1339 |
Example
# From GET /orders/:id
# username: ipv6user291 password: v6pass8171Rotating, a fresh IPv6 address on every request (US gateway)
curl -x ipv6-us.catproxies.com:1338 -U "ipv6user291:v6pass817" https://api6.ipify.org2Sticky, hold the same exit for 60 minutes (ttl is in SECONDS, so 3600)
curl -x ipv6-de.catproxies.com:1338 \
-U "ipv6user291-session-483920-ttl-3600:v6pass817" \
https://api6.ipify.org3SOCKS5
curl --socks5 ipv6-us.catproxies.com:1339 -U "ipv6user291:v6pass817" https://api6.ipify.orgTargeting, appended to the username
The country comes from the gateway you pick. The only flags are the ones that hold an IP still.
| Target | Flag | Value format |
|---|---|---|
| Sticky session | -session-483920-ttl-3600 | session id is 6 digits; ttl is in SECONDS, up to 86400 (24h) |
- Without the session flags you get a new IPv6 address on every request.
- The session id is a 6-digit number, 000000 to 999999. Pick your own and reuse it to keep the same exit, or generate a fresh one per line.
- ttl is in seconds, not minutes: 1800 is 30 minutes and 3600 is one hour. The maximum is 86400, which is 24 hours.
- Use different session ids to hold several sticky IPs at the same time.
Renewing
Yes. Check the price first with GET /orders/:id/extend-options, which lists the packages that qualify and the exact total for each. Then POST /purchase/extend with the orderId and the packageId of a plan of the same kind. An unlimited plan renews with the unlimited package of the same speed and the same length (a 30-day plan renews for 30 days), added on top of your current end date. A bandwidth plan renews with any IPv6 bandwidth package that keeps it at or under 5000 GB in total (the most an IPv6 plan can hold): its GB are added to what you have left, and the end date moves forward by your plan's own term (the number of days it was bought with). Read GET /orders/:id afterwards for the new end date and bandwidth. See Renewing a Datacenter or IPv6 plan below.
Renewing a Datacenter or IPv6 plan
Three calls: check the price, renew, then read the plan again for the new end date. The price check charges nothing, so call it as often as you like.
1Check the price. Charges nothing. renewable must be true. Pick one of options[] and note its package_id and total, and show note to whoever is paying.
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID/extend-options" \
-H "Authorization: Bearer cp_your_api_key_here"2Renew, paid from your balance (it must cover options[].total).
curl -X POST "https://catproxies.com/api/v1/user/purchase/extend" \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "orderId": "ORDER_ID", "packageId": "PACKAGE_ID_FROM_STEP_1", "paymentMethod": "Balance" }'payload.ExtendOrderId, payload.extendOrder.amount (what was charged)
3Read the plan again: proxy.expired_at is the new end date, proxy.bandwidth_left the data you now have.
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID" \
-H "Authorization: Bearer cp_your_api_key_here"- Renew before the end date. An expired plan cannot be renewed; buy a new one instead.
- IPv6 unlimited plan: the package's days are added on top of your current end date. IPv6 bandwidth plan: the package's GB are added on top of the data you have left, and the end date moves forward by the plan's own term (the number of days it was bought with, which is the package's days when you renew with the plan's own package).
- If step 2 times out or you are not sure it landed, do step 3 before trying again. A renewal that went through has moved proxy.expired_at (and on an IPv6 bandwidth plan raised the data). Sending it again would renew, and charge, a second time.
- Two 500 messages mean opposite things. "Failed to extend proxy plan. Your balance has been refunded." means nothing happened: try again later. "Your renewal payment went through, but we need to confirm it with a quick manual check..." means you WERE charged and our team finishes it within 24 hours or refunds it: do not retry.
- One renewal per plan at a time: a second request while one is running gets a 409 and is not charged. Renewals share the 3-per-minute limit with purchases and password resets.
- Related: POST /orders/:id/reset-password rotates the password on both products, and GET /orders/:id/stats shows how the plan is being used.
Usage stats
GET /orders/:id/stats gives traffic and requests over time, a log of recent connections and your top sites. See Usage stats below.
Good to know
| Where these hosts come from | These gateways are fixed, and the same list is on the plan page in your dashboard, which is always current. If we ever move a gateway the hostname stays the same, so build your proxy strings from the names above rather than resolving one to an IP and hard-coding that. |
| Your target site must support IPv6 | Exits are IPv6 only, so the destination needs an AAAA DNS record. Google, YouTube, Facebook, Instagram and TikTok all do; many smaller sites do not and will simply be unreachable. Test your target first, then confirm the proxy end to end against https://api6.ipify.org. A site with no IPv6 usually shows up as a 503 from the proxy. |
| No IP whitelist | IPv6 plans are username and password only. There is no whitelist on this product. |
| Bandwidth | On bandwidth plans, proxy.bandwidth_left on GET /orders/:id is what is left. On unlimited plans there is no GB figure; the plan is capped by speed instead. |
| Rotate the password | POST /orders/:id/reset-password issues a new password. The session flags live on the username, so only the password half of your proxy strings changes. |
Rotating Mobile
RotatingMobileReal mobile carrier IPs, sold by the gigabyte.
What it is
Sold by bandwidth and bought with nothing but the packageId. One set of credentials covers every location; you choose the location with flags on the username. A fresh IP on every request by default.
Buying
curl -X POST https://catproxies.com/api/v1/user/purchase \
-H "Authorization: Bearer cp_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "packageId": "PACKAGE_ID", "paymentMethod": "Balance" }'Proxy format and connecting
GET /orders/:id gives you proxy.username and proxy.password. The host is one of the three fixed regional gateways below: pick the one nearest your target country, since crossing continents costs real latency. The same credentials work on all of them, and one port serves every location. Ignore proxy.server_ip on this product; it is not set.
| Gateway | Port | Protocol |
|---|---|---|
| mobile-us.catproxies.com (Americas) | 5000 | HTTP and HTTPS |
| mobile-eu.catproxies.com (Europe) | 5000 | HTTP and HTTPS |
| mobile-asia.catproxies.com (Asia and Oceania) | 5000 | HTTP and HTTPS |
Example
# From GET /orders/:id
# username: mob8814720 password: r4Xq9tLp
# Host: pick the gateway nearest your target from the table above1Untargeted rotation
curl -x mobile-us.catproxies.com:5000 -U "mob8814720:r4Xq9tLp" https://ipinfo.io2United States, a specific carrier, pinned at country level
curl -x mobile-us.catproxies.com:5000 \
-U "mob8814720-country-US-isp-at&t+wireless:r4Xq9tLp" \
https://ipinfo.io3Hold one IP for 30 minutes
curl -x mobile-us.catproxies.com:5000 \
-U "mob8814720-country-US-sid-ab12-ttl-30m:r4Xq9tLp" \
https://ipinfo.ioTargeting, appended to the username
Leave the password alone and append flags to the username. Every flag is optional; with none of them you get untargeted rotation.
| Target | Flag | Value format |
|---|---|---|
| Country | -country-US | ISO-2 code |
| Region or state | -region-california | full name in lowercase, from /generator/mobile-locations/regions |
| City | -city-los+angeles | from /generator/mobile-locations/cities. Spaces are a plus sign. |
| Carrier | -isp-at&t+wireless | from /generator/mobile-locations/isps |
| Sticky session | -sid-ab12-ttl-30m | any id, plus one of 1m 5m 10m 30m 60m 120m 180m 240m |
- Write spaces as a plus sign, never a hyphen: los+angeles, new+york, at&t+wireless. Regions are full names such as california, not two-letter codes.
- An unknown or malformed value fails outright rather than quietly falling back to untargeted rotation. If a targeted request errors, check the code against the targeting endpoints first.
- Carrier coverage varies by city, so a valid city and carrier pair can still fail if that carrier has no live IP there right now. For dependable carrier targeting, pin the carrier at country level and leave the city off. City targeting is approximate to the metro area, not pinpoint.
- Untargeted rotation is not evenly spread across carriers. If you need a particular mix, ask for each carrier explicitly.
Renewing
Yes. POST /purchase/extend with the orderId and the packageId of the size you want.
Good to know
| Where these hosts come from | These gateways are fixed, and the same list is on the plan page in your dashboard, which is always current. If we ever move a gateway the hostname stays the same, so build your proxy strings from the names above rather than resolving one to an IP and hard-coding that. |
| Bandwidth | proxy.bandwidth_left on GET /orders/:id is what you have left, in GB. |
| Reset the login | POST /orders/:id/reset-password gives the plan a new login and moves your remaining data onto it. The username AND the password both change, so rebuild your proxy strings from the username and password in the response. The old login stops working straight away. Once per hour per plan. |
| Cache the targeting lists | The four /generator/mobile-locations/* endpoints are cached on our side for an hour and the lists change rarely, so fetch them once at startup rather than per request. They still count against your hourly budget. |
| Sticky windows | ttl accepts only the listed values, up to 240m (4 hours). Anything else is rejected. |
Usage stats
Datacenter and IPv6 plans come with usage analytics: traffic and requests over time, a log of recent connections, and the sites used most. It is one read-only endpoint, GET /orders/:id/stats, and the view parameter picks which of the three you get. It never changes the plan.
1Traffic over the last 24 hours, one row per hour (the defaults)
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID/stats" \
-H "Authorization: Bearer cp_your_api_key_here"2The last week, one row per day
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID/stats?timeframe=1week&interval=1day" \
-H "Authorization: Bearer cp_your_api_key_here"3Recent connections, 100 per page
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID/stats?view=activity&page=1" \
-H "Authorization: Bearer cp_your_api_key_here"4The sites used most this month
curl "https://catproxies.com/api/v1/user/orders/ORDER_ID/stats?view=top-domains&timeframe=1month" \
-H "Authorization: Bearer cp_your_api_key_here"- timeframe: 1hour, 6hours, 1day (default), 1week, 1month or 3months. interval, for the overview only: 5min, 30min, 1hour (default), 6hour, 1day, 1week or 1month. An unknown value quietly falls back to the default, so check timeframe and interval in the reply.
- available: false means the stats source could not be reached just now and the lists are empty. Retry later; it does not mean zero traffic.
- The figures lag a little behind real time. For what is left on the plan right now, read proxy.bandwidth_left on GET /orders/:id instead.
- Units: the overview is in GB, activity and top-domains traffic is in bytes, and success_rate is a percentage. Timestamps are "YYYY-MM-DD HH:MM:SS" strings.
- GET /orders/:id/unlimited-metrics is the older name of the same endpoint and returns exactly the same thing.
Endpoints
