PROXYRADAR DEVELOPER GUIDES

Proxy Detection in Python, Node.js & PHP

Call the ProxyRadar API from your server with an Authorization bearer header, the public IP to check and format=json. The examples below return a classification only after validating a successful response; errors remain an explicit unknown state.

Before you start

Create a free account, copy the API key from your dashboard and store it in a server-side environment variable named PROXYRADAR_API_KEY. The free account includes 1,000 successful requests per day. Do not commit the key to source control or put these authenticated requests in browser JavaScript.

Each example accepts one IP as a command-line argument. Use the public address you intend to check. The sample address 8.8.8.8 is for demonstrating the request, not a guaranteed example of a negative result. Classifications can change.

All examples use a 15-second request timeout and avoid automatic retries. If your application requires retries, add a bounded policy and respect Retry-After on HTTP 429. Do not retry invalid input or an invalid API key without correcting the request.

Proxy detection in Python

This example uses Python’s standard library; no third-party HTTP package is required. Save it as proxy-check.py and run python proxy-check.py 8.8.8.8 after setting the environment variable.

import ipaddress
import json
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, HTTPRedirectHandler, build_opener


class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, request, fp, code, message, headers, new_url):
        return None


def check_ip(ip, api_key):
    ipaddress.ip_address(ip)
    if not api_key:
        raise ValueError("Set PROXYRADAR_API_KEY on your server.")
    query = urlencode({"ip": ip, "format": "json"})
    request = Request(
        "https://proxyradar.io/v1/check?" + query,
        headers={"Authorization": "Bearer " + api_key, "Accept": "application/json"},
    )
    try:
        with build_opener(NoRedirect()).open(request, timeout=15) as response:
            raw = response.read(65537)
        if len(raw) > 65536:
            raise ValueError("Response too large")
        data = json.loads(raw)
        if not isinstance(data, dict) or data.get("status") != "success":
            raise ValueError("Unexpected response")
        if type(data.get("proxy")) is not int or data["proxy"] not in (0, 1):
            raise ValueError("Unexpected verdict")
        return {"ip": data["ip"], "proxy": data["proxy"], "flags": data.get("flags")}
    except HTTPError as error:
        raise RuntimeError(f"Lookup unavailable (HTTP {error.code}); result is unknown.") from None
    except (URLError, TimeoutError, ValueError, KeyError):
        raise RuntimeError("Lookup unavailable; result is unknown.") from None


if __name__ == "__main__":
    if len(sys.argv) != 2:
        sys.exit("Usage: python proxy-check.py PUBLIC_IP")
    try:
        result = check_ip(sys.argv[1], os.environ.get("PROXYRADAR_API_KEY", ""))
        print(json.dumps(result, indent=2))
    except (ValueError, RuntimeError) as error:
        sys.exit(str(error))

Open the Python example as plain text →

Proxy detection in Node.js

Use a Node.js version with built-in fetch and AbortSignal.timeout. Save the module as proxy-check.mjs and run node proxy-check.mjs 8.8.8.8. You can also import checkIp into your backend.

import { isIP } from 'node:net';
import { pathToFileURL } from 'node:url';

export async function checkIp(ip, apiKey) {
  if (!isIP(ip)) throw new Error('Supply a valid public IP address.');
  if (!apiKey) throw new Error('Set PROXYRADAR_API_KEY on your server.');
  const url = new URL('https://proxyradar.io/v1/check');
  url.search = new URLSearchParams({ ip, format: 'json' }).toString();
  let response;
  try {
    response = await fetch(url, {
      headers: { Authorization: `Bearer ${apiKey}`, Accept: 'application/json' },
      signal: AbortSignal.timeout(15000),
      redirect: 'error',
    });
  } catch {
    throw new Error('Lookup unavailable; result is unknown.');
  }
  if (!response.ok) {
    throw new Error(`Lookup unavailable (HTTP ${response.status}); result is unknown.`);
  }
  try {
    const body = await response.text();
    if (body.length > 65536) throw new Error('Response too large');
    const data = JSON.parse(body);
    if (data?.status !== 'success' || ![0, 1].includes(data.proxy)) {
      throw new Error('Unexpected verdict');
    }
    return { ip: data.ip, proxy: data.proxy, flags: data.flags };
  } catch {
    throw new Error('Invalid lookup response; result is unknown.');
  }
}

if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  try {
    const result = await checkIp(process.argv[2] || '', process.env.PROXYRADAR_API_KEY);
    console.log(JSON.stringify(result, null, 2));
  } catch (error) {
    console.error(error.message);
    process.exitCode = 1;
  }
}

Open the Node.js example as plain text →

Proxy detection in PHP

This example uses PHP with the cURL extension. Save it as proxy-check.php and run php proxy-check.php 8.8.8.8. The checkIp function can also be called from your application; keep the key in server configuration.

<?php
function checkIp(string $ip, string $apiKey): array
{
    if (!filter_var($ip, FILTER_VALIDATE_IP)) {
        throw new InvalidArgumentException('Supply a valid public IP address.');
    }
    if ($apiKey === '') {
        throw new InvalidArgumentException('Set PROXYRADAR_API_KEY on your server.');
    }
    $url = 'https://proxyradar.io/v1/check?' . http_build_query(
        ['ip' => $ip, 'format' => 'json'], '', '&', PHP_QUERY_RFC3986
    );
    $handle = curl_init($url);
    curl_setopt_array($handle, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey, 'Accept: application/json'],
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT => 15,
        CURLOPT_FOLLOWLOCATION => false,
    ]);
    $body = curl_exec($handle);
    $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
    curl_close($handle);
    if ($body === false || $status !== 200 || strlen($body) > 65536) {
        throw new RuntimeException('Lookup unavailable; result is unknown.');
    }
    try {
        $data = json_decode($body, true, 32, JSON_THROW_ON_ERROR);
        if (!is_array($data) || ($data['status'] ?? null) !== 'success'
            || !in_array($data['proxy'] ?? null, [0, 1], true)) {
            throw new RuntimeException('Unexpected verdict');
        }
    } catch (Throwable $error) {
        throw new RuntimeException('Invalid lookup response; result is unknown.');
    }
    return ['ip' => $data['ip'], 'proxy' => $data['proxy'], 'flags' => $data['flags'] ?? null];
}

if (PHP_SAPI === 'cli' && realpath($_SERVER['SCRIPT_FILENAME'] ?? '') === __FILE__) {
    try {
        $result = checkIp($argv[1] ?? '', getenv('PROXYRADAR_API_KEY') ?: '');
        echo json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . PHP_EOL;
    } catch (Throwable $error) {
        fwrite(STDERR, $error->getMessage() . PHP_EOL);
        exit(1);
    }
}

Open the PHP example as plain text →

Turn the result into an application decision

Read proxy as the overall result. A value of 1 includes proxy-related and hosting classifications. Available category flags add context, but a false VPN flag does not override a positive overall result. A value of 0 means no proxy was detected, not that a visitor is necessarily human or safe.

Do not return proxy: 0 from a catch block. If a request fails, return an explicit unknown state to your application and use the policy you chose for that action. For example, a public page view might proceed with ordinary rate limits, while a sensitive action might require verification or a retry.

Common integration mistakes

Use the response field reference for exact semantics and the traffic policy guide when deciding what a result should do in your app.

Put the guide into practice.

Check an IP in your browser or start with 1,000 free API queries per day.

Keep exploring