Endpoints de esta página
GET /v1/catalog/products: Productos, planes y preciosPOST /v1/orders: Comprar un plan con el saldo (nuevo servicio, más tráfico o ampliación de puerto)GET /v1/orders: Listar pedidosGET /v1/orders/{orderId}: Obtener un pedido
URL base https://africaproxies.com/api/v1. Autenticación, errores y límites: consulta la descripción general de la API.
Productos, planes y precios
GET/v1/catalog/products
Cada producto con sus planes y precios, exactamente como se cobran al hacer el pedido.
Público: no se necesita ninguna clave API.
Respuesta 200 OK
{
"data": [
{
"id": "residential",
"name": "Residential proxies",
"description": "Residential IPs across 49 African locations for public price research, local SEO and your application tests. Prepaid traffic, billed per GB.",
"unit": "GB",
"plans": [
{
"id": "res-10",
"productId": "residential",
"name": "Team",
"quantity": 10,
"unit": "GB",
"durationDays": null,
"price": "5.94",
"pricePerUnit": "0.59",
"popular": false,
"features": [
"Prepaid traffic never expires",
"Country and city where available",
"Project credentials and traffic caps"
],
"available": true,
"countries": null
}
]
}
]
}Ejemplos de código
curl -s "https://africaproxies.com/api/v1/catalog/products"import os
import requests
API = "https://africaproxies.com/api/v1"
r = requests.get(f"{API}/catalog/products", timeout=30)
r.raise_for_status()
print(r.json())// Node.js 18+ (built-in fetch), ES module
const API = 'https://africaproxies.com/api/v1';
const res = await fetch(`${API}/catalog/products`);
if (!res.ok) throw new Error((await res.json()).error?.message ?? `HTTP ${res.status}`);
console.log(await res.json());Comprar un plan con el saldo (nuevo servicio, más tráfico o ampliación de puerto)
POST/v1/orders
Siempre se paga con el saldo prepago: la API calcula el precio (precio del catálogo × quantity), descuenta el saldo, crea o amplía el servicio y devuelve el pedido como completed con su fulfillment. Las credenciales de proxy están disponibles de inmediato.
- Nuevo tráfico residencial:
{ "planId": "res-10" }. - Nuevo tráfico 4G/5G rotativo (por GB):
{ "planId": "mgb-10" }(suscripción de tráfico conproductId: "mobile-gb", entregada enfulfillment.residentialSubscriptionId). - Añadir tráfico a una suscripción existente:
{ "planId": "res-10", "options": { "subscriptionId": "res_9x2m4k" } }: el plan debe pertenecer al producto de la suscripción. - Nuevos puertos móviles:
{ "planId": "mob-30d", "quantity": 1, "options": { "country": "AE" } }, opcionalmente concarrier(consulta los operadores de un país en Puertos móviles). Los planes de zona solo cubren los países de su zona (de lo contrario,422enoptions.country). - Ampliar un puerto móvil:
{ "planId": "mob-7d", "options": { "portId": "mob_2v8k1q" } }añade la duración del plan aexpiresAt.
Saldo insuficiente → 402 insufficient_balance, con el importe que falta y una recarga sugerida en error.details (missing, suggestedTopUp). No se descuenta nada si se produce cualquier error. Para pagar la diferencia, inicia una recarga que incluya la misma solicitud en purchase (POST /v1/topups): el plan se compra en cuanto se abona la recarga.
Autenticación: clave API en el encabezado Authorization: Bearer API_KEY.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
Idempotency-Key | header | string | No | Clave única (por ejemplo, un UUID) para reintentar un POST con seguridad. Se conserva durante 24 h. — máx. 128 caracteres |
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
planId | string | Sí | — |
quantity | integer | No | 1–100, valor predeterminado 1 |
options | object | No | — |
{
"planId": "res-10"
}{
"planId": "mob-30d",
"quantity": 1,
"options": {
"country": "AE",
"carrier": "etisalat",
"autoRenew": true
}
}{
"planId": "mob-7d",
"options": {
"portId": "mob_2v8k1q"
}
}{
"planId": "mgb-10"
}{
"planId": "mob-30d",
"options": {
"country": "AE",
"carrier": "etisalat"
}
}Respuesta 201 Created
{
"id": "ord_4f8k2m9q",
"status": "completed",
"productId": "residential",
"planId": "res-10",
"planName": "Team",
"quantity": 1,
"unitPrice": "5.94",
"subtotal": "5.94",
"discount": "0.00",
"total": "5.94",
"promoCode": null,
"currency": "USD",
"topUpId": null,
"options": {},
"fulfillment": {
"residentialSubscriptionId": "res_9x2m4k",
"mobilePortIds": []
},
"createdAt": "2026-10-05T14:03:11Z",
"paidAt": "2026-10-05T14:03:11Z"
}Ejemplos de código
curl -s -X POST "https://africaproxies.com/api/v1/orders" \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"planId":"res-10"}'import os, uuid
import requests
API = "https://africaproxies.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}", "Idempotency-Key": str(uuid.uuid4())}
r = requests.post(f"{API}/orders", headers=HEADERS, json={"planId": "res-10"}, timeout=30)
r.raise_for_status()
print(r.json())// Node.js 18+ (built-in fetch), ES module
import { randomUUID } from 'node:crypto';
const API = 'https://africaproxies.com/api/v1';
const res = await fetch(`${API}/orders`, {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Idempotency-Key': randomUUID(), 'Content-Type': 'application/json' },
body: JSON.stringify({ planId: 'res-10' }),
});
if (!res.ok) throw new Error((await res.json()).error?.message ?? `HTTP ${res.status}`);
console.log(await res.json());Listar pedidos
GET/v1/orders
Autenticación: clave API en el encabezado Authorization: Bearer API_KEY.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
page | query | integer | No | ≥ 1, valor predeterminado 1 |
perPage | query | integer | No | 1–100, valor predeterminado 20 |
status | query | completed · cancelled | No | Los pedidos se crean ya pagados (descontados del saldo). completed — pagado y entregado (credenciales disponibles de inmediato). |
productId | query | string | No | Identificador del producto en el catálogo. Valores de AfricaProxies: residential (GB), mobile (puertos 4G/5G dedicados) y mobile-gb (tráfico 4G/5G rotativo por GB). Los clientes deben admitir valores desconocidos. |
Respuesta 200 OK
{
"data": [
{
"id": "ord_4f8k2m9q",
"status": "completed",
"productId": "residential",
"planId": "res-10",
"planName": "Team",
"quantity": 1,
"unitPrice": "5.94",
"subtotal": "5.94",
"discount": "0.00",
"total": "5.94",
"promoCode": null,
"currency": "USD",
"topUpId": null,
"options": {},
"fulfillment": {
"residentialSubscriptionId": "res_9x2m4k",
"mobilePortIds": []
},
"createdAt": "2026-10-05T14:03:11Z",
"paidAt": "2026-10-05T14:03:11Z"
}
],
"pagination": {
"page": 1,
"perPage": 20,
"total": 1,
"totalPages": 1
}
}Ejemplos de código
curl -s "https://africaproxies.com/api/v1/orders" \
-H "Authorization: Bearer $API_KEY"import os
import requests
API = "https://africaproxies.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
r = requests.get(f"{API}/orders", headers=HEADERS, timeout=30)
r.raise_for_status()
print(r.json())// Node.js 18+ (built-in fetch), ES module
const API = 'https://africaproxies.com/api/v1';
const res = await fetch(`${API}/orders`, {
headers: { Authorization: `Bearer ${process.env.API_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).error?.message ?? `HTTP ${res.status}`);
console.log(await res.json());Obtener un pedido
GET/v1/orders/{orderId}
Autenticación: clave API en el encabezado Authorization: Bearer API_KEY.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
orderId | path | string | Sí | — |
Respuesta 200 OK
{
"id": "ord_4f8k2m9q",
"status": "completed",
"productId": "residential",
"planId": "res-10",
"planName": "Team",
"quantity": 1,
"unitPrice": "5.94",
"subtotal": "5.94",
"discount": "0.00",
"total": "5.94",
"promoCode": null,
"currency": "USD",
"topUpId": null,
"options": {},
"fulfillment": {
"residentialSubscriptionId": "res_9x2m4k",
"mobilePortIds": []
},
"createdAt": "2026-10-05T14:03:11Z",
"paidAt": "2026-10-05T14:03:11Z"
}Ejemplos de código
curl -s "https://africaproxies.com/api/v1/orders/ord_4f8k2m9q" \
-H "Authorization: Bearer $API_KEY"import os
import requests
API = "https://africaproxies.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['API_KEY']}"}
r = requests.get(f"{API}/orders/ord_4f8k2m9q", headers=HEADERS, timeout=30)
r.raise_for_status()
print(r.json())// Node.js 18+ (built-in fetch), ES module
const API = 'https://africaproxies.com/api/v1';
const res = await fetch(`${API}/orders/ord_4f8k2m9q`, {
headers: { Authorization: `Bearer ${process.env.API_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).error?.message ?? `HTTP ${res.status}`);
console.log(await res.json());