Documentation menu

API errors

Every endpoint under https://litport.net/api/v1 (Tokens, Packages, and Pay-per-GB) returns its errors in the JSON format on this page. Failures of a proxied connection itself use separate numeric proxy error codes, and the public free proxy API is not covered here.

Error envelope#

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication failed.",
    "requestId": "req_example",
    "docsUrl": "https://litport.net/docs/api/errors"
  }
}

The same request ID appears in the X-Request-ID header. Log it with the HTTP status and error code. Never log the Authorization header.

A 409 that carries a wait also adds nextChangeAt, an ISO-8601 UTC timestamp: CHANGE_LIMIT on a token's location or new IP.

Status reference#

Status Codes Client action
400 INVALID_REQUEST_BODY, INVALID_LIMIT, INVALID_CURSOR, INVALID_TYPE, INVALID_STATUS, INVALID_PACKAGE_ID, INVALID_TIME_RANGE, INVALID_GROUP_BY, INVALID_INCLUDE, INVALID_POOL, INVALID_LEVEL, INVALID_PARENT, GEO_NOT_ENABLED, GEO_LEVEL_UNSUPPORTED, INVALID_IP, IPV6_UNSUPPORTED, INVALID_LOCATION, INVALID_ROTATION Correct the request. Do not retry it unchanged.
401 UNAUTHORIZED Supply a current API key using the Bearer scheme. The response does not reveal whether a key or user exists.
404 TOKEN_NOT_FOUND, PACKAGE_NOT_FOUND Check the ID and ownership. The response does not disclose another user's token or package.
404 NOT_FOUND Correct the route; it does not exist.
405 METHOD_NOT_ALLOWED Use one of the methods in the Allow header.
409 NOT_SUPPORTED, PACKAGE_INACTIVE, CONCURRENT_CHANGE, LOCATION_UNAVAILABLE, CHANGE_LIMIT, ALLOWED_IPS_LIMIT_REACHED See the matching detail below; CONCURRENT_CHANGE means retry the same request, CHANGE_LIMIT means wait for the reported nextChangeAt.
413 INVALID_REQUEST_BODY The body exceeds 4 KiB. Send a smaller one.
415 INVALID_CONTENT_TYPE Send Content-Type: application/json for a write with a body.
429 RATE_LIMITED Respect Retry-After and use jittered backoff.
503 SERVICE_UNAVAILABLE, TOKEN_DATA_INVALID, ALLOWED_IPS_UNAVAILABLE Respect Retry-After, retry with bounded backoff, then contact support with the request ID.

Retry algorithm#

Auto-retry 429 and 503 with Retry-After and added jitter, except a 503 on POST /tokens/{tokenId}/new-ip (see below). Cap attempts and make the total retry budget visible to the caller.

Every write in this API is safe to repeat except new-ip: a 409 CONCURRENT_CHANGE or an ambiguous response (timeout, lost response, 503) can simply be sent again, because the latest write always wins and every other write is a no-op when it is already applied. For new-ip, an ambiguous result means reading GET /tokens/{tokenId}/location first and retrying only when nextChangeAt is not already later than the current time. A blind repeat inside the week only returns 409 CHANGE_LIMIT.

Error code details#

Invalid request body#

400 when the body fails to parse as JSON or fails an endpoint's own shape check (for example, PUT /tokens/{tokenId}/rotation needs exactly {"intervalSec": <integer>}). 413 when the body exceeds 4 KiB.

Invalid content type#

INVALID_CONTENT_TYPE means a write with a body was sent without Content-Type: application/json.

Invalid limit#

INVALID_LIMIT means limit is not an integer from 1 through 100.

Invalid cursor#

INVALID_CURSOR means the opaque cursor is malformed, edited, cannot be authenticated, or was issued for a different endpoint. Restart pagination without a cursor.

Invalid type#

INVALID_TYPE means type on GET /tokens is not unlimited or ppg.

Invalid status#

INVALID_STATUS means status on GET /tokens is not active, expired, or disabled.

Invalid package ID#

INVALID_PACKAGE_ID means the packageId filter on GET /tokens is not a positive integer. A packageId in a URL path is never a 400: an unknown or foreign one is 404 PACKAGE_NOT_FOUND.

