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 del puerto)GET /v1/orders: Listar pedidosGET /v1/orders/{orderId}: Consultar un pedido
URL base https://localserpproxy.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
Todos los productos con sus planes y precios, exactamente como se cobran al hacer el pedido.
Público: no se necesita una clave de API.
Respuesta 200 OK
{
"data": [
{
"id": "residential",
"name": "Residential proxies",
"description": "Residential traffic for manual local search, advertising, price and application checks in US cities. State, city and ZIP selection, subject to available exits; no promise of GPS position or rankings.",
"unit": "GB",
"plans": [
{
"id": "res-10",
"productId": "residential",
"name": "Local team",
"quantity": 10,
"unit": "GB",
"durationDays": null,
"price": "7.50",
"pricePerUnit": "0.75",
"popular": false,
"features": [
"US city selection, subject to availability",
"Traffic stays until used",
"Rotating or sticky sessions"
],
"available": true,
"countries": null
}
]
}
]
}Ejemplos de código
curl -s "https://localserpproxy.com/api/v1/catalog/products"import os
import requests
API = "https://localserpproxy.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://localserpproxy.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());Compra un plan con el saldo (nuevo servicio, más tráfico o ampliación de un puerto)
POST/v1/orders
El pago siempre se realiza con el saldo prepago: la API calcula el precio (precio del catálogo × quantity), descuenta el importe del saldo, crea o amplía el servicio y devuelve el pedido completed con su fulfillment. Las credenciales del proxy están disponibles de inmediato.
- Nuevo tráfico residencial:
{ "planId": "res-10" }. - Nuevo tráfico rotativo 4G/5G (por GB):
{ "planId": "mgb-10" }(una 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-us-30d", "quantity": 1, "options": { "country": "US" } }, opcionalmente concarrier(consulta los operadores de un país en Puertos móviles). Los planes por zona solo cubren los países de esa zona (422enoptions.countryen caso contrario). - Ampliar un puerto móvil:
{ "planId": "mob-us-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 un 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 acredita la recarga.
Autenticación: clave de API en el encabezado Authorization: Bearer API_KEY.
Parámetros
| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
Idempotency-Key | header | string | No | Clave única (p. ej., un UUID) para reintentar un POST de forma segura. Se conserva durante 24 h. — máx. 128 caracteres |
Cuerpo de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
planId | string | Sí | — |
quantity | integer | No | 1–100, predeterminado 1 |
options | object | No | — |
{
"planId": "res-10"
}{
"planId": "mob-us-30d",
"quantity": 1,
"options": {
"country": "US",
"carrier": "verizon",
"autoRenew": true
}
}{
"planId": "mob-us-7d",
"options": {
"portId": "mob_2v8k1q"
}
}{
"planId": "mgb-10"
}{
"planId": "mob-us-30d",
"options": {
"country": "US",
"carrier": "verizon"
}
}Respuesta 201 Created
{
"id": "ord_4f8k2m9q",
"status": "completed",
"productId": "residential",
"planId": "res-10",
"planName": "Local team",
"quantity": 1,
"unitPrice": "7.50",
"subtotal": "7.50",
"discount": "0.00",
"total": "7.50",
"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://localserpproxy.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://localserpproxy.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://localserpproxy.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 de API en el encabezado Authorization: Bearer API_KEY.
Parámetros
| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
page | query | integer | No | ≥ 1, predeterminado 1 |
perPage | query | integer | No | 1–100, 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 | ID del producto del catálogo. Valores para LocalSERP Proxy: residential (GB), mobile (puertos dedicados 4G/5G) y mobile-gb (tráfico rotativo 4G/5G por GB). Los clientes deben admitir valores desconocidos. |
Respuesta 200 OK
{
"data": [
{
"id": "ord_4f8k2m9q",
"status": "completed",
"productId": "residential",
"planId": "res-10",
"planName": "Local team",
"quantity": 1,
"unitPrice": "7.50",
"subtotal": "7.50",
"discount": "0.00",
"total": "7.50",
"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://localserpproxy.com/api/v1/orders" \
-H "Authorization: Bearer $API_KEY"import os
import requests
API = "https://localserpproxy.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://localserpproxy.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 de API en el encabezado Authorization: Bearer API_KEY.
Parámetros
| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
orderId | path | string | Sí | — |
Respuesta 200 OK
{
"id": "ord_4f8k2m9q",
"status": "completed",
"productId": "residential",
"planId": "res-10",
"planName": "Local team",
"quantity": 1,
"unitPrice": "7.50",
"subtotal": "7.50",
"discount": "0.00",
"total": "7.50",
"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://localserpproxy.com/api/v1/orders/ord_4f8k2m9q" \
-H "Authorization: Bearer $API_KEY"import os
import requests
API = "https://localserpproxy.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://localserpproxy.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());