Proxynator Proxynator

Use a Mobile Proxy in Python, Node.js and curl

Working examples for curl, Python and Node.js: send requests through your mobile proxy, check the exit IP, rotate it from code, and retry cleanly while the phone reconnects.

Proxynator team 4 min read Updated

This tutorial shows the same three tasks in each language: send a request through the proxy, confirm the exit IP, and rotate the IP from code. Every example reads the credentials from environment variables, so set these first:

export PROXY_URL="http://USER:[email protected]:PORT"
export PROXYNATOR_API_KEY="your-api-key"
export PHONE_ID="your-phone-id"

curl

curl is the quickest way to check that the proxy works.

# HTTP proxy
curl -x "$PROXY_URL" https://api.ipify.org

# SOCKS5, with DNS resolved by the proxy
curl -x "socks5h://USER:[email protected]:PORT" https://api.ipify.org

The output should be the phone’s carrier IP, not your own. If you get 407, the login is wrong; if the command hangs, check that the phone shows as online.

Python with requests

import os
import requests

proxy = os.environ["PROXY_URL"]
proxies = {"http": proxy, "https": proxy}

r = requests.get("https://api.ipify.org?format=json", proxies=proxies, timeout=30)
print(r.json())  # {"ip": "..."}

For SOCKS5, install the extra (pip install "requests[socks]") and use a socks5h:// URL in the same proxies dictionary.

Python with httpx

import os
import httpx

with httpx.Client(proxy=os.environ["PROXY_URL"], timeout=30) as client:
    print(client.get("https://api.ipify.org?format=json").json())

Node.js

Node’s built-in fetch is powered by undici, which ships a proxy agent:

import { fetch, ProxyAgent } from "undici";

const dispatcher = new ProxyAgent(process.env.PROXY_URL);
const res = await fetch("https://api.ipify.org?format=json", { dispatcher });
console.log(await res.json());

With axios, pass an agent from the https-proxy-agent package; for SOCKS use socks-proxy-agent:

import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent(process.env.PROXY_URL);
const { data } = await axios.get("https://api.ipify.org?format=json", { httpsAgent: agent, proxy: false });
console.log(data);

Rotating the IP from code

There are two ways: the REST API (needs your API key) or the phone’s change-IP link (needs only the link).

Method Request Best for
REST API POST /api/v1/phones/PHONE_ID/rotate with a bearer key Your own software, several phones
Change-IP link GET /change-ip?key=PHONE_KEY Tools that can only call a URL

Rotate and wait in Python

import os
import time
import requests

API = "https://proxynator.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PROXYNATOR_API_KEY']}"}
PHONE = os.environ["PHONE_ID"]


def rotate_and_wait(timeout=120):
    old_ip = requests.get(f"{API}/phones/{PHONE}", headers=HEADERS, timeout=15).json().get("ip")
    requests.post(f"{API}/phones/{PHONE}/rotate", headers=HEADERS, timeout=15).raise_for_status()
    deadline = time.time() + timeout
    while time.time() < deadline:
        time.sleep(5)
        phone = requests.get(f"{API}/phones/{PHONE}", headers=HEADERS, timeout=15).json()
        if phone.get("online") and not phone.get("rotating") and phone.get("ip") != old_ip:
            return phone["ip"]
    raise TimeoutError("phone did not come back with a new IP")


print("new IP:", rotate_and_wait())

Retry while the phone reconnects

Requests sent during a rotation fail. A small retry with a growing delay keeps a script running through it:

import time
import requests


def get_with_retry(url, proxies, attempts=6):
    delay = 5
    for i in range(attempts):
        try:
            return requests.get(url, proxies=proxies, timeout=30)
        except requests.RequestException:
            if i == attempts - 1:
                raise
            time.sleep(delay)
            delay = min(delay * 2, 40)

Running requests in parallel

A phone serves many connections at once, up to the plan’s limit: 25 on Lite, 100 on Pro and 300 on Max. Use a connection pool or a semaphore in your code to stay below it, and remember that a rotation drops every open connection, so pause your workers before rotating.

If several tools share one phone, give each its own login (more than one login is part of Max) so you can see and cap their traffic separately.

Troubleshooting

  • 407 Proxy Authentication Required. Wrong login, or special characters in the password that need URL-encoding (for example @ becomes %40).
  • Timeouts. The phone may be offline or rotating. Check its status in the dashboard or through the API.
  • The exit IP is your own. The library isn’t using the proxy. In axios, set proxy: false when you pass your own agent.
  • 429 Too Many Requests from the site. The target is rate-limiting this IP. Slow down, or rotate between batches; see rotating vs sticky sessions.

Summary

Using a mobile proxy in code is one setting in every major HTTP library. Add the rotation API and a retry loop, and you have a script that changes its IP between batches and keeps going while the phone reconnects.

Frequently asked questions

Where do I find my proxy username, password and port?

+

In the dashboard, open the phone. Its proxy login, port and ready-made connection strings are shown there, along with the change-IP link.

Should I put credentials in my code?

+

No. Read them from environment variables or a secrets file, as in the examples, so they don't end up in version control.

Why do requests fail right after I rotate?

+

The phone is reconnecting to the mobile network, which takes 20 to 60 seconds. Wait until the API reports the phone online again, or retry with a back-off.

How many requests can I run in parallel?

+

Up to the plan's connection limit: 25 on Lite, 100 on Pro and 300 on Max. Keep some headroom, because one HTTP request can use more than one connection.

Run your own mobile proxy

Install the Proxynator app on a spare Android phone with a SIM card and get an HTTP and SOCKS5 proxy on a real carrier IP. The first phone gets a 2-day Max trial.

Start the free trial

#python#nodejs#curl#api#automation