ISP Proxies API
Everything you can do on an ISP Proxies plan page in the panel is also available over this API: search the locations you can place IPs on, list every proxy with its username, place the IPs you have not placed yet, and move IPs to another city or ISP.
Authentication
Section titled “Authentication”All endpoints authenticate with an api_token query parameter. Generate a token in the panel under Account → API Tokens.
?api_token=YOUR_API_TOKENEvery path starts with https://shifter.io/api/v1/isp/{membership}. The {membership} path parameter accepts either form of the plan identifier: the short code at the end of the plan’s panel URL (for example Rxqk) or the plan number shown on the plan page (for example 68057). Both resolve to the same plan.
The API only reaches ISP Proxies plans that belong to the owner of the token. Any other plan answers 404.
Rules for location changes
Section titled “Rules for location changes”- Each IP can change location 5 times per billing period. The count resets when the plan renews, and unused changes do not carry over to the next period. This applies to trials too.
- A moved IP gets a new username and a new
proxy_id. The old username stops working immediately, so switch your clients to the new one right away. - The plan password stays the same. There is one password per plan, shared by every username on it.
- Usernames are case-sensitive. Every proxy connects through
isp.shifter.io:443, over HTTP(S) or SOCKS5. - Each IP keeps the city and ISP you chose. The address behind it can refresh now and then, the same way a home connection gets a new address from its ISP.
List locations
Section titled “List locations”Returns the city and ISP pairs you can place IPs on, with how many IPs are available on each right now. Locations with nothing available are left out unless you ask for them.
| Parameter | In | Required | Description |
|---|---|---|---|
membership | path | yes | The plan ID (short code or plan number) |
api_token | query | yes | Your account API token |
country | query | no | ISO 3166-1 alpha-2 country code, e.g. US |
q | query | no | Search text: a city (local names work too), a region, an ISP name, or an ASN such as 7922 or AS7922 |
page | query | no | Page number, starting at 1 |
per_page | query | no | Results per page, default 100, maximum 500 |
include_sold_out | query | no | Set to 1 to include locations with no IPs available |
Example:
curl "https://shifter.io/api/v1/isp/YOUR_PLAN_ID/locations?country=US&q=Dallas&api_token=YOUR_API_TOKEN"Response:
{ "ok": true, "page": 1, "per_page": 100, "total": 2, "has_more": false, "locations": [ { "location_id": 1842, "country": "US", "region": "Texas", "city": "Dallas", "asn": 7922, "isp": "COMCAST-7922", "available": 7 } ]}location_id is stable, so you can store it and reuse it later. available is the number of IPs you can place on that location right now. Use has_more to know when to request the next page.
List proxies
Section titled “List proxies”Returns the connection details for the plan and every placed IP with its username, location and remaining location changes.
| Parameter | In | Required | Description |
|---|---|---|---|
membership | path | yes | The plan ID (short code or plan number) |
api_token | query | yes | Your account API token |
Example:
curl "https://shifter.io/api/v1/isp/YOUR_PLAN_ID/proxies?api_token=YOUR_API_TOKEN"Response:
{ "ok": true, "host": "isp.shifter.io", "port": 443, "password": "YOUR_PLAN_PASSWORD", "ips_total": 10, "ips_placed": 3, "ips_unplaced": 7, "changes_per_ip": 5, "period_ends_at": "2026-10-20T08:00:00+00:00", "proxies": [ { "proxy_id": 5531, "username": "us-texas-dallas-as7922-Ksj25", "location_id": 1842, "country": "US", "region": "Texas", "city": "Dallas", "asn": 7922, "isp": "COMCAST-7922", "changes_left": 5 } ]}| Field | Description |
|---|---|
host / port | Where every proxy on the plan connects |
password | The plan password, shared by every username |
ips_total | IPs included in the plan |
ips_placed / ips_unplaced | IPs already on a location, and IPs you can still place |
changes_per_ip | Location changes each IP gets per billing period |
period_ends_at | When the current billing period ends and the changes reset |
proxies[].username | The username to connect with. Case-sensitive |
proxies[].isp | The ISP name for the ASN. Can be null when no name is known |
proxies[].changes_left | Location changes this IP has left in the current period |
To connect, combine the fields into a proxy URL:
http://us-texas-dallas-as7922-Ksj25:YOUR_PLAN_PASSWORD@isp.shifter.io:443socks5://us-texas-dallas-as7922-Ksj25:YOUR_PLAN_PASSWORD@isp.shifter.io:443Move one IP
Section titled “Move one IP”Moves one IP to another location. This uses one of that IP’s location changes.
| Parameter | In | Required | Description |
|---|---|---|---|
membership | path | yes | The plan ID (short code or plan number) |
proxy_id | path | yes | The proxy_id of the IP to move |
api_token | query | yes | Your account API token |
location_id | body | yes | The location to move the IP to |
Example:
curl -X POST "https://shifter.io/api/v1/isp/YOUR_PLAN_ID/proxies/5531/location?api_token=YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"location_id":1901}'Response:
{ "ok": true, "message": "Location changed. Use the new username from now on.", "old_proxy_id": 5531, "proxy": { "proxy_id": 5534, "username": "us-texas-austin-as7018-Pq7rT", "location_id": 1901, "country": "US", "region": "Texas", "city": "Austin", "asn": 7018, "isp": "ATT-INTERNET4", "changes_left": 4 }}The IP now has a new proxy_id and a new username. The old username (and old_proxy_id) stop working as soon as the response arrives.
Move many IPs
Section titled “Move many IPs”Moves several IPs in one request, each to the location you name for it.
| Parameter | In | Required | Description |
|---|---|---|---|
membership | path | yes | The plan ID (short code or plan number) |
api_token | query | yes | Your account API token |
moves | body | yes | Array of {"proxy_id", "location_id"} pairs, at most 1,000 per request |
dry_run | body | no | true to check the request without changing anything. Default false |
- The request is all or nothing: if any move cannot be made, no IP moves and you get an error.
- An entry whose IP is already on its target location is skipped and does not use a change. Its
proxy_idis listed inskipped. - With
dry_run: truenothing is written. The response shows what would happen, withproxy_idandusernameset tonullinmoved, since the new ones only exist once the move is real.
Example:
curl -X POST "https://shifter.io/api/v1/isp/YOUR_PLAN_ID/proxies/location?api_token=YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"moves":[{"proxy_id":5531,"location_id":1901},{"proxy_id":5532,"location_id":1842}],"dry_run":false}'Response:
{ "ok": true, "dry_run": false, "message": "1 IP moved. Use the new username from now on. 1 IP was already there and stays as it is.", "moved": [ { "old_proxy_id": 5531, "proxy_id": 5535, "username": "us-texas-austin-as7018-Zt3wQ", "location_id": 1901, "country": "US", "region": "Texas", "city": "Austin", "asn": 7018, "isp": "ATT-INTERNET4", "changes_left": 4 } ], "skipped": [5532]}Place unplaced IPs
Section titled “Place unplaced IPs”Places IPs that are not on a location yet (ips_unplaced in the proxy list). Placing an IP does not use a location change.
| Parameter | In | Required | Description |
|---|---|---|---|
membership | path | yes | The plan ID (short code or plan number) |
api_token | query | yes | Your account API token |
placements | body | yes | Array of {"location_id", "count"} pairs: how many IPs to place on each location |
Example:
curl -X POST "https://shifter.io/api/v1/isp/YOUR_PLAN_ID/proxies/place?api_token=YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"placements":[{"location_id":1901,"count":2}]}'Response:
{ "ok": true, "message": "2 IPs are ready.", "placed": 2, "ips_unplaced": 5, "proxies": [ { "proxy_id": 5540, "username": "us-texas-austin-as7018-Hh8aa", "location_id": 1901, "country": "US", "region": "Texas", "city": "Austin", "asn": 7018, "isp": "ATT-INTERNET4", "changes_left": 5 } ]}End-to-end example
Section titled “End-to-end example”Find a location in Austin, move two IPs there, and read back the usernames to use from now on. This uses jq to read the JSON.
TOKEN="YOUR_API_TOKEN"PLAN="YOUR_PLAN_ID"BASE="https://shifter.io/api/v1/isp/$PLAN"
# 1. Find a location with IPs availableLOCATION=$(curl -s "$BASE/locations?country=US&q=Austin&api_token=$TOKEN" \ | jq '.locations[0].location_id')
# 2. Move two IPs therecurl -s -X POST "$BASE/proxies/location?api_token=$TOKEN" \ -H "Content-Type: application/json" \ -d "{\"moves\":[{\"proxy_id\":5531,\"location_id\":$LOCATION},{\"proxy_id\":5532,\"location_id\":$LOCATION}]}" \ | jq -r '.moved[].username'
# 3. Read every current username and build proxy URLscurl -s "$BASE/proxies?api_token=$TOKEN" \ | jq -r '.password as $p | .proxies[] | "http://\(.username):\($p)@isp.shifter.io:443"'Update your clients with the new usernames from step 2 or 3 straight away: the old ones stop working as soon as the move completes.
Errors
Section titled “Errors”A failed request returns "ok": false with a machine-readable error code and a readable message:
{ "ok": false, "error": "plan_inactive", "message": "This plan is not active, so locations cannot be assigned."}| Status | error | Meaning |
|---|---|---|
404 | not_found | The plan or IP does not exist on your account. May include proxy_ids |
422 | validation | A parameter is missing or invalid |
422 | no_changes_left | One or more IPs have used all their location changes for this period. Includes proxy_ids |
409 | out_of_stock | A location does not have enough IPs available. Includes location_id and available |
409 | plan_inactive | The plan is not active, so its IPs cannot be placed or moved |
Rate limits
Section titled “Rate limits”| Requests | Limit |
|---|---|
Reads (GET) | 60 per minute per account |
Writes (POST) | 20 per minute per account |
Past the limit the API answers 429. Wait and retry with backoff. To move many IPs, send them in one Move many IPs request instead of one request per IP.
See also
Section titled “See also”- ISP Proxies overview
- Managing IPs, the same actions in the panel
- Usage & Quota API