Mobile Proxy API Integration Guide: Python, Node.js & cURL Examples

Mobile Proxy API Integration Guide: Python, Node.js & cURL Examples

Most mobile proxy providers expose APIs for programmatic control — rotating IPs, selecting geolocations, checking proxy status, and managing sessions. Integrating these APIs correctly is the difference between a robust automation pipeline and one that breaks at scale.

This guide provides production-ready code examples in Python, Node.js, and cURL for the most common mobile proxy API operations. We’ve tested these patterns against multiple provider APIs at DataResearchTools.com and distilled the approaches that work reliably.

Common Mobile Proxy API Patterns

While every provider has a slightly different API, most follow similar patterns:

Endpoint Types

  1. Gateway endpoint: A single hostname/port that automatically rotates IPs on each request or at timed intervals. Example: us-mobile.provider.com:5000
  2. Rotation endpoint: An API call that triggers a new IP assignment. Example: POST /api/rotate
  3. Status endpoint: Returns current IP, carrier, location, and session info. Example: GET /api/status
  4. Geo-selection endpoint: Changes the target country or city. Example: POST /api/geo?country=US&state=CA

Authentication Styles

  • Basic auth: Username and password embedded in the proxy URL or headers.
  • API key: A bearer token or query parameter for management API calls.
  • IP whitelist: Your server’s IP is pre-authorized, no credentials needed per request.

Python Integration Examples

Basic Request Through Mobile Proxy

import requests

proxy_config = {
    "http": "socks5://user:password@us-mobile.provider.com:5000",
    "https": "socks5://user:password@us-mobile.provider.com:5000"
}

response = requests.get(
    "https://httpbin.org/ip",
    proxies=proxy_config,
    timeout=30
)

print(f"Current IP: {response.json()['origin']}")

Async Requests with aiohttp

For high-throughput scenarios, async requests dramatically improve performance:

import aiohttp
import asyncio
from aiohttp_socks import ProxyConnector

async def fetch_through_proxy(url, proxy_url):
    connector = ProxyConnector.from_url(proxy_url)
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get(url, timeout=aiohttp.ClientTimeout(total=30)) as resp:
            return await resp.text()

async def main():
    proxy = "socks5://user:password@us-mobile.provider.com:5000"
    urls = [
        "https://httpbin.org/ip",
        "https://httpbin.org/headers",
        "https://httpbin.org/user-agent"
    ]

    tasks = [fetch_through_proxy(url, proxy) for url in urls]
    results = await asyncio.gather(*tasks, return_exceptions=True)

    for url, result in zip(urls, results):
        if isinstance(result, Exception):
            print(f"Error for {url}: {result}")
        else:
            print(f"{url}: {result[:100]}")

asyncio.run(main())

IP Rotation via API

import requests
import time

class MobileProxyManager:
    def __init__(self, api_base, api_key, proxy_host, proxy_port, proxy_user, proxy_pass):
        self.api_base = api_base
        self.api_key = api_key
        self.proxy_url = f"socks5://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
        self.proxies = {
            "http": self.proxy_url,
            "https": self.proxy_url
        }
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        self.current_ip = None

    def get_current_ip(self):
        """Check the current proxy IP."""
        try:
            resp = requests.get(
                "https://api.ipify.org?format=json",
                proxies=self.proxies,
                timeout=15
            )
            self.current_ip = resp.json()["ip"]
            return self.current_ip
        except requests.RequestException as e:
            print(f"IP check failed: {e}")
            return None

    def rotate_ip(self, wait_for_change=True, max_wait=60):
        """Trigger IP rotation and optionally wait for the new IP."""
        old_ip = self.get_current_ip()
        print(f"Current IP: {old_ip}")

        # Trigger rotation via provider API
        resp = requests.post(
            f"{self.api_base}/api/rotate",
            headers=self.headers,
            timeout=15
        )

        if resp.status_code != 200:
            raise Exception(f"Rotation failed: {resp.status_code} - {resp.text}")

        if not wait_for_change:
            return True

        # Wait for IP to actually change
        start_time = time.time()
        while time.time() - start_time < max_wait:
            time.sleep(3)
            new_ip = self.get_current_ip()
            if new_ip and new_ip != old_ip:
                print(f"New IP: {new_ip}")
                return True

        print("Warning: IP did not change within timeout")
        return False

    def set_geo(self, country, state=None, city=None):
        """Set geographic location for the proxy."""
        payload = {"country": country}
        if state:
            payload["state"] = state
        if city:
            payload["city"] = city

        resp = requests.post(
            f"{self.api_base}/api/geo",
            headers=self.headers,
            json=payload,
            timeout=15
        )

        if resp.status_code == 200:
            print(f"Geo set to: {payload}")
            return True
        else:
            print(f"Geo change failed: {resp.text}")
            return False

    def get_status(self):
        """Get full proxy status including carrier and location."""
        resp = requests.get(
            f"{self.api_base}/api/status",
            headers=self.headers,
            timeout=15
        )
        return resp.json()

