Proxy list API
Ready proxy lines for your scraper, antidetect browser or bot: up to 500 per call, in the format your tool reads.
The generator is the dashboard's proxy list form as an endpoint. It writes the targeting and session keys into each login for you and checks every value against the location lists first, so a line it returns is never refused for a wrong key.
Sticky lines each get their own session key: every line keeps one exit IP for ttl minutes (1–60), then moves to a new one. Rotating lines change the exit IP on every connection, so all of them are the same line and one is enough. Generating costs nothing: traffic is counted only when the lines carry requests through the gateway.
Generate a proxy list
/api/v1/proxy-listReturns count lines as JSON, each split into host, port, username and password and joined in your format. Send "output": "text" to get plain text, one line per row.
Body (JSON)
| Name | Type | Description |
|---|---|---|
productrequired | residential | mobile | Which pool: residential or mobile. |
country | string | Country code from List countries. Omit for any country. |
region | string | Region name or slug from List regions. Needs country. |
city | string | City name or slug from List cities. Needs country. |
isp | string | Residential only: ISP from List ISPs. Needs country. |
carrier | string | Mobile only: carrier from List ISPs. Needs country. |
session | sticky | rotating | sticky: one exit IP per line for ttl minutes. rotating: a new exit IP on every connection. Default sticky. |
ttl | integer | Sticky only: minutes each line keeps its IP. 1–60. Default 10. |
protocol | http | socks5 | http (HTTP and HTTPS, port 7000) or socks5 (port 7001, TCP and UDP). Default http. |
count | integer | How many lines. 1–500. Default 10. |
format | string | How proxy joins the parts. protocol://… writes http:// or socks5://. One of: host:port:user:pass, host:port@user:pass, user:pass:host:port, user:pass@host:port, protocol://user:pass@host:port. Default host:port:user:pass. |
sub_user_id | integer | Build the lines on a sub-user's login (same product) instead of the main one, so its traffic limit applies. |
output | json | text | text answers text/plain with one proxy per line. Default json. |
Request
curl -X POST "https://aeonproxy.com/api/v1/proxy-list" \
-H "Authorization: Bearer $AEONPROXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product":"residential","country":"us","region":"new york","session":"sticky","ttl":30,"count":3}'import os
import requests
r = requests.post(
"https://aeonproxy.com/api/v1/proxy-list",
headers={"Authorization": f"Bearer {os.environ['AEONPROXY_API_KEY']}"},
json={"product": "residential", "country": "us", "region": "new york", "session": "sticky", "ttl": 30, "count": 3},
timeout=30,
)
data = r.json()
if not r.ok:
raise SystemExit(data["error"]["message"])
print(data)// Node.js 18+, as an ES module (.mjs)
const res = await fetch("https://aeonproxy.com/api/v1/proxy-list", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AEONPROXY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ product: "residential", country: "us", region: "new york", session: "sticky", ttl: 30, count: 3 }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error.message);
console.log(data);<?php
$ch = curl_init('https://aeonproxy.com/api/v1/proxy-list');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('AEONPROXY_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['product' => 'residential', 'country' => 'us', 'region' => 'new york', 'session' => 'sticky', 'ttl' => 30, 'count' => 3]),
CURLOPT_RETURNTRANSFER => true,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$data = json_decode($body, true);
if ($status >= 400) {
fwrite(STDERR, $data['error']['message'] . PHP_EOL);
exit(1);
}
print_r($data);package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
body := strings.NewReader(`{"product":"residential","country":"us","region":"new york","session":"sticky","ttl":30,"count":3}`)
req, err := http.NewRequest("POST", "https://aeonproxy.com/api/v1/proxy-list", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AEONPROXY_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status)
fmt.Println(string(out))
}Response 200
{
"product": "residential",
"session": "sticky",
"ttl": 30,
"protocol": "http",
"format": "host:port:user:pass",
"count": 3,
"results": [
{
"host": "gate.aeonproxy.com",
"port": 7000,
"username": "ap_u1a2b-cc-us-st-newyork-sid-4f2a9c1e-ttl-30",
"password": "Xr7pQ2mK9sLd",
"proxy": "gate.aeonproxy.com:7000:ap_u1a2b-cc-us-st-newyork-sid-4f2a9c1e-ttl-30:Xr7pQ2mK9sLd"
},
{
"host": "gate.aeonproxy.com",
"port": 7000,
"username": "ap_u1a2b-cc-us-st-newyork-sid-b71d03aa-ttl-30",
"password": "Xr7pQ2mK9sLd",
"proxy": "gate.aeonproxy.com:7000:ap_u1a2b-cc-us-st-newyork-sid-b71d03aa-ttl-30:Xr7pQ2mK9sLd"
},
{
"host": "gate.aeonproxy.com",
"port": 7000,
"username": "ap_u1a2b-cc-us-st-newyork-sid-9e5c62f0-ttl-30",
"password": "Xr7pQ2mK9sLd",
"proxy": "gate.aeonproxy.com:7000:ap_u1a2b-cc-us-st-newyork-sid-9e5c62f0-ttl-30:Xr7pQ2mK9sLd"
}
]
}Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_parameter | product is missing or not residential / mobile |
| 400 | invalid_parameter | a country, region, city, ISP or carrier outside the lists, or one of them without country |
| 404 | not_found | sub_user_id is not one of your sub-users of that product |
Download a proxy list
/api/v1/proxy-listThe same generator with the parameters in the query string, for tools that only fetch a URL and for curl … > proxies.txt. With output=text the answer is plain text. URL-encode format: user%3Apass%40host%3Aport.
Query parameters
| Name | Type | Description |
|---|---|---|
productrequired | residential | mobile | Which pool: residential or mobile. |
country | string | As in Generate a proxy list; so are region, city, isp, carrier, ttl, protocol, format and sub_user_id. |
session | sticky | rotating | Sticky or rotating lines. Default sticky. |
count | integer | How many lines. 1–500. Default 10. |
output | json | text | text answers text/plain, one line per row. Default json. |
Request
curl "https://aeonproxy.com/api/v1/proxy-list?product=residential&country=us®ion=newyork&ttl=30&count=3&format=user%3Apass%40host%3Aport&output=text" \
-H "Authorization: Bearer $AEONPROXY_API_KEY"import os
import requests
r = requests.get(
"https://aeonproxy.com/api/v1/proxy-list?product=residential&country=us®ion=newyork&ttl=30&count=3&format=user%3Apass%40host%3Aport&output=text",
headers={"Authorization": f"Bearer {os.environ['AEONPROXY_API_KEY']}"},
timeout=30,
)
r.raise_for_status()
print(r.text)// Node.js 18+, as an ES module (.mjs)
const res = await fetch("https://aeonproxy.com/api/v1/proxy-list?product=residential&country=us®ion=newyork&ttl=30&count=3&format=user%3Apass%40host%3Aport&output=text", {
headers: {
Authorization: `Bearer ${process.env.AEONPROXY_API_KEY}`,
},
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
console.log(await res.text());<?php
$ch = curl_init('https://aeonproxy.com/api/v1/proxy-list?product=residential&country=us®ion=newyork&ttl=30&count=3&format=user%3Apass%40host%3Aport&output=text');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('AEONPROXY_API_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status >= 400) {
fwrite(STDERR, "HTTP $status" . PHP_EOL);
exit(1);
}
echo $body, PHP_EOL;package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", "https://aeonproxy.com/api/v1/proxy-list?product=residential&country=us®ion=newyork&ttl=30&count=3&format=user%3Apass%40host%3Aport&output=text", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AEONPROXY_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status)
fmt.Println(string(out))
}Response 200text/plain
ap_u1a2b-cc-us-st-newyork-sid-4f2a9c1e-ttl-30:[email protected]:7000
ap_u1a2b-cc-us-st-newyork-sid-b71d03aa-ttl-30:[email protected]:7000
ap_u1a2b-cc-us-st-newyork-sid-9e5c62f0-ttl-30:[email protected]:7000Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_parameter | product is missing or not residential / mobile |
| 400 | invalid_parameter | a value outside the lists, or a malformed number |
Example: Save 100 sticky US proxies to a file
One line per session, ten minutes each, in the format most antidetect browsers import.
import os, requests
r = requests.post(
"https://aeonproxy.com/api/v1/proxy-list",
headers={"Authorization": f"Bearer {os.environ['AEONPROXY_API_KEY']}"},
json={"product": "residential", "country": "us", "count": 100, "ttl": 10, "output": "text"},
timeout=30,
)
r.raise_for_status()
open("proxies.txt", "w").write(r.text + "\n")Proxy list API: questions
Up to 500 lines. Call it again for more: every sticky line has its own random session key, so lines from two calls never share an exit by accident.
No. A line works for as long as its login and password do. A sticky line keeps its exit IP for ttl minutes after its first connection, then takes a new one with the same line.