mobileproxy.app

API

Referencia de la API

Una referencia completa, endpoint por endpoint, de la API REST de mobileproxy.app. Cada ruta, campo y ejemplo refleja el documento OpenAPI en vivo con el que se construye la API. URL base https://mobileproxy.app/api/v1.

Autenticación y URL base

Todos los endpoints están bajo https://mobileproxy.app/api/v1 y requieren un token bearer. Crea uno en el panel, en Para desarrolladores → Tokens de API, o con POST /tokens con la sesión iniciada. El secreto se muestra una sola vez: guárdalo. Envíalo en cada petición:

Authorization: Bearer mpx_live_…

Los tokens que empiezan por mpx_live_ son los tokens de tu cuenta. Los endpoints /device/* los llama la propia app de Android y se autentican con un token de dispositivo por teléfono (mpxdev_…) emitido en el emparejamiento: normalmente nunca los llamas.

Pruébalo en vivo
La consola interactiva te permite pegar un token y llamar a cada endpoint desde el navegador, con cuerpos de petición y respuestas reales. La especificación en bruto está en /api/v1/openapi.json.

Los errores son JSON con un mensaje legible y un código para máquinas:

{ "error": "No such device.", "code": "not_found" }
CampoTipoDescripción
401unauthorizedToken ausente, con formato incorrecto o revocado.
403forbiddenToken válido pero sin permiso.
404not_foundEl recurso no existe en esta cuenta.
502control_plane_unavailableGateway/plano de control momentáneamente inaccesible: reintenta.

Cuenta

GET /me — ¿quién soy? Devuelve la cuenta más los recuentos en vivo de suscripciones y tokens de API.

curl https://mobileproxy.app/api/v1/me \
     -H "Authorization: Bearer mpx_live_…"

# → { "id": "u_8c31f0", "email": "[email protected]",
#     "created_at": "2026-06-28T14:02:11.000Z",
#     "subscriptions": 3, "api_tokens": 2,
#     "plan": "beta", "balance": "0.00" }

Suscripciones

Una suscripción (id sub_…) es la ranura duradera que posees: su name descriptivo, sus ajustes y sus proxies persisten aunque cambie el teléfono que la respalda. Su device es el teléfono que la alimenta actualmente (o null cuando no está emparejada), y es intercambiable: un cambio conserva todos los endpoints de proxy.

Lista las suscripciones — cada una con su dispositivo emparejado fusionado con el estado en vivo del gateway (online = el túnel del proxy está activo):

curl https://mobileproxy.app/api/v1/subscriptions \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscriptions": [ {
#     "id": "sub_760c1fc8ddab", "name": "Paris SFR",
#     "status": "active", "wifi_split": true, "created_at": "…",
#     "device": { "id": "phone_ac862619408e", "model": "Galaxy S8",
#                 "hardware_id": "352091081234567", "hardware_type": "imei",
#                 "status": "online", "exit_ip": "77.136.66.63",
#                 "carrier": "SFR", "last_seen": "…", "paired_at": "…" } } ] }

Crea una suscripción (sin emparejar) y luego empareja o cambia el teléfono. POST /subscriptions/{id}/pair devuelve un PIN válido ~3 minutos; introducido en la app de Android, vincula el teléfono. En una ranura que ya tiene dispositivo, esto es un cambio (mode: "swap"): el teléfono antiguo se retira y cada proxy conserva su host:puerto y sus credenciales:

curl -X POST https://mobileproxy.app/api/v1/subscriptions \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" -d '{ "name": "Paris SFR" }'
# → { "id": "sub_760c1fc8ddab", "status": "unpaired", "device": null, … }

# Pair (or swap) a phone into it
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/pair \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "mode": "new",
#     "pairing": { "pin": "483-119-702", "expires_at": "…" }, … }

Obtén, actualiza o cancela una suscripción. POST cambia el nombre, una description libre (máx. 200 caracteres, null la borra), la preferencia wifi_split (encolada al teléfono emparejado, aplicada en su siguiente sondeo ~25 s) o shared_speed_kbps: cómo se reparte la velocidad del dispositivo entre sus proxies. -1 (recomendado) la comparte automáticamente: el plano de control mide la velocidad real del dispositivo a partir del rendimiento en vivo (reajuste ~3 s), los proxies ocupados al mismo tiempo convergen a partes iguales de ella, y un proxy que trabaja solo obtiene toda la velocidad. Un valor > 0 reparte del mismo modo ese total fijo del dispositivo. Los valores speed_limit_kbps por proxy se conservan pero no se aplican mientras cualquiera de las dos opciones esté activa; 0 desactiva el reparto. DELETE desmonta su dispositivo y sus proxies, libera los puertos del gateway y elimina el historial de la ranura: es irreversible:

# Fetch one subscription
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID \
     -H "Authorization: Bearer mpx_live_…"

# Rename / describe / set Wi-Fi split / share the device's speed equally (auto)
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "name": "Paris SFR", "description": "Client X — farm slot 2", "wifi_split": true, "shared_speed_kbps": -1 }'

# Cancel (irreversible)
curl -X DELETE https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID \
     -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "id": "sub_760c1fc8ddab" }

Proxies

Un proxy es un único endpoint de un solo protocolo (SOCKS5 o HTTP) en un dispositivo, con su propia autenticación, lista blanca de IP de origen, límite de velocidad y reglas de dominio. Cuántos puede servir un dispositivo a la vez es una prestación del plan (10 en Standard, 20 en Pro): crea uno por cliente o herramienta y revoca cualquiera sin tocar el resto. Crear uno por encima del tope de tu plan devuelve 409 proxy_limit_reached.

Los proxies de un dispositivo comparten su IP
Cada proxy de un dispositivo sale por la misma IP del operador y rota conjuntamente: crear un segundo proxy te da una segunda credencial y política, no una segunda IP. Para otra IP, empareja otro teléfono.

Crea un proxy: genera un nombre de usuario/contraseña nuevos; la contraseña se devuelve en claro una sola vez, aquí. Elige protocol (socks5 o http) y, opcionalmente, pasa traffic_limit_bytes para darle un tope de tráfico estricto desde el inicio:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "protocol": "socks5", "traffic_limit_bytes": 5368709120 }'

# → { "id": "acc_5f734b9270e8", "subscription_id": "sub_760c1fc8ddab",
#     "protocol": "socks5",
#     "host": "173.249.36.102", "host_v6": "2a02:c207:2319:6018::1",
#     "port": 30000,
#     "username": "u04c770", "password": "k7Qp2mXe9wZ4",
#     "endpoint": "socks5h://u04c770:[email protected]:30000",
#     "endpoint_ipv6": "socks5h://u04c770:k7Qp2mXe9wZ4@[2a02:c207:2319:6018::1]:30000",
#     "ip_whitelist": [], "speed_limit_kbps": 0,
#     "domain_mode": "none", "domain_rules": [],
#     "status": "active", "traffic_limit_bytes": 5368709120, "bytes_used": 0,
#     "over_limit": false, "created_at": "…" }
Cada puerto de proxy es dual-stack (IPv4 + IPv6)
Conéctate por cualquiera de las dos familias: endpoint es la URI IPv4, endpoint_ipv6 el mismo puerto sobre IPv6 (el literal v6 va entre corchetes, según la sintaxis de URL). La lista blanca de IP de origen acepta direcciones y CIDR IPv4 e IPv6, y los destinos también pueden ser IPv6: un CONNECT de SOCKS5 a un literal IPv6 o a un dominio solo con AAAA sale por la IPv6 del operador del teléfono cuando la SIM tiene una.

Edita la política de un proxy: modo de autenticación, lista blanca de IP, límite de velocidad y reglas de dominio, aplicados en vivo al gateway (protocol es fijo: elimínalo y recréalo en su lugar):

curl -X PATCH \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "speed_limit_kbps": 2000,
        "domain_mode": "whitelist", "domain_rules": ["api.example.com"] }'

Lista los proxies: en un dispositivo, o todos los proxies de toda la cuenta:

# One device
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies \
     -H "Authorization: Bearer mpx_live_…"

# Account-wide
curl https://mobileproxy.app/api/v1/proxies \
     -H "Authorization: Bearer mpx_live_…"
# → { "proxies": [ { …Proxy… }, … ] }

Revoca un proxy: detiene ese listener de inmediato; los demás proxies del dispositivo siguen funcionando:

curl -X DELETE \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID \
  -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "id": "acc_5f734b9270e8" }

Límites de uso y caducidad por proxy

Da a cualquier proxy un límite de uso: ideal cuando revendes acceso y limitas a cada cliente a un cupo de datos. Fíjalo o cámbialo cuando quieras (0 lo borra), al crearlo, mediante PATCH o con el endpoint dedicado de abajo. Cuando bytes_used alcanza el tope, el proxy queda bloqueado: conserva su puerto y sus credenciales pero rechaza cada petición, y over_limit pasa a true. Sube el límite por encima de lo consumido —o bórralo— y el proxy se reanuda de inmediato, mismo endpoint, sin reconfiguración. Al listar proxies también se informa de cada traffic_limit_bytes, del bytes_used en vivo y de over_limit.

curl -X POST \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/limit \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "traffic_limit_bytes": 10737418240 }'   # 10 GB — or 0 to remove
# → { "proxy_id": "acc_5f734b9270e8", "subscription_id": "sub_760c1fc8ddab",
#     "traffic_limit_bytes": 10737418240, "over_limit": false }

Caducidad por tiempo: da a un proxy un instante expires_at (ISO 8601, en el futuro) al crearlo o mediante PATCH; null borra una caducidad pendiente. En ese momento el proxy se retira, de forma permanente, a diferencia del bloqueo reversible por límite de uso. Para renovar a un cliente, crea un proxy nuevo (nuevo puerto y credenciales). Perfecto para vender pases de día o de semana:

# A proxy that stops serving in 7 days
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "protocol": "socks5", "expires_at": "2026-07-13T09:00:00Z" }'

# Extend or clear it later
curl -X PATCH \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "expires_at": "2026-07-20T09:00:00Z" }'   # or null to remove

Configuraciones de VPN (WireGuard y OpenVPN)

Convierte cualquier proxy en una VPN de dispositivo completo. Cada configuración es un archivo de WireGuard (.conf) o de OpenVPN (.ovpn) que tuneliza todo un dispositivo —teléfono, portátil, router— a través de la IP del operador móvil de ese proxy. Un proxy puede tener 1 de cada tipo: una configuración de WireGuard y una de OpenVPN. Las configuraciones requieren un proxy SOCKS5 + usuario/contraseña para que el gateway pueda autenticarse ante él. Crear una configuración requiere el complemento VPN en el pedido del dispositivo (403 vpn_addon_required si no lo tiene): las configuraciones existentes siguen listadas, descargables y revocables.

El archivo se muestra una sola vez
La respuesta a una creación incluye config_text: el archivo completo, que contiene la clave privada / el certificado del cliente. No es rederivable; guárdalo cuando lo crees. Puedes volver a descargar exactamente el mismo archivo en cualquier momento desde el endpoint /file, pero un archivo perdido solo se puede reemplazar revocando y creando una nueva configuración.
# Create a WireGuard config on a proxy
curl -X POST \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "wireguard", "name": "My laptop" }'
# → { "id": "vpn_9f2c1a0b7e", "kind": "wireguard", "client_ip": "10.77.0.2",
#     "config_text": "[Interface]\nPrivateKey = …\n[Peer]\n…", … }

# ...or OpenVPN
curl -X POST \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs \
  -H "Authorization: Bearer mpx_live_…" -H "Content-Type: application/json" \
  -d '{ "kind": "openvpn" }'

# List a proxy's configs (metadata + per-kind usage vs the 1-per-kind cap)
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs \
     -H "Authorization: Bearer mpx_live_…"

# Re-download the file straight to disk
curl -OJ \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs/vpn_9f2c1a0b7e/file \
  -H "Authorization: Bearer mpx_live_…"

# Revoke (drops the WireGuard peer / OpenVPN cert and kills any live session)
curl -X DELETE \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs/vpn_9f2c1a0b7e \
  -H "Authorization: Bearer mpx_live_…"

Usa el archivo como de costumbre: wg-quick up ./mpx-9f2c1a0b.conf para WireGuard, o importa el .ovpn en cualquier cliente de OpenVPN. Todo el tráfico del dispositivo sale entonces por la IP del operador del teléfono, y rotar la IP de ese proxy rota también la salida de la VPN.

Rotación de IP

La rotación pide al operador una IP nueva. Es por dispositivo —cada proxy del dispositivo obtiene la nueva IP—, se encola al teléfono y se aplica en un ciclo de sondeo (~25 s).

Al mejor esfuerzo en redes móviles
Que un re-marcado produzca una dirección nueva lo decide el operador: algunos reasignan la misma IP en re-marcados rápidos. Confírmalo desde exit_ip en el dispositivo o desde /ip-history.

Rotar ahora: encola una rotación puntual:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/change-ip \
     -H "Authorization: Bearer mpx_live_…"

# → { "status": "rotating", "subscription_id": "sub_760c1fc8ddab",
#     "command_id": "cmd_a41b",
#     "note": "IP rotation on mobile networks is best-effort; …" }

Rotación con IP única: pasa unique: true para seguir rotando hasta que la IP de salida sea una no vista en los últimos window_min minutos del historial de IP de esta suscripción (por defecto 60, máx. 1440), reintentando hasta max_attempts veces (por defecto 3, máx. 5). Cada intento cuesta un ciclo de rotación completo (~30–90 s); sondea la variante GET para ver el progreso. Los operadores pueden reemitir legítimamente una IP, así que exhausted es un resultado honesto posible:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/change-ip \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "unique": true, "window_min": 60, "max_attempts": 3 }'
# → { "status": "rotating", "request_id": "rr_18d2c4", "command_id": "cmd_a41b",
#     "unique": { "window_min": 60, "max_attempts": 3 }, … }

# Poll for the outcome (active | succeeded | exhausted | superseded | expired)
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/change-ip \
     -H "Authorization: Bearer mpx_live_…"
# → { "request_id": "rr_18d2c4", "status": "succeeded",
#     "attempts_used": 2, "attempts_max": 3, "window_min": 60,
#     "started_ip": "77.136.66.63", "result_ip": "77.136.67.101", … }

Enlaces de rotación: una URL con token que rota la IP de este dispositivo al solicitarla, sin cabecera de autenticación (el secreto es el token). Pégalo en cualquier herramienta que admita una «URL de rotación». Lístalos, créalos y revócalos:

# List rotation links
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation-links \
     -H "Authorization: Bearer mpx_live_…"
# → { "rotation_links": [ { "token": "rk_9f2c81d4e7",
#       "url": "https://mobileproxy.app/rotate/rk_9f2c81d4e7", "created_at": "…" } ] }

# Create one
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation-links \
     -H "Authorization: Bearer mpx_live_…"
# → { "token": "rk_9f2c81d4e7", "url": "https://mobileproxy.app/rotate/rk_9f2c81d4e7" }

# Revoke one
curl -X DELETE https://mobileproxy.app/api/v1/rotation-links/ROTATION_TOKEN \
     -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "token": "rk_9f2c81d4e7" }

Rotación programada (temporizada): fija un intervalo de rotación automática en minutos (0 la desactiva; máx. 1440). Persiste como rotation_interval_min en el dispositivo y envía un comando set_rotation_interval que el teléfono aplica en su siguiente sondeo, de modo que re-marca a ese ritmo por sí solo:

# Read the current settings
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "interval_minutes": 0,
#     "airplane_seconds": 5, "stale_ip_alert_minutes": 0 }

# Rotate automatically every 15 minutes
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "interval_minutes": 15 }'
# → { "status": "set", "subscription_id": "sub_760c1fc8ddab",
#     "interval_minutes": 15, "airplane_seconds": 5,
#     "stale_ip_alert_minutes": 0, "command_id": "cmd_a41b" }

Tiempo de espera del modo avión: cuánto mantiene el teléfono activado el modo avión durante cada cambio de IP (airplane_seconds, 3–60, por defecto 5). Algunos operadores solo liberan la concesión anterior tras una espera más larga; súbelo si las rotaciones siguen devolviendo la misma IP. Se aplica por igual a las rotaciones programadas, del panel y de la API:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "airplane_seconds": 20 }'
# → { "status": "set", "subscription_id": "sub_760c1fc8ddab",
#     "interval_minutes": 15, "airplane_seconds": 20,
#     "stale_ip_alert_minutes": 0, "command_id": "cmd_b52c" }

DNS personalizado: los resolutores que el teléfono usa para las resoluciones de dominio proxificadas (hasta 3 literales de IP; el teléfono aplica el primero y re-marca su túnel). Una lista vacía restaura el DNS por defecto del operador:

# Read
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/dns \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "dns_servers": [] }

# Set (and later send [] to go back to carrier DNS)
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/dns \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "dns_servers": ["1.1.1.1", "8.8.8.8"] }'
# → { "status": "set", "subscription_id": "sub_760c1fc8ddab",
#     "dns_servers": ["1.1.1.1", "8.8.8.8"], "command_id": "cmd_c63d" }

Monitorización

Historial de IP de salida: las IP de salida recientes reportadas por el teléfono, deduplicadas (una fila nueva solo cuando la IP cambia de verdad). La forma fiable de verificar que una rotación cuajó:

curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/ip-history \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "ip_history": [
#     { "ip": "77.136.66.63", "carrier": "SFR", "ts": "…" }, … ] }

Parámetros de consulta opcionales: from/to (ISO 8601) acotan la ventana, limit limita las entradas (por defecto 50, máx. 500), y group=day devuelve recuentos de cambios por día en su lugar: pasa tz como tu desfase UTC en minutos para que los días se agrupen en tu zona horaria. Esto es lo que alimenta el calendario de historial de IP del panel:

# Entries for one day
curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/ip-history?from=2026-07-04T22:00:00Z&to=2026-07-05T22:00:00Z&limit=500" \
     -H "Authorization: Bearer mpx_live_…"

# Per-day counts for a month (tz = minutes east of UTC, e.g. 120 for CEST)
curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/ip-history?group=day&tz=120&from=2026-06-30T22:00:00Z&to=2026-07-31T22:00:00Z" \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "days": [
#     { "day": "2026-07-03", "changes": 9 }, { "day": "2026-07-05", "changes": 2 } ] }

Alertas de IP: el servidor vigila tu flota (~cada 60 s) y abre una alerta cuando algo requiere atención: stale_ip cuando un dispositivo está en línea pero su IP de salida no ha cambiado durante más tiempo que el umbral de la suscripción (fija stale_ip_alert_minutes en /rotation; 0 = desactivado, 2–10080), y duplicate_ip cuando dos de tus dispositivos reportan la misma IP de salida (el NAT del operador puede dar una dirección a dos SIM: rota una para separarlas). Las alertas se resuelven automáticamente cuando la condición desaparece; también aparecen en la campana de alertas del panel:

# Turn on stale-IP alerts: warn after 60 min without an IP change
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "stale_ip_alert_minutes": 60 }'

# Poll open alerts (feed this to your own monitoring)
curl https://mobileproxy.app/api/v1/alerts \
     -H "Authorization: Bearer mpx_live_…"
# → { "alerts": [
#     { "id": "42", "sub_id": "sub_760c1fc8ddab", "sub_name": "Galaxy S8",
#       "kind": "stale_ip",
#       "message": "IP unchanged for 75 min (alert threshold 60 min) — still 77.136.66.44",
#       "detail": { "ip": "77.136.66.44", "age_min": 75, "threshold_min": 60 },
#       "created_at": "…", "resolved_at": null, "seen_at": null },
#     { "id": "41", "sub_id": "sub_9d8e7f6a5b4c", "sub_name": "Galaxy A32",
#       "kind": "duplicate_ip",
#       "message": "Exit IP 77.136.67.33 is also used by “Galaxy S8” — rotate one device to separate them",
#       "detail": { "ip": "77.136.67.33",
#                   "shared_with": [ { "sub_id": "sub_760c1fc8ddab", "name": "Galaxy S8" } ] },
#       "created_at": "…", "resolved_at": null, "seen_at": null } ],
#     "unseen": 2 }

# Include resolved history; filter to one subscription
curl "https://mobileproxy.app/api/v1/alerts?status=all&subscription=SUBSCRIPTION_ID" \
     -H "Authorization: Bearer mpx_live_…"

# Reset the dashboard's unseen badge (never resolves anything)
curl -X POST https://mobileproxy.app/api/v1/alerts/seen \
     -H "Authorization: Bearer mpx_live_…"
# → { "status": "ok", "marked": 2 }

Tráfico de un dispositivo: bytes contados en el gateway, desglosados por proxy. Práctico para facturar a los clientes a los que revendes:

curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/traffic \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab",
#     "bytes_sent": 10485760, "bytes_recv": 262144000, "bytes_total": 272629760,
#     "per_proxy": [ { "proxy_id": "acc_5f734b9270e8",
#                      "bytes_sent": 10485760, "bytes_recv": 262144000 } ] }

Desglose de tráfico diario: bytes enviados/recibidos por día, a partir de muestras con resolución de minuto guardadas en la capa web, de modo que la serie sobrevive a los cambios de dispositivo y a la retirada de proxies. data_since marca la muestra más antigua: los días anteriores no tienen datos, lo cual no es lo mismo que tráfico cero. Pasa tz (tu desfase UTC en minutos) para que los días se agrupen en tu zona horaria; ventanas de hasta 92 días:

curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/traffic/by-day?tz=120" \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "tz": 120, "data_since": "…",
#     "days": [ { "day": "2026-07-06", "bytes_sent": 10485760,
#                 "bytes_recv": 262144000, "bytes_total": 272629760 } ],
#     "total": { "bytes_sent": 10485760, "bytes_recv": 262144000,
#                "bytes_total": 272629760 } }

Tiempo de actividad diario: segundos de actividad/inactividad por día calculados a partir del registro de heartbeat del dispositivo (unificado a través de los cambios de dispositivo). Mide la vitalidad del heartbeat del dispositivo (ritmo ~25 s, umbral de hueco ~90 s), no la usabilidad del túnel de extremo a extremo. current es el estado en este momento; uptime_pct cubre la parte observada de cada día:

curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/uptime?tz=120" \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "tz": 120, "current": "up",
#     "data_since": "…",
#     "days": [ { "day": "2026-07-06", "up_seconds": 31547,
#                 "down_seconds": 253, "uptime_pct": 99.2 } ] }

Uso de toda la cuenta: un resumen agregado de todos los dispositivos:

curl https://mobileproxy.app/api/v1/usage/summary \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscriptions": 3, "proxies": 5,
#     "bytes_sent": 31457280, "bytes_recv": 786432000, "bytes_total": 817889280 }

SMS / OTP

SMS recibidos: mensajes entrantes en la SIM de este teléfono, los más recientes primero. Útil para leer códigos de verificación de un solo uso (OTP) en teléfonos que posees. Depende del permiso opcional de recepción de SMS de la app; si se rechazó en el dispositivo, la lista queda vacía:

curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/sms \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "messages": [
#     { "id": "1042", "sender": "+15550101",
#       "body": "Your verification code is 314159",
#       "received_at": "2026-07-05T14:12:00.000Z" }, … ] }

Servidores

Ubicaciones del gateway: las ubicaciones desde las que se sirven tus proxies:

curl https://mobileproxy.app/api/v1/servers/locations \
     -H "Authorization: Bearer mpx_live_…"

# → { "locations": [ { "id": "eu-de-1", "host": "173.249.36.102",
#       "region": "EU · Germany (Frankfurt)", "country": "DE",
#       "protocols": ["socks5"], "pool": "mobile" } ] }

Tokens de API

Lista, crea y revoca tokens de API. El secreto de un token recién creado se muestra una sola vez: guárdalo de inmediato; nunca se puede recuperar. La revocación surte efecto de inmediato:

# List (metadata only — never the secret)
curl https://mobileproxy.app/api/v1/tokens \
     -H "Authorization: Bearer mpx_live_…"
# → { "tokens": [ { "id": "tk_51ad", "name": "storefront",
#       "prefix": "mpx_live_9f2c", "created_at": "…", "last_used_at": "…" } ] }

# Create (secret shown once)
curl -X POST https://mobileproxy.app/api/v1/tokens \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "name": "storefront" }'
# → { "id": "tk_51ad", "name": "storefront",
#     "token": "mpx_live_9f2c81d4e7…", "prefix": "mpx_live_9f2c",
#     "scope_subscription_id": null, "readonly": false,
#     "note": "Store this token now — it will not be shown again." }

# Revoke
curl -X DELETE https://mobileproxy.app/api/v1/tokens/TOKEN_ID \
     -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "id": "tk_51ad" }

Claves con alcance y de solo lectura

Delega el acceso sin compartir tu cuenta. Pasa subscription_id para acotar un token a una única suscripción, y readonly: true para limitarlo a peticiones GET. Un token con alcance solo puede llegar a los endpoints de esa suscripción (más /me); un token de solo lectura se rechaza en cualquier escritura. Ambos son restricciones superpuestas a tu cuenta: una clave con alcance nunca puede llegar a los datos de otra cuenta.

# A read-only key for ONE subscription — safe to hand a teammate or a monitor
curl -X POST https://mobileproxy.app/api/v1/tokens \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "name": "customer-42",
           "subscription_id": "sub_760c1fc8ddab",
           "readonly": true }'
# → { …, "scope_subscription_id": "sub_760c1fc8ddab", "readonly": true }

# With that key: a GET on its own subscription works…
curl https://mobileproxy.app/api/v1/subscriptions/sub_760c1fc8ddab/traffic \
     -H "Authorization: Bearer mpx_live_scoped…"     # 200

# …but another subscription, the account-wide list, or any write is refused.
curl -X POST https://mobileproxy.app/api/v1/subscriptions/sub_760c1fc8ddab/change-ip \
     -H "Authorization: Bearer mpx_live_scoped…"     # 401 (read-only)
Consejo
Esta referencia se mantiene sincronizada con la API. Para un navegador donde puedas hacer clic —con tu propio token y respuestas en vivo— abre la consola interactiva, o lee el documento OpenAPI en bruto.