Menú de la documentación

API de tokens

Todos los tokens de proxy: listado, lectura, uso de uno o de muchos tokens y, para los proxies de pago por GB, crear, cambiar, volver a emitir las credenciales y eliminar. Los tokens ilimitados reubicables también tienen ubicación, rotación y una IP nueva a solicitud.

Listar y leer#

GET /api/v1/tokens
Authorization: Bearer lit_...
Parámetro Tipo Reglas
limit integer Entero 1-100; predeterminado 50.
cursor string El page.nextCursor de la página anterior, enviado de vuelta sin cambios.
type string unlimited o ppg.
status string active, expired o disabled.
packageId integer ID numérico público de un paquete propio. Un valor desconocido o ajeno devuelve una lista vacía. Un valor con formato incorrecto devuelve INVALID_PACKAGE_ID.

Los resultados se ordenan del más reciente al más antiguo. Sigue solicitando el page.nextCursor devuelto hasta que sea null.

GET /api/v1/tokens/{tokenId}
Authorization: Bearer lit_...

Devuelve un token con la misma estructura que un elemento de la lista de GET /tokens, incluidos su username y password. Un tokenId desconocido, ajeno o que no se puede interpretar da 404 TOKEN_NOT_FOUND; la respuesta nunca revela el token de otro usuario.

Ejemplos#

Un token ilimitado de centro de datos, en un paquete con IP permitidas y una ubicación que se puede cambiar:

{
  "id": 12345,
  "type": "unlimited",
  "status": "active",
  "disabledReason": null,
  "label": "Production crawler",
  "externalRef": null,
  "createdAt": "2026-08-01T10:15:00.000Z",
  "expiresAt": "2026-12-01T00:00:00.000Z",
  "allowanceBytes": null,
  "allowanceReservedBytes": null,
  "ingress": {
    "hub": "us-11",
    "protocol": "http",
    "mode": "assigned",
    "host": "hub-us-11-1.litport.net",
    "port": 31337,
    "status": "available"
  },
  "packageId": 45,
  "ipAuth": { "host": "hub-us-11-1.litport.net", "port": 31338 },
  "location": { "country": "us", "region": "new-york", "city": "new-york-city" },
  "rotation": { "intervalSec": 600, "options": [600, 1800, 3600], "changeable": true },
  "username": "proxy-username",
  "password": "proxy-password"
}

Un token de pago por GB, fijado a un pool, con una referencia, una caducidad y un tope de tráfico:

{
  "id": 12399,
  "type": "ppg",
  "status": "active",
  "disabledReason": null,
  "label": "Residential crawler",
  "externalRef": "customer-1042",
  "createdAt": "2026-08-01T10:15:00.000Z",
  "expiresAt": "2026-12-31T23:59:59.999Z",
  "allowanceBytes": 5000000000,
  "allowanceReservedBytes": 1200000000,
  "ingress": {
    "hub": "example-hub",
    "protocol": "http",
    "mode": "request-selected",
    "supportedProtocols": ["http", "https", "socks5"]
  },
  "poolSelection": {
    "mode": "fixed",
    "pool": { "authKey": "residential-main", "name": "Residential Main" }
  },
  "packageId": null,
  "ipAuth": null,
  "username": "proxy-username",
  "password": "proxy-password"
}

Los identificadores y hubs de ejemplo de esta documentación son ilustrativos.

Semántica de los campos#

type es ppg o unlimited. status es active, expired o disabled. Nunca es hub-unavailable; ese valor pertenece a ingress.status, más abajo.

disabledReason indica por qué un token no está atendiendo tráfico. Es null mientras status es active.

status disabledReason Significado
disabled owner Desactivado por ti (enabled: false) o, en el token de un paquete, por su paquete.
disabled ban Desactivado porque la cuenta está bloqueada.
expired expired Pasó expiresAt.
disabled allowance Activado, pero ya se usó todo su tope de tráfico. Sube o quita el tope para que vuelva a funcionar.
disabled balance Activado, pero el saldo de la cuenta no alcanza para pagarlo. Recarga el saldo para volver a usarlo.

El filtro status de GET /tokens selecciona solo según el interruptor de encendido y apagado propio del token y su caducidad. No encuentra un token que esté disabled por allowance o balance, así que lee disabledReason en los resultados.

externalRef es tu propia referencia para un proxy de pago por GB, o null. expiresAt es el momento en que el token se detiene, o null. allowanceBytes es el tope de tráfico en bytes, o null si no hay tope, y allowanceReservedBytes es cuánto de ese tope se ha reservado hasta ahora, o null si no hay tope.

Para un token PPG, ingress.mode es request-selected: no hay un único host ni puerto, porque el hub, el protocolo y el pool se eligen por solicitud o exportación. ingress.hub e ingress.protocol son preferencias del panel y de la exportación, y ingress.supportedProtocols enumera las opciones. Toma el host de los hubs de un pool y el puerto de su httpPort/socks5Port en Pago por GB.

Para un token ilimitado, ingress.mode es assigned: el token se resuelve en exactamente un endpoint, que siempre se informa como ingress.host e ingress.port. ingress.status es available o hub-unavailable. hub-unavailable significa que el token nombra un hub que ya no está en servicio: ingress.host e ingress.port son entonces null, y las credenciales no se pueden usar hasta que soporte traslade el token a un hub actual.

packageId es el ID numérico público del paquete cuando el token pertenece a un paquete propio; si no, null; consulta el paquete con Paquetes. ipAuth es {host, port}, el endpoint sin contraseña del token, o null cuando el token no tiene uno en este momento. Solo acepta conexiones desde las IP permitidas del paquete.

