Skip to main content
Lumi’s public REST API for automation: read account data, check and buy resources, top up balance. Each product has its own API and its own key.
A key for one product works only with that product. Domains and proxy use separate keys. Keys are issued by an operator, message @lumisup_robot.

Authentication

Every request carries the key in a header:
Keys are shown once, so keep them secret. Only a hash is stored; a key cannot be recovered, only re-issued.

Key types

  • Reseller: every request is automatically scoped to its account. A foreign user_id returns 404 (the existence of other accounts is not revealed).
  • Operator: passes user_id explicitly (body or ?user_id=); required for money operations.

Scopes

A reseller key holds a set of scopes. An operator key holds all of them implicitly. A missing scope → 403 forbidden_scope.

Money operations

Endpoints that move money (create invoice, buy, renew) follow extra rules.
Money operations work only when API_MONEY_ENABLED is on for the deployment. While off, such requests return 403 money_disabled even if the key holds the scope.

Idempotency

Every money POST must carry an Idempotency-Key header (8–200 chars):
  • A repeat with the same key returns the original response without re-running the operation.
  • Two simultaneous identical requests won’t both execute: the loser gets 409 in_progress.
  • Missing header → 400 idempotency_key_required.

Daily spend cap

A key may have a daily USD cap (or the global default). Once reached, money operations return 402 daily_cap_exceeded until the next UTC day. Operator keys are exempt.

Request signing (optional)

If a key is issued with signing required, every money request must carry:
The signature is computed over the exact request-body bytes, so a leaked Bearer alone cannot move money without the second secret. A missing/invalid signature → 401 invalid_signature.

Rate limits

A bulk request consumes one money “token” per item. On exceed → 429 rate_limited with a Retry-After header (seconds).

Pagination

List endpoints use a cursor:
  • limit: 1–200 (default 50).
  • Response: { "items": [...], "next_cursor": "...", "has_more": true }. Pass next_cursor as cursor for the next page. next_cursor: null means no more pages.

Bulk operations

Bulk endpoints take an array and return a per-item result. They are not atomic: one item failing does not roll back the others.
Item cap per request is 500, else 413 batch_too_large. Long bulk purchases run asynchronously: the endpoint returns 202 with a batch_id; poll status via GET /v1/batches/{batch_id}.

Error format

All errors share one JSON shape:

Money in responses

Money amounts are always strings ("5.15"), never floats, so there is no precision loss. Send amounts as strings too.

Health

Unauthenticated liveness probe.