# Usage
manager = MobileProxyManager(
    api_base="https://api.provider.com",
    api_key="your-api-key",
    proxy_host="us-mobile.provider.com",
    proxy_port=5000,
    proxy_user="user",
    proxy_pass="password"
)

# Check current IP
print(manager.get_current_ip())

# Rotate to new IP
manager.rotate_ip()

# Change geo location
manager.set_geo("US", state="CA")

Robust Request with Retry Logic

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import time

def create_session_with_retries(proxy_url, max_retries=3):
    """Create a requests session with mobile-proxy-aware retry logic."""
    session = requests.Session()

    # Configure retries for transient mobile network errors
    retry_strategy = Retry(
        total=max_retries,
        backoff_factor=2,  # 2s, 4s, 8s between retries
        status_forcelist=[429, 500, 502, 503, 504],
        allowed_methods=["HEAD", "GET", "POST"]
    )

    adapter = HTTPAdapter(max_retries=retry_strategy)
    session.mount("http://", adapter)
    session.mount("https://", adapter)

    session.proxies = {
        "http": proxy_url,
        "https": proxy_url
    }

    # Mobile-appropriate timeout (mobile networks can be slow)
    session.timeout = (10, 30)  # 10s connect, 30s read

    return session

proxy = "socks5://user:pass@mobile.proxy.com:5000"
session = create_session_with_retries(proxy)

try:
    response = session.get("https://target-site.com/api/data")
    print(f"Status: {response.status_code}")
except requests.RequestException as e:
    print(f"Request failed after retries: {e}")

Node.js Integration Examples

Basic Request with axios

const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');

const proxyAgent = new SocksProxyAgent(
  'socks5://user:password@us-mobile.provider.com:5000'
);

async function fetchThroughProxy(url) {
  try {
    const response = await axios.get(url, {
      httpAgent: proxyAgent,
      httpsAgent: proxyAgent,
      timeout: 30000
    });
    return response.data;
  } catch (error) {
    console.error(`Request failed: ${error.message}`);
    throw error;
  }
}

// Usage
fetchThroughProxy('https://httpbin.org/ip')
  .then(data => console.log('Current IP:', data.origin));

node-fetch with Proxy

const fetch = require('node-fetch');
const { SocksProxyAgent } = require('socks-proxy-agent');

const agent = new SocksProxyAgent(
  'socks5://user:password@us-mobile.provider.com:5000'
);

async function proxyFetch(url, options = {}) {
  const response = await fetch(url, {
    ...options,
    agent,
    timeout: 30000
  });

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }

  return response;
}

// Usage
(async () => {
  const resp = await proxyFetch('https://httpbin.org/ip');
  const data = await resp.json();
  console.log('IP:', data.origin);
})();

IP Rotation Manager in Node.js

const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');

class MobileProxyManager {
  constructor(config) {
    this.apiBase = config.apiBase;
    this.apiKey = config.apiKey;
    this.proxyUrl = `socks5://${config.proxyUser}:${config.proxyPass}@${config.proxyHost}:${config.proxyPort}`;
    this.agent = new SocksProxyAgent(this.proxyUrl);
    this.currentIp = null;
  }

  async getCurrentIp() {
    const resp = await axios.get('https://api.ipify.org?format=json', {
      httpAgent: this.agent,
      httpsAgent: this.agent,
      timeout: 15000
    });
    this.currentIp = resp.data.ip;
    return this.currentIp;
  }

  async rotateIp(maxWaitMs = 60000) {
    const oldIp = await this.getCurrentIp();
    console.log(`Current IP: ${oldIp}`);

    await axios.post(`${this.apiBase}/api/rotate`, null, {
      headers: { Authorization: `Bearer ${this.apiKey}` },
      timeout: 15000
    });

    const startTime = Date.now();
    while (Date.now() - startTime < maxWaitMs) {
      await new Promise(resolve => setTimeout(resolve, 3000));
      const newIp = await this.getCurrentIp();
      if (newIp && newIp !== oldIp) {
        console.log(`New IP: ${newIp}`);
        return newIp;
      }
    }

    throw new Error('IP rotation timed out');
  }