Invalid time range#

INVALID_TIME_RANGE means a timestamp is not canonical UTC, from is not before to, or the requested span is too large.

Invalid group by#

INVALID_GROUP_BY means groupBy is not hour, day, or month.

Invalid include#

INVALID_INCLUDE means the requested expansion is incompatible with the token or grouping; charge components require a PPG token and hourly buckets.

Invalid pool#

INVALID_POOL means pool on GET /pay-per-gb/geo is missing, empty, or contains an auth key that does not resolve to a customer-selectable pool.

Invalid level#

INVALID_LEVEL means level is not one of the values that endpoint accepts: region/city for a token's location options, or country/region/city for pay-per-GB geo.

Invalid parent#

INVALID_PARENT means a required parent geography is missing: a token's location/options?level=city needs region; GET /pay-per-gb/geo needs country for level=region and for level=city.

Geo not enabled#

GEO_NOT_ENABLED means a requested pool has geo targeting switched off.

Geo level unsupported#

GEO_LEVEL_UNSUPPORTED means a requested pool does not support the requested level. Check the pool's geoLevels in Pay-per-GB.

Invalid IP#

INVALID_IP means the supplied address is not an exact public IPv4 literal.

IPv6 unsupported#

IPV6_UNSUPPORTED means an IPv6 address was sent to a package allowed-IP write; contact support.

Invalid location#

INVALID_LOCATION means the requested region, city, or carrier is not a value this token can use, or country was sent as something other than "us".

Invalid rotation#

INVALID_ROTATION means intervalSec on PUT /tokens/{tokenId}/rotation is not one of the token's listed options.

Unauthorized#

UNAUTHORIZED covers missing, malformed, unknown, rotated, and ownerless keys without revealing which condition occurred.

Token not found#

TOKEN_NOT_FOUND covers a missing, unowned, or unparseable tokenId on any token route. The response is identical in every case, so it never discloses another user's token.

Package not found#

PACKAGE_NOT_FOUND covers a missing, unowned, or unparseable packageId on any package route, including a package's allowed IPs.

Not found#

NOT_FOUND means the requested /api/v1 route does not exist.

Method not allowed#

METHOD_NOT_ALLOWED means a known endpoint received an unsupported method. The response includes its supported methods in Allow.

Not supported#

NOT_SUPPORTED means this token has no such control: its location can't be changed, its rotation interval can't be changed, or (new-ip) it is not a static datacenter or ISP proxy. A Multi-location token's rotation interval always answers NOT_SUPPORTED, because the phone the proxy is on sets it.

Package inactive#

PACKAGE_INACTIVE means the token's or package's paid period is not currently active.

Concurrent change#

CONCURRENT_CHANGE means another write to the same token or package landed at the same moment. Retry the same request.

Location unavailable#

LOCATION_UNAVAILABLE means the requested location currently has no usable IP or working device. Nothing changed.

Change limit#

CHANGE_LIMIT means a change or replacement allowance is already used: once a week for a static datacenter/ISP new IP or location change, once per 48 hours for a standard US Shared Mobile location change. The error carries nextChangeAt and a matching Retry-After.

Allowed IPs limit reached#

ALLOWED_IPS_LIMIT_REACHED means the package's allowed-IP list is already at its limit (1 or 50). Contact support to raise it.

Rate limited#

RATE_LIMITED means the API key, or for an allowed-IP write the package, exhausted its current window. Respect Retry-After.

Service unavailable#

SERVICE_UNAVAILABLE means an API dependency is temporarily unavailable. Respect Retry-After.

Token data invalid#

TOKEN_DATA_INVALID means a token's stored metadata is temporarily unreadable. Retry later, then report the request ID.

Allowed IPs unavailable#

ALLOWED_IPS_UNAVAILABLE means allowed-IP storage, configuration, or port allocation is unavailable, including a package temporarily out of assignable ports.

Authentication failures#

The API deliberately returns the same 401 envelope for malformed, unknown, rotated, and ownerless keys. Create or rotate an API key in Settings. A rotation immediately invalidates the previous active key.