Skip to content

Conventions

{
"balance": "124.30",
"currency": "USD"
}
{
"purchased_gb": "25.000",
"used_gb": "2.566",
"left_gb": "22.434"
}

Parse them as decimal, not as float. The currency is USD. A gigabyte = 10^9 bytes.

ISO-8601 with an explicit offset, always UTC: 2026-08-28T14:03:11+00:00.

Order status, transaction type, event type, package status, kind, family gain new values within v1 without notice - an unfamiliar value must be tolerated. In filters an unfamiliar value is read as “no filter”.

ParameterMeaning
offsethow many rows to skip; 0 by default
limit1..200, 50 by default (200 for GET /api/v1/packages)

Both are clamped, not rejected, and returned in the body already clamped. The response carries total.

GET /api/v1/orders?limit=100&offset=100
-> { "orders": [...], "total": 317, "offset": 100, "limit": 100 }

On lists that are being written to, offset addresses a position: when doing a full export, deduplicate by id. The order is fixed - newest first.

The event log is read differently: ?after=<id>, the response carries next_after.

Operations that charge money require the header: POST /api/v1/packages (purchase), POST /api/v1/packages/{id}/topup (traffic top-up) and POST /api/v1/packages/{id}/prolong (address renewal).

Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

A string up to 255 characters, surrounding whitespace is trimmed.

A retry with the same key and the same body returns the same response. Generate the key before the request and reuse it on retry, including a retry after a timeout.

The key is remembered for 24 hours: the same key a day later starts a new operation.

Errors:

  • 422 - idempotency_key_required (no header), idempotency_key_invalid (empty or longer than 255), idempotency_key_reused (the same key with a different body)
  • 409 - idempotency_in_progress (the previous request is still running - retry a bit later with the same key)
  • 500 - operation_indeterminate (a retry with the key of an operation whose outcome is undetermined - see Errors)

The geo catalog levels return an ETag - an opaque hash of the catalog version. Send it in If-None-Match - you get 304 with no body. The same version in readable form is in the body as the version field.

Released in v1 without notice: a new response field, a new optional parameter, a new value of an extensible enum, a new endpoint, a new error code on an existing status.

Only in a new version: removing or renaming a field, narrowing a type, a new required request field, changing the status or code for a documented case, changing a default value.

Deprecation: Deprecation and Sunset headers, at least 6 months before shutdown.