  async setGeo(country, state = null) {
    const payload = { country };
    if (state) payload.state = state;

    const resp = await axios.post(`${this.apiBase}/api/geo`, payload, {
      headers: {
        Authorization: `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      timeout: 15000
    });

    return resp.data;
  }
}

// Usage
const manager = new MobileProxyManager({
  apiBase: 'https://api.provider.com',
  apiKey: 'your-api-key',
  proxyHost: 'us-mobile.provider.com',
  proxyPort: 5000,
  proxyUser: 'user',
  proxyPass: 'password'
});

(async () => {
  console.log('IP:', await manager.getCurrentIp());
  await manager.rotateIp();
  await manager.setGeo('US', 'CA');
})();

cURL Examples

Basic Proxy Request

# SOCKS5 proxy
curl -x socks5://user:password@us-mobile.provider.com:5000 \
     https://httpbin.org/ip

# HTTP proxy
curl -x http://user:password@us-mobile.provider.com:5000 \
     https://httpbin.org/ip

Check Proxy IP and Headers

# Full header inspection
curl -x socks5://user:pass@mobile.proxy.com:5000 \
     -v https://httpbin.org/headers 2>&1

# Just the IP
curl -x socks5://user:pass@mobile.proxy.com:5000 \
     -s https://api.ipify.org

Trigger IP Rotation

# Rotate IP via provider API
curl -X POST https://api.provider.com/api/rotate \
     -H "Authorization: Bearer your-api-key" \
     -H "Content-Type: application/json"

# Wait a few seconds, then verify
sleep 5
curl -x socks5://user:pass@mobile.proxy.com:5000 \
     -s https://api.ipify.org

Set Geo Location

curl -X POST https://api.provider.com/api/geo \
     -H "Authorization: Bearer your-api-key" \
     -H "Content-Type: application/json" \
     -d '{"country": "US", "state": "CA", "city": "Los Angeles"}'

Speed Test via cURL

# Download speed test (10MB file)
curl -x socks5://user:pass@mobile.proxy.com:5000 \
     -o /dev/null -w "Speed: %{speed_download} bytes/sec\nTime: %{time_total}s\n" \
     https://speed.hetzner.de/10MB.bin

# Latency test (time to first byte)
curl -x socks5://user:pass@mobile.proxy.com:5000 \
     -o /dev/null -s -w "TTFB: %{time_starttransfer}s\n" \
     https://httpbin.org/ip

Error Handling for Mobile-Specific Issues

Mobile proxies introduce unique failure modes that don’t exist with datacenter or residential proxies. Your code needs to handle these gracefully.

Connection Drops

Mobile networks are inherently less stable than wired connections. Carriers can drop connections during cell tower handoffs, signal degradation, or network congestion.

import requests
from requests.exceptions import ConnectionError, Timeout, ProxyError

def resilient_request(url, proxies, max_attempts=3):
    for attempt in range(max_attempts):
        try:
            response = requests.get(url, proxies=proxies, timeout=30)
            return response
        except (ConnectionError, ProxyError) as e:
            if attempt < max_attempts - 1:
                wait = (attempt + 1) * 5  # 5s, 10s, 15s
                print(f"Connection error (attempt {attempt + 1}): {e}")
                print(f"Retrying in {wait}s...")
                time.sleep(wait)
            else:
                raise
        except Timeout:
            if attempt < max_attempts - 1:
                print(f"Timeout (attempt {attempt + 1}), retrying...")
                time.sleep(3)
            else:
                raise

Slow IP Rotation

Mobile IP rotation isn’t instant. It can take 5-30 seconds depending on the provider and carrier. Your code should poll for the IP change rather than assuming it’s immediate.

Rate Limiting

Mobile proxies have bandwidth constraints. A single 4G modem can typically handle 20-50 Mbps at best. If you’re running multiple concurrent requests, you need to respect this limit.

import asyncio
from asyncio import Semaphore

# Limit concurrent requests per mobile proxy
semaphore = Semaphore(5)  # Max 5 concurrent requests

async def rate_limited_request(session, url):
    async with semaphore:
        async with session.get(url) as response:
            return await response.text()

Rate Limiting Best Practices

  1. Per-proxy concurrency: Limit to 3-5 concurrent requests per mobile proxy endpoint. More than that risks timeouts and IP-level rate limiting on target sites.
  1. Request spacing: Add 1-3 second delays between requests to the same target domain. Mobile users don’t send 100 requests per second.
  1. Bandwidth awareness: Track your bandwidth consumption per proxy. Most providers charge per GB, and overshooting your allocation leads to unexpected bills or throttling.
  1. Rotation cooldown: After rotating an IP, wait at least 5 seconds before sending requests. The new connection needs time to stabilize.
  1. Error-triggered backoff: If you receive 429 (Too Many Requests) or consistent timeouts, implement exponential backoff starting at 10 seconds.

Provider API Comparison

Different mobile proxy providers offer varying API capabilities:

FeatureProvider AProvider BProvider C
IP rotation APIYesYesManual only
Geo-selectionCountry + CityCountry onlyCountry
Status endpointFull detailsIP onlyNone
Webhook on rotationYesNoNo
Bandwidth monitoringReal-timeDailyMonthly
Session managementSticky + RotatingRotating onlyBoth

When choosing a provider for API-heavy integrations, prioritize those with comprehensive APIs. The ability to programmatically rotate IPs, check status, and select geolocations is essential for production systems.

Conclusion

Integrating mobile proxies via API is straightforward once you understand the patterns. The key differences from datacenter proxy integration are: longer timeouts (mobile networks are slower), robust retry logic (mobile connections drop), rate limiting (bandwidth is finite), and rotation verification (always confirm IP changes before proceeding).

The code examples in this guide are production-tested patterns. Adapt them to your specific provider’s API endpoints and authentication scheme. For testing your integration, use our IP Lookup Tool to verify proxy IPs and our Browser Fingerprint Tester to confirm your automated sessions look legitimate.


Related Reading

Scroll to Top