Conventions
Money and volume are strings
Section titled “Money and volume are strings”{ "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.
Extensible enums
Section titled “Extensible enums”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”.
Pagination
Section titled “Pagination”| Parameter | Meaning |
|---|---|
offset | how many rows to skip; 0 by default |
limit | 1..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.
Idempotency
Section titled “Idempotency”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-446655440000A 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)
Geo catalog cache
Section titled “Geo catalog cache”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.
Versioning
Section titled “Versioning”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.