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, INVALID, INVALID, INVALID_TYPE, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID_POOL, INVALID, INVALID, GEO, GEO, INVALID_IP, IPV6, INVALID, INVALID |
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, PACKAGE |
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 |
Use one of the methods in the Allow header. |
409 |
NOT, PACKAGE, CONCURRENT, LOCATION, CHANGE_LIMIT, ALLOWED |
See the matching detail below; CONCURRENT means retry the same request, CHANGE_LIMIT means wait for the reported nextChangeAt. |
413 |
INVALID |
The body exceeds 4 KiB. Send a smaller one. |
415 |
INVALID |
Send Content-Type: application for a write with a body. |
429 |
RATE_LIMITED |
Respect Retry-After and use jittered backoff. |
503 |
SERVICE, TOKEN, ALLOWED |
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.