Balance and events
GET /api/v1/balance
Section titled “GET /api/v1/balance”Scope billing:read. Top-ups are done in the dashboard.
{ "balance": "124.30", "currency": "USD"}GET /api/v1/transactions
Section titled “GET /api/v1/transactions”Scope billing:read. Parameters: offset, limit, type.
The order is fixed and cannot be configured: newest first, by created_at, ties broken by id.
There is no sort parameter.
type: deposit, purchase, refund, commission, bonus - what each of them stands for, see
Top-ups and bonuses.
external_reference is the external event that produced the movement, not the transaction
identifier (that is id).
promo_code is filled for rows of type bonus - it is the code the bonus was credited for. For
other types it is null.
Events
Section titled “Events”GET /api/v1/events, scope events:read. Read forward from ?after=<id>, oldest first.
Parameters: after, limit, type.
{ "events": [ { "id": 881, "type": "order.completed", "occurred_at": "2026-08-28T12:00:04+00:00", "order_id": 128, "package_id": 42, "data": { "family": "traffic_gateway", "client_reference": "deal-8891" } }, { "id": 882, "type": "package.traffic_low", "occurred_at": "2026-08-28T18:31:00+00:00", "order_id": 128, "package_id": 42, "data": { "purchased_gb": "35.000", "left_gb": "3.410" } } ], "next_after": 882}| Type | When | data |
|---|---|---|
order.provisioning | the order went into issuance | family, client_reference |
order.completed | issuance succeeded; also arrives for an address renewal | family, client_reference |
order.failed | the order did not go through | + refunded |
order.refunded | the money was returned | + refunded |
package.traffic_low | the remainder dropped below 10% | purchased_gb, left_gb |
package.traffic_exhausted | the volume is used up | purchased_gb, left_gb |
package.expired | the term of a fixed address package has ended, the addresses do not answer | expired_at, cut_off (true - the password is disabled, a renewal issues a new one) |
topup.credited | a top-up was credited | amount, external_reference |
api_key.revoked | a key was revoked | api_key_id, name |
For package.* events the order_id field is the order the package was bought with.
- Delivery is at-least-once: deduplicate by
id. next_afteris the position for the next request;nullmeans there are no new events.- An empty
eventsmeans you have caught up with the log. - Events are kept for 30 days.
after = load_position()
while True: params = {"limit": 200} | ({"after": after} if after else {}) body = session.get(f"{BASE}/api/v1/events", params=params, headers=AUTH).json()
for event in body["events"]: if not already_handled(event["id"]): handle(event) mark_handled(event["id"])
if body["next_after"] is not None: after = body["next_after"] save_position(after)
if not body["events"]: sleep(15)Delivery is by polling the log only.