location solo está presente en un token cuya ubicación se puede cambiar; Ubicación indica qué tokens cumplen los requisitos. Su estructura depende del tipo: un token de centro de datos o ISP informa {country, region, city}; un token móvil informa {country, city, carrier}.

rotation es {intervalSec, options, changeable}, presente en todo token que rota con un temporizador. Consulta Rotación.

rotateUrl es el enlace para cambiar la IP de un Dispositivo privado o de un token rotativo de centro de datos/ISP, presente solo cuando el token tiene uno. Mantenlo tan privado como la contraseña que lo acompaña. Consulta Enlace para cambiar la IP más abajo, y Cambiar la IP para ver las formas de obtener una IP nueva.

username y password son las credenciales de proxy del token. Úsalas con el endpoint que aparece en ingress o en el panel.

Si la cuenta activó Usar direcciones neutras, los nombres de host que devuelve esta API (ingress.host, ipAuth.host), el authKey del pool y el enlace rotateUrl llevan los nombres neutros. Un nombre de pool que envíes se acepta en cualquiera de las dos formas. Para un proxy HTTPS usa ingress.httpsHost (un token ilimitado con el protocolo http): el certificado se emite para ese nombre. Es el nombre propio del hub y es igual a ingress.host, salvo que la cuenta use direcciones neutras. Para un token de pago por GB toma httpsHostname de los hubs del pool.

Crear y administrar proxies#

Los proxies de pago por GB se pueden crear, cambiar y eliminar mediante la API, y las credenciales de cualquier proxy que tengas se pueden volver a emitir. El formulario de proxy de pago por GB del panel sigue las mismas reglas. Toda llamada de aquí necesita una clave de API Bearer, y las escrituras cuentan para el límite de 120 solicitudes cada 60 segundos de la clave.

Los proxies de un paquete pertenecen a su paquete, que los crea, los termina y los activa y desactiva. En ellos puedes cambiar la etiqueta y volver a emitir las credenciales, nada más.

Revender está permitido en todas las cuentas. Respondes por cómo tus clientes usan sus proxies: el abuso de uno de ellos puede bloquear toda tu cuenta.

Crear un proxy#

POST /api/v1/tokens
Authorization: Bearer lit_...
Content-Type: application/json

Envía un objeto JSON, {} como mínimo. Una solicitud sin cuerpo no crea nada.

Campo Reglas
pool Opcional. El authKey de un pool de Pago por GB. Omítelo, o envía null, para un proxy que elige su pool en cada solicitud. Un pool que no puedes elegir da 400 INVALID_POOL.
label Opcional. Hasta 255 caracteres.
externalRef Opcional, y conviene enviarlo siempre. De 1 a 128 caracteres imprimibles, único entre tus proxies existentes.
expiresAt Opcional. Una fecha y hora ISO 8601 con zona horaria, como 2026-12-31T10:00:00Z, o una fecha, como 2026-12-31, que significa el final de ese día en UTC. Debe ser posterior a ahora. El proxy se detiene en ese momento.
allowanceBytes Opcional. El tope de tráfico en bytes, un entero de al menos 1.
curl -X POST 'https://litport.net/api/v1/tokens' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"pool": "residential-main", "label": "Residential crawler", "externalRef": "customer-1042", "expiresAt": "2026-12-31", "allowanceBytes": 5000000000}'

La respuesta es 201 y el proxy con la estructura que se muestra en Ejemplos, con su username y su password. Arma el usuario del proxy a partir de ellos como se describe en Parámetros de proxies de pago por GB.

Envía siempre un externalRef. Es tu propia referencia, como un ID de cliente o un número de pedido. Una creación que repite un externalRef que ya usas responde 200 con ese proxy y no cambia nada, aunque el resto del cuerpo sea distinto. Así, si una creación agota el tiempo de espera o pierdes la respuesta, envíala de nuevo con el mismo externalRef y obtendrás el proxy que ya existe. Sin un externalRef, una repetición puede crear un segundo proxy. Un proxy eliminado devuelve su externalRef, así que puedes volver a usarlo.

Crear necesita un saldo positivo (INSUFFICIENT_BALANCE) y una cuenta que no esté bloqueada (ACCOUNT_BANNED). Una cuenta puede tener un número limitado de proxies de pago por GB (TOKEN_LIMIT_REACHED); ponte en contacto con soporte para aumentarlo.

Una cuenta puede crear 60 proxies nuevos por minuto, contando juntas todas sus claves de API y el panel. Una repetición de un externalRef que ya usas no cuenta. Pasado el límite, una creación responde 429 RATE_LIMITED con Retry-After, y no se crea nada: envía la misma solicitud de nuevo después de la espera.

Cambiar un proxy#

PATCH /api/v1/tokens/{tokenId}
Authorization: Bearer lit_...
Content-Type: application/json

Envía solo los campos que quieras cambiar, y al menos uno. Un campo que omites queda como está. null borra label, pool, expiresAt y allowanceBytes.

Campo Reglas
label Hasta 255 caracteres, o null.
enabled false desactiva el proxy, true lo activa. Activarlo necesita un saldo positivo y una cuenta que no esté bloqueada.
pool El authKey de un pool, o null para un proxy que elige su pool en cada solicitud. Un proxy que inicia sesión por IP permitida conserva su pool: null da 409 POOL_REQUIRED_FOR_IP_AUTH.
expiresAt Una fecha y hora, o una fecha, posterior a ahora, como al crear, o null para que no caduque.
allowanceBytes El tope de tráfico en bytes, un entero de al menos 1, o null para quitarlo.

La respuesta es 200 y el proxy tal como queda ahora. Un cuerpo que no cambia nada no escribe nada. Un pool nuevo se aplica a las conexiones nuevas; las conexiones abiertas conservan el pool con el que empezaron y se cobran a su precio.

Desactivar, cambiar la etiqueta y cambiar la caducidad o el tope funcionan siempre, incluso con el saldo vacío, así que puedes cortar el servicio a un cliente en cualquier momento. Lo mismo ocurre con volver a emitir las credenciales y con eliminar. En el proxy de un paquete, label es el único campo; cualquier otro da 400 FIELD_NOT_ALLOWED.

Volver a emitir las credenciales#

POST /api/v1/tokens/{tokenId}/credentials
Authorization: Bearer lit_...
Content-Type: application/json

{"requestId": "reissue-2026-11-04-a"}

Emite un usuario, una contraseña y una clave de cambio de IP nuevos para cualquier proxy que tengas, de pago por GB o de paquete. La respuesta es 200 y el proxy con la estructura que se muestra en Ejemplos, con el username y el password nuevos, y un rotateUrl nuevo cuando el proxy tiene uno. El cuerpo es opcional.

  • La contraseña anterior deja de funcionar y sus conexiones abiertas se cierran.
  • El enlace anterior para cambiar la IP deja de funcionar.
  • Las IP permitidas de un paquete siguen funcionando y sus conexiones siguen abiertas. Las IP permitidas pertenecen a todo el paquete, no a un proxy, así que volver a emitir las credenciales de un proxy no puede dejar sin acceso a un cliente que se conecta desde una IP permitida. Comparte un paquete entre clientes solo con contraseñas.

requestId tiene de 1 a 64 caracteres: letras, dígitos, guion bajo o guion. Usa un requestId nuevo para cada reemisión que quieras hacer. Envía el mismo solo para reintentar una llamada que no tuvo respuesta: una repetición devuelve las credenciales que emitió la primera llamada y no emite nada nuevo, ya haya terminado la primera llamada o siga en curso. Sin un requestId, cada llamada emite un par nuevo, así que no la repitas a ciegas.

Eliminar un proxy#

DELETE /api/v1/tokens/{tokenId}
Authorization: Bearer lit_...

Elimina un proxy de pago por GB. La respuesta es 204 sin cuerpo. El proxy deja de funcionar y sus conexiones abiertas se cierran. Su historial se conserva: el uso de muchos tokens lo sigue incluyendo, marcado como deleted, y GET /tokens/{tokenId}/usage sigue respondiendo por él. GET /tokens y GET /tokens/{tokenId} ya no lo devuelven. Eliminar un proxy que ya está eliminado vuelve a dar 204.

El proxy de un paquete no se puede eliminar: 409 NOT_SUPPORTED. Termina con su paquete.

Tope de tráfico#

Un proxy de pago por GB puede tener un tope de tráfico, allowanceBytes: el máximo de tráfico que puede usar, en bytes (1 GB son 1,000,000,000 bytes). Úsalo para dar a cada cliente, miembro del equipo o herramienta una cantidad fija. El tope es opcional. En el panel es el campo Límite de tráfico (GB) del proxy.

  • Qué cuenta. Todo el tráfico entre el cliente y el hub, en ambas direcciones y con la sobrecarga del protocolo incluida. Por eso el tope nunca es menor que el tráfico cobrado en el uso: un proxy nunca recibe más tráfico cobrado que su tope.
  • Dónde se detiene. Un proxy puede detenerse un poco antes de su tope, pero nunca lo supera. Litport reserva tráfico para un proxy antes de que se use, y lo que no se usa no se devuelve.
  • allowanceReservedBytes. Cuánto del tope se ha reservado hasta ahora. No es el mismo número que el uso cobrado: puede ir por delante del tráfico entregado y nunca se descuenta de lo que se te cobra. Lee el tráfico cobrado en el uso.
  • La facturación no cambia. El tope solo rechaza tráfico.
  • Cuando se agota. status es disabled, disabledReason es allowance y las conexiones nuevas reciben el error de proxy 24 (HTTP 403). Sube o quita el tope para volver a usar el proxy.
  • Cambiar un tope. Agregar, subir, bajar o quitar un tope cierra una vez las conexiones abiertas del proxy; los clientes se reconectan con el tope nuevo. Un tope que se baja por debajo de lo que ya se reservó detiene el proxy en cuanto se usa el tráfico ya reservado. No se devuelve nada.

Errores de escritura de proxies#

Estado Código Significado
400 INVALID_REQUEST_BODY El cuerpo no es un objeto JSON, tiene un campo que la llamada no admite o (PATCH) no tiene ningún campo.
400 FIELD_NOT_ALLOWED PATCH envió a un proxy de un paquete un campo distinto de label.
400 INVALID_LABEL, INVALID_EXTERNAL_REF, INVALID_REQUEST_ID, INVALID_ENABLED, INVALID_EXPIRY, INVALID_ALLOWANCE El campo indicado está fuera de rango o es del tipo incorrecto.
400 INVALID_POOL pool no es un pool que puedas elegir.
402 INSUFFICIENT_BALANCE Crear o activar necesita un saldo positivo.
403 ACCOUNT_BANNED No se permite crear ni activar mientras la cuenta esté bloqueada.
404 TOKEN_NOT_FOUND tokenId desconocido, ajeno o con formato incorrecto.
409 NOT_SUPPORTED DELETE en un proxy de un paquete.
409 TOKEN_LIMIT_REACHED La cuenta ya tiene el máximo de proxies de pago por GB que puede tener.
409 ALLOWANCE_CONFLICT No se pudo guardar el tope. Envía de nuevo la misma solicitud.
409 POOL_REQUIRED_FOR_IP_AUTH Un proxy que inicia sesión por IP permitida no puede quedarse sin pool.
409 TOKEN_NOT_EDITABLE El proxy ya no se puede editar, por ejemplo porque se eliminó mientras se ejecutaba la escritura. No cambió nada.
409 CONCURRENT_CHANGE Otra escritura en este proxy llegó en el mismo instante. Envía de nuevo la misma solicitud.
429 RATE_LIMITED Al crear: más proxies nuevos en el último minuto que el límite de la cuenta (o el límite de solicitudes de la clave). No se creó nada. Espera Retry-After y vuelve a enviar la misma solicitud.

Cada código tiene su apartado en Errores de la API.

Uso#

Consulta el tráfico visible para el cliente de un token propio.

GET /api/v1/tokens/{tokenId}/usage
Authorization: Bearer lit_...

Parámetros de consulta#

Parámetro Reglas
from Marca de tiempo ISO-8601 canónica en UTC, inclusiva.
to Marca de tiempo ISO-8601 canónica en UTC, exclusiva; debe ser posterior a from.
groupBy hour, day o month; el valor predeterminado es day.
include domains y/o charges, separados por comas. charges requiere groupBy=hour.

Cuando se omite el rango, la API usa los 30 días UTC completos anteriores al día UTC actual. Los rangos por hora se limitan a 31 días, los rangos por día a 366 días y los rangos por mes a 36 meses.

Ejemplo#

curl --get 'https://litport.net/api/v1/tokens/12345/usage' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  --data-urlencode 'from=2026-08-01T00:00:00Z' \
  --data-urlencode 'to=2026-08-03T00:00:00Z' \
  --data-urlencode 'groupBy=day'
{
  "data": {
    "tokenId": 12345,
    "deleted": false,
    "range": {
      "from": "2026-08-01T00:00:00.000Z",
      "to": "2026-08-03T00:00:00.000Z",
      "groupBy": "day",
      "timezone": "UTC"
    },
    "trafficBasis": "customer_chargeable",
    "summary": {
      "requests": 42,
      "uploadedBytes": "12000",
      "downloadedBytes": "88000",
      "totalBytes": "100000",
      "cache": {
        "hits": 12,
        "misses": 4,
        "bypasses": 2,
        "hitRate": 0.75,
        "freeUploadedBytes": "0",
        "freeDownloadedBytes": "24000",
        "freeTotalBytes": "24000",
        "savedCostUnits": "0.0324"
      }
    },
    "buckets": [
      {
        "start": "2026-08-01T00:00:00.000Z",
        "end": "2026-08-02T00:00:00.000Z",
        "requests": 42,
        "uploadedBytes": "12000",
        "downloadedBytes": "88000",
        "totalBytes": "100000",
        "cache": {
          "hits": 12,
          "misses": 4,
          "bypasses": 2,
          "hitRate": 0.75,
          "freeUploadedBytes": "0",
          "freeDownloadedBytes": "24000",
          "freeTotalBytes": "24000",
          "savedCostUnits": "0.0324"
        }
      }
    ]
  }
}

Semántica del uso#

El intervalo es semiabierto: [from, to). Los buckets se ordenan por hora de inicio y son dispersos; un bucket ausente significa que no hay una fila de agregado almacenada, no un error de la API.

Para los tokens PPG, trafficBasis es customer_chargeable, por lo que los totales de tráfico coinciden con el tráfico que se muestra al cliente. Para los tokens de precio fijo/ilimitados, es observed; esos totales de tráfico existentes siguen siendo la base de transferencia observada. Los totales grandes de bytes son cadenas decimales para que los clientes conserven los valores exactos. requests es un entero JSON.

Beneficio de la caché#

Cada bucket y el resumen contienen cache. hits, misses y bypasses son enteros JSON; hitRate es hits / (hits + misses) y vale 0 cuando no hubo aciertos ni fallos. freeUploadedBytes, freeDownloadedBytes y freeTotalBytes son cadenas decimales en base 10 no negativas, y freeTotalBytes es igual a la suma de los dos valores por dirección. Los períodos anteriores sin telemetría de caché informan ceros en estos campos.

Solo para los tokens PPG, cache.savedCostUnits es una cadena decimal en base 10 no negativa con el cobro auditado que se evitó, al precio vigente cuando ocurrió el tráfico. El campo se omite deliberadamente, no se establece en 0 ni en null, para los tokens ilimitados, porque no se evitó ningún cobro por GB al cliente.

El token debe pertenecer al usuario autenticado. Un token desconocido o ajeno devuelve la misma respuesta 404 TOKEN_NOT_FOUND. Un token eliminado igualmente responde, con deleted: true, de modo que la última factura de un cliente se pueda leer cuando el proxy ya no existe.

Desglose de cobros#

Para un token PPG, solicita include=charges&groupBy=hour para agregar el cobro persistido a cada bucket por hora. La expansión se rechaza para los tokens ilimitados. Un cobro versionado contiene la clave pública y el nombre del pool, los bytes de subida y descarga brutos y cobrados, los hubs y protocolos que intervinieron, las tarifas base y efectivas y el descuento registrados en una instantánea, y el importe exacto deducido. Una fila sin instantáneas se etiqueta como Legacy PPG usage; la API no deduce su pool ni su tarifa a partir de la configuración actual del token.

Los componentes del cobro son el registro de facturación. Tanto la subida como la descarga se cobran. Un cobro reserved puede crecer mientras llega tráfico tardío de la hora; un cobro finished es definitivo.

Desglose por dominio#

Solicita include=domains para agregar domainBreakdown a data:

{
  "domainBreakdown": {
    "limit": 150,
    "totalDestinationCount": 151,
    "displayedCount": 150,
    "truncated": true,
    "range": {
      "from": "2026-08-01T00:00:00.000Z",
      "to": "2026-08-03T00:00:00.000Z",
      "timezone": "UTC",
      "periodClamped": false,
      "endClamped": false
    },
    "items": [{
      "protocol": "tcp",
      "destination": "example.com",
      "port": 443,
      "requests": 42,
      "uploadedBytes": "12000",
      "downloadedBytes": "88000",
      "totalBytes": "100000",
      "lastSeenAt": "2026-08-01T12:00:00.000Z",
      "firstSeenAt": "2026-08-01T00:00:00.000Z"
    }],
    "other": {
      "protocol": null,
      "destination": "Other",
      "port": null,
      "requests": 1,
      "uploadedBytes": "1",
      "downloadedBytes": "2",
      "totalBytes": "3",
      "lastSeenAt": null,
      "firstSeenAt": null
    }
  }
}

La respuesta incluye como máximo los 150 destinos con mayor tráfico total. Todos los destinos restantes y el desbordamiento de telemetría se combinan en other; truncated indica cuándo ocurrió esa agrupación. Los requests de TCP son recuentos de solicitudes exitosas y los requests de UDP son datagramas entrantes. Los datos de dominio se almacenan en buckets UTC de horas completas y se limitan a los 31 días más recientes del intervalo solicitado. El range UTC devuelto es el intervalo efectivo de buckets: un inicio parcial pasado se redondea hacia abajo a su hora y un final parcial pasado se redondea hacia arriba a la hora siguiente. Un final limitado a la hora actual se queda en esa hora exacta, de modo que la respuesta no afirma cobertura más allá de la hora actual. El rango también informa periodClamped o endClamped cuando se ajustó.

Uso de muchos tokens#

Lee el uso de muchos proxies en una sola llamada, día por día. Los proxies eliminados se incluyen, para que puedas liquidar la última factura de un cliente que se fue.

GET /api/v1/usage
Authorization: Bearer lit_...

Parámetros de la lista de uso#

Parámetro Reglas
from Marca de tiempo ISO-8601 canónica en UTC, inclusiva.
to Marca de tiempo ISO-8601 canónica en UTC, exclusiva; debe ser posterior a from.
tokenIds IDs de proxy, separados por comas o como parámetro repetido, como máximo 100. Omítelo para incluir todos los proxies. Un ID que no es tuyo se omite. Una lista mal formada da 400 INVALID_TOKEN_IDS.
limit Entero de 1 a 100; el valor predeterminado es 50. El número de proxies de una página.
cursor El page.nextCursor de la página anterior, reenviado sin cambios.

Cuando se omite el rango, la API usa los 30 días UTC completos anteriores al día UTC actual. Un rango se limita a 92 días (400 INVALID_TIME_RANGE si se supera); lee un periodo más largo en varias llamadas. Esta llamada se limita a 10 solicitudes cada 60 segundos por clave de API (429 RATE_LIMITED), y los encabezados RateLimit-* y Retry-After informan de ese límite.

Ejemplo de la lista de uso#

curl --get 'https://litport.net/api/v1/usage' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  --data-urlencode 'from=2026-10-01T00:00:00Z' \
  --data-urlencode 'to=2026-10-03T00:00:00Z' \
  --data-urlencode 'tokenIds=12399,12400'
{
  "data": {
    "range": {
      "from": "2026-10-01T00:00:00.000Z",
      "to": "2026-10-03T00:00:00.000Z",
      "groupBy": "day",
      "timezone": "UTC"
    },
    "tokens": [
      {
        "tokenId": 12399,
        "type": "ppg",
        "deleted": false,
        "label": "Residential crawler",
        "externalRef": "customer-1042",
        "trafficBasis": "customer_chargeable",
        "summary": {
          "requests": 42,
          "uploadedBytes": "12000",
          "downloadedBytes": "88000",
          "totalBytes": "100000",
          "costUnits": "0.00045"
        },
        "buckets": [
          {
            "start": "2026-10-01T00:00:00.000Z",
            "end": "2026-10-02T00:00:00.000Z",
            "requests": 42,
            "uploadedBytes": "12000",
            "downloadedBytes": "88000",
            "totalBytes": "100000",
            "costUnits": "0.00045"
          }
        ]
      },
      {
        "tokenId": 12400,
        "type": "ppg",
        "deleted": true,
        "label": null,
        "externalRef": "customer-0977",
        "trafficBasis": "customer_chargeable",
        "summary": {
          "requests": 0,
          "uploadedBytes": "0",
          "downloadedBytes": "0",
          "totalBytes": "0",
          "costUnits": "0"
        },
        "buckets": []
      }
    ]
  },
  "page": { "nextCursor": null }
}

Semántica de la lista de uso#

Una página contiene hasta limit proxies, del más reciente al más antiguo, cada uno con un summary del rango y un bucket por cada día UTC que tiene tráfico. El intervalo es semiabierto, [from, to), y los buckets son dispersos, igual que para un solo token. Sigue solicitando page.nextCursor hasta que sea null; una página puede contener menos de limit proxies, porque los proxies eliminados sin uso se omiten.

Las credenciales nunca aparecen aquí. trafficBasis, las cadenas de bytes y requests significan lo mismo que para un solo token. Esta lista no incluye beneficio de caché, desglose por dominio ni cobro por hora; léelos con GET /tokens/{tokenId}/usage.

costUnits es el importe cobrado, en unidades de saldo, como cadena decimal. Un proxy de pago por GB lo lleva en cada día y en su summary; el costUnits de un bucket es null para un día con tráfico pero sin cobro registrado todavía, y el cobro de la hora en curso puede cambiar. Es null para el proxy de un paquete, que no se cobra por GB.

Los proxies eliminados se listan con deleted: true y el externalRef que tenían. Un proxy eliminado sin uso en el rango aparece solo cuando lo nombras en tokenIds. Un proxy de pago por GB existente siempre aparece. El proxy de un paquete aparece a menos que haya caducado antes de from.

Ubicación#

Un token de centro de datos o ISP, y un token móvil cuya ciudad u operador se pueden cambiar, informan un campo location y admiten esta API. Qué tokens cumplen los requisitos y cómo se comporta un cambio:

Token Cambios Espera
Centro de datos/ISP, rotativo En cualquier momento Ninguna
Centro de datos/ISP, estático Una IP nueva en la ubicación elegida Una vez por semana
Centro de datos/ISP, estático, fuera de su ubicación guardada Mover de vuelta a la ubicación guardada Ninguna
Móvil con «Multiubicación» (complemento de pago) En cualquier momento Ninguna
Móvil compartido estándar de EE. UU. Ciudad y operador juntos Una vez cada 48 horas
Todo lo demás (PPG, Dispositivo privado, móvil fuera de EE. UU., un paquete de un día o un token anterior sin tipo de puerto) No admitido Ninguna
GET /api/v1/tokens/{tokenId}/location
Authorization: Bearer lit_...
{
  "data": {
    "tokenId": 12345,
    "kind": "datacenter",
    "mode": "rotating",
    "target": { "country": "us", "region": "new-york", "city": "new-york-city" },
    "effective": {
      "country": "us", "region": "new-york", "city": "new-york-city",
      "labels": { "region": "New York", "city": "New York City" }
    },
    "status": "ready",
    "canChangeNow": true,
    "nextChangeAt": null
  }
}

kind es datacenter, isp o mobile. mode es rotating o static. target es la opción guardada; en centro de datos/ISP, region/city pueden ser "any". effective es la ubicación real de la IP que el token tiene en este momento, o null cuando aún no se conoce. status es pending durante un breve tiempo mientras se propaga un cambio, ready una vez que se propagó, package-inactive cuando el paquete del token no está activo, o allowance-exhausted, solo para un paquete «Multiubicación» más antiguo que todavía tiene un tope de tráfico. Un token de centro de datos o ISP informa dos valores más, según dónde esté su IP en este momento:

  • fallback: el proxy funciona con una IP fuera de su ubicación guardada, porque la ubicación no tenía ninguna IP libre. Un proxy rotativo vuelve solo cuando hay una IP libre allí. Uno estático se queda donde está hasta que lo muevas de vuelta, porque una IP que cambia sin que se pida rompería las listas de IP permitidas de los sitios donde se usa.
  • unavailable: la IP del proxy no funciona en este momento; se está moviendo a una que funcione, lo que suele tardar unos minutos.

fallback es un valor más reciente, así que un cliente que decide según status tiene que manejarlo. En un token móvil, unavailable sigue significando que la ubicación de destino no tiene en este momento ningún dispositivo en funcionamiento (el token conserva el último que tenía en lugar de perder su ruta).

Listar las ubicaciones disponibles#

GET /api/v1/tokens/{tokenId}/location/options?level=region
GET /api/v1/tokens/{tokenId}/location/options?level=city&region=new-york

Centro de datos/ISP: level=region, luego level=city&region=…. Móvil: level=city, luego level=carrier&city=…. Cada opción es {"value": …, "label": …}, y la lista contiene solo las opciones que este token puede usar en este momento.

Cambiar la ubicación#

Centro de datos/ISP:

curl -X PUT 'https://litport.net/api/v1/tokens/12345/location' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"region": "new-york", "city": "new-york-city"}'

Móvil:

curl -X PUT 'https://litport.net/api/v1/tokens/98765/location' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"city": "seattle", "carrier": "verizon"}'

Que el servidor elija, para cualquiera de los dos tipos:

curl -X PUT 'https://litport.net/api/v1/tokens/12345/location' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"random": true}'

Envía exactamente los campos que corresponden al tipo de ese token: en centro de datos/ISP son region y city; en móvil son city y carrier. country es opcional y debe ser "us" si se envía. No se requiere ni se respeta ningún encabezado de precondición: el último PUT confirmado pasa a ser el destino deseado del token, y un PUT idéntico al destino guardado actualmente se completa con éxito sin un nuevo cambio.

Un token de centro de datos/ISP rotativo pasa de inmediato a una IP que coincida. Uno estático recibe una IP nueva en la ubicación elegida, usando su cupo de una vez por semana; una repetición dentro de esa semana da 409 CHANGE_LIMIT con nextChangeAt. Un token «Multiubicación» cambia de inmediato, sin espera. Un token móvil compartido estándar de Estados Unidos se puede cambiar una vez cada 48 horas; una repetición dentro de esa ventana también da 409 CHANGE_LIMIT.

En cualquier token móvil, la ciudad siempre se conserva: si el operador elegido no tiene ningún teléfono funcionando en esa ciudad, el proxy usa en su lugar otro operador de la misma ciudad, y effective muestra el operador que realmente se está usando.

{"random": true} se envía solo, sin ningún otro campo. El servidor elige una ubicación que este proxy puede usar en este momento, entre los mismos valores que muestra Listar las ubicaciones disponibles: una ciudad distinta cuando la hay y, en un proxy móvil, cuando su ciudad es la única, otro operador de la misma ciudad. Nunca elige el target actual del proxy. La elección se guarda como destino igual que cualquier otro cambio, con las mismas comprobaciones y las mismas esperas (un proxy estático de centro de datos/ISP usa su cupo de una vez por semana, un proxy móvil compartido estándar de Estados Unidos el de 48 horas, y CHANGE_LIMIT lleva nextChangeAt como siempre), y target en la respuesta muestra adónde fue el proxy. Si una elección resulta no tener ninguna IP libre ni ningún teléfono disponible, se prueba la siguiente, hasta tres. Si no hay ninguna otra ubicación, o ninguna de las tres puede recibir el proxy, la respuesta es 409 LOCATION_UNAVAILABLE y no cambia nada.

Un cambio aleatorio no se puede repetir a ciegas: cuando no se aplica ninguna espera, cada repetición vuelve a mover el proxy. Tras una respuesta perdida, lee GET /tokens/{tokenId}/location antes de enviarlo de nuevo.

Mover de vuelta#

POST /api/v1/tokens/{tokenId}/location/return
Authorization: Bearer lit_...

Para un token estático de centro de datos o ISP cuyo status es fallback: toma una IP libre en su ubicación guardada, con el mismo host, puerto, usuario y contraseña. Es gratis: no usa el cupo de una vez por semana y el target guardado no cambia. La solicitud no lleva cuerpo (se acepta un {} vacío). Devuelve la misma estructura que Ubicación, con la IP effective nueva. La IP cambia, así que una lista de IP permitidas en un sitio de destino que tenía la IP anterior deja de coincidir.

Un token rotativo no tiene esta solicitud: vuelve solo cuando hay una IP libre en su ubicación guardada. Cualquier otro token responde 409 NOT_SUPPORTED.

Una repetición después de un éxito da 409 NOT_IN_FALLBACK y no da una segunda IP, así que es seguro volver a enviar la solicitud tras una respuesta perdida.

Estado Código Significado
400 INVALID_REQUEST_BODY La solicitud trae un cuerpo que no está vacío.
404 TOKEN_NOT_FOUND tokenId desconocido, ajeno o con formato incorrecto.
409 NOT_SUPPORTED No es un token estático de centro de datos o ISP, o no tiene una ubicación guardada.
409 PACKAGE_INACTIVE El token o su paquete no está activo.
409 NOT_IN_FALLBACK El token no está fuera de su ubicación guardada (una repetición tras un éxito llega aquí), o su IP aún no funciona. No cambió nada.
409 LOCATION_UNAVAILABLE La ubicación guardada aún no tiene ninguna IP libre. No cambió nada; inténtalo de nuevo más tarde.
409 CONCURRENT_CHANGE Otro cambio en este token llegó en el mismo instante. Lee la ubicación y vuelve a enviar la solicitud solo mientras status siga siendo fallback.

Errores de ubicación#

Estado Código Significado
400 INVALID_REQUEST_BODY El cuerpo tiene campos incorrectos para el tipo de este token, random no es true o random se envió junto con otros campos.
400 INVALID_LOCATION No es una ubicación u operador de EE. UU. admitido, o es "any" para un token móvil compartido estándar.
400 INVALID_LEVEL / INVALID_PARENT Opciones: un level que este token no usa, o falta region/city.
404 TOKEN_NOT_FOUND tokenId desconocido, ajeno o con formato incorrecto.
409 NOT_SUPPORTED La ubicación de este token no se puede cambiar.
409 PACKAGE_INACTIVE El token o su paquete no está activo.
409 CHANGE_LIMIT Dentro de la espera semanal o de 48 horas. El error incluye nextChangeAt y un Retry-After equivalente.
409 LOCATION_UNAVAILABLE No hay ninguna IP utilizable ni teléfono en funcionamiento allí en este momento o, con random, no hay ninguna otra ubicación disponible. No cambió nada.
409 CONCURRENT_CHANGE Otro cambio en este token llegó en el mismo instante. Reintenta el mismo PUT.

Rotación#

PUT /api/v1/tokens/{tokenId}/rotation
Authorization: Bearer lit_...
Content-Type: application/json

{"intervalSec": 600}
{
  "data": { "tokenId": 12345, "intervalSec": 600, "options": [600, 1800, 3600], "changeable": true }
}

intervalSec debe ser uno de los options, los mismos valores que enumera el propio campo rotation del token. changeable es true para un token de centro de datos/ISP rotativo, un token móvil compartido estándar de Estados Unidos y un Dispositivo privado de Estados Unidos. Los options de un Dispositivo privado empiezan en 2 minutos. Un token «Multiubicación» siempre informa el intervalo de su teléfono actual con changeable: false, porque el teléfono en el que está el proxy define su propio temporizador; su PUT también responde 409 NOT_SUPPORTED, igual que cualquier otro token que no rota.

Errores de rotación#

Estado Código Significado
400 INVALID_REQUEST_BODY El cuerpo no es exactamente {"intervalSec": <integer>}.
400 INVALID_ROTATION intervalSec no es uno de los options del token.
404 TOKEN_NOT_FOUND tokenId desconocido, ajeno o con formato incorrecto.
409 NOT_SUPPORTED El token no rota, o su intervalo lo define el teléfono («Multiubicación»).
409 PACKAGE_INACTIVE El token o su paquete no está activo.

IP nueva#

POST /api/v1/tokens/{tokenId}/new-ip
Authorization: Bearer lit_...

El botón Obtener IP nueva del proxy en el panel y el enlace para cambiar la IP del token son las formas sin código de hacer lo mismo; consulta Cambiar la IP. Este endpoint cubre solo tokens de centro de datos e ISP. Un Dispositivo privado cambia de IP con su enlace para cambiar la IP. La solicitud no lleva cuerpo. La IP nueva se queda en la ubicación guardada del token. Un token cuyo status es fallback o unavailable (fuera de su ubicación, o con una IP que dejó de funcionar) recibe una en su ubicación guardada si hay una libre allí; si no, en la misma región y después en cualquier lugar de EE. UU. Devuelve la misma estructura que Ubicación, con una IP effective nueva.

Un token estático usa su cupo de una vez por semana. El servicio reutiliza la ubicación guardada del propio token en cada intento, incluido un reintento.

Un token rotativo recibe una IP nueva en cualquier momento. La IP nueva siempre es distinta de la actual y el temporizador automático se reinicia: el siguiente cambio automático llega rotation.intervalSec segundos después de este. Las conexiones nuevas usan la IP nueva en unos 5 segundos; las conexiones abiertas conservan la IP anterior hasta que se reconecten. Entre dos solicitudes debe pasar al menos el valor más corto de rotation.options del token; una repetición dentro de esa espera da 409 CHANGE_LIMIT.

En un token estático, esta es la única escritura que no es seguro repetir a ciegas. Si se pierde una respuesta o se agota el tiempo de espera, consulta GET /tokens/{tokenId}/location antes de reintentar: un nextChangeAt posterior a la hora actual significa que el cambio se realizó. Enviar el POST de nuevo dentro de esa semana no da una segunda IP; devuelve 409 CHANGE_LIMIT.

En un token rotativo, una respuesta perdida no se puede confirmar con GET /tokens/{tokenId}/location: su canChangeNow y su nextChangeAt hablan de la ubicación y no dicen nada sobre esta espera. Enviar el POST de nuevo después de Retry-After no hace daño; solo da otra IP nueva. Un 409 CHANGE_LIMIT justo después de una respuesta perdida no demuestra que el cambio se hiciera, porque una respuesta 409 LOCATION_UNAVAILABLE también consume la espera.

Errores de IP nueva#

Estado Código Significado
404 TOKEN_NOT_FOUND tokenId desconocido, ajeno o con formato incorrecto.
409 NOT_SUPPORTED El token no es un proxy de centro de datos o ISP.
409 PACKAGE_INACTIVE El token o su paquete no está activo.
409 CHANGE_LIMIT Estático: el reemplazo de esta semana ya se usó. Rotativo: dentro de la espera desde la última solicitud. El error incluye nextChangeAt y un Retry-After equivalente.
409 LOCATION_UNAVAILABLE No hay ninguna otra IP utilizable en la ubicación guardada en este momento. No cambió nada; en un token rotativo, la solicitud igualmente consume la espera.
409 CONCURRENT_CHANGE Otro cambio en este token llegó en el mismo instante. Estático: consulta la ubicación y luego reintenta. Rotativo: envía la solicitud de nuevo cuando termine la espera.

rotateUrl cambia la IP sin clave de API: envía un GET a ese enlace desde un script o una app, o ábrelo en un navegador. Un enlace abierto como página en una pestaña del navegador muestra una página corta en el idioma del usuario. Cualquier otro cliente recibe el JSON de abajo, y &format=json siempre devuelve JSON, por ejemplo para una app que controla un navegador real. Quien tenga el enlace puede cambiar la IP, así que mantenlo tan privado como la contraseña. Restablecer, junto al enlace en el panel, genera un enlace nuevo y el anterior deja de funcionar de inmediato. En un token rotativo de centro de datos/ISP sigue las mismas reglas que POST /tokens/{tokenId}/new-ip, arriba: la espera entre cambios, una IP nueva en la ubicación guardada y el reinicio del temporizador. Cambiar la IP es la guía del enlace y del botón. Toda respuesta JSON es HTTP 200 con un cuerpo de esta tabla:

Cuerpo Significado
{"status": "ok"} Listo. Un token rotativo de centro de datos/ISP tiene una IP nueva. Un Dispositivo privado empieza a cambiar su IP.
{"error": "tooFrequent", "retryAfterSec": 4} Demasiado pronto desde el último cambio. Envía la solicitud de nuevo después de retryAfterSec segundos. Sin retryAfterSec, el enlace se llamó más de 20 veces en un minuto, o un Dispositivo privado cambió su IP hace menos de un minuto.
{"error": "noOtherIp"} No hay otra IP en la ubicación guardada del token en este momento. No cambió nada y la espera sigue aplicándose.
{"error": "invalidKey"} El enlace es desconocido, o su token está caducado, desactivado o en un paquete que no está activo.
{"error": "internalError"} Algo falló de nuestro lado. Inténtalo de nuevo más tarde.