# Evolution Boost Reseller API (v1) REST API for official Evolution Boost resellers: top up a BRL balance with PIX, buy Steam hour-boost license keys with it and look up your keys. Base URL: https://evolutionboost.xyz/api/v1 Docs: https://evolutionboost.xyz/docs/api OpenAPI 3.1: https://evolutionboost.xyz/openapi.json Generated from the same source as https://evolutionboost.xyz/docs/api and /openapi.json. ## Introduction The Evolution Boost Reseller API lets official resellers top up a balance with PIX, buy license keys with that balance and look up their keys (free, redeemed or all) from their own systems, bots or stores. It is a JSON REST API over HTTPS. The base URL is `https://evolutionboost.xyz/api/v1`. It is meant for server-to-server use: never call it from a browser or ship your API key inside an app (there is no CORS). - Money is always an integer number of cents of BRL (`12990` = R$ 129,90), with `currency: "BRL"`. - Timestamps are ISO 8601 in UTC. - Every response carries an `X-Request-Id` header. Include it when you contact support. - Responses are never cached (`Cache-Control: no-store`). - There are no webhooks in v1: poll the endpoints. ## Authentication Authenticate every request with your API key in the `Authorization` header as a Bearer token. Keys start with `evb_live_` and are created by the Evolution Boost team in the admin panel. You receive the full key only once, so store it in a secret manager or environment variable. ```http Authorization: Bearer evb_live_xxxxxxxxxxxxxxxx ``` - A missing, invalid, revoked or expired key returns `401 invalid_api_key` (same answer for all cases). - A valid key of a revoked reseller returns `403 reseller_inactive`. - Too many authentication failures from the same IP (20 per minute) return `429` before the key is even checked. - If a key leaks, ask the team to revoke it and issue a new one. You can have several keys (for example one per system). ### Headers - Authorization (Always): `Bearer evb_live_...`, your API key. - Content-Type (POST): `application/json`. Bodies are limited to 24000 bytes. - Idempotency-Key (POST): A unique key per operation (UUID). See Idempotency. - X-Request-Id (Optional): Your own request id (8 to 64 characters among `A-Z a-z 0-9 . _ -`), echoed back; otherwise we generate one. Always present in responses. ## Errors Errors use conventional HTTP status codes and a JSON body. Branch on `error.type` and `error.code`, never on `message`. `param` points to the field or header that caused the error. ```json { "error": { "type": "insufficient_balance", "code": "insufficient_balance", "message": "Insufficient balance: this purchase costs 5990 cents and the balance is 1200 cents.", "param": null }, "request_id": "req_5b0f3c9a1d2e4f6a8b7c9d0e1f2a3b4c" } ``` ### Error types - authentication_error (HTTP 401): The API key is missing, invalid, revoked or expired. - permission_error (HTTP 403): The key is valid but the reseller account is not active. - invalid_request_error (HTTP 400, 404, 405, 409, 413): The request is malformed or refers to something that does not exist. - insufficient_balance (HTTP 402): The balance does not cover the purchase. Nothing was charged. - rate_limit_error (HTTP 429): Too many requests. Wait `Retry-After` seconds. - api_error (HTTP 500, 502, 503): Something failed on our side or at the payment provider. Retry with backoff. ### Error codes - invalid_api_key (HTTP 401, authentication_error): Missing, invalid, revoked or expired API key. The response is the same for every case. - reseller_inactive (HTTP 403, permission_error): The reseller account was revoked or removed. - invalid_json (HTTP 400, invalid_request_error): The body is empty, is not JSON or is not a JSON object. - idempotency_key_required (HTTP 400, invalid_request_error): POST without the `Idempotency-Key` header. - invalid_idempotency_key (HTTP 400, invalid_request_error): `Idempotency-Key` must have 1 to 255 visible ASCII characters, no spaces. - invalid_amount (HTTP 400, invalid_request_error): `amount_cents` must be an integer between 1000 and 500000. - too_many_pending_deposits (HTTP 400, invalid_request_error): You already have 3 pending deposits. Pay one or wait for it to expire. - missing_items (HTTP 400, invalid_request_error): Send `items` (non-empty) or `package_code`. - invalid_items (HTTP 400, invalid_request_error): `items` must be an array of objects. - too_many_items (HTTP 400, invalid_request_error): `items` accepts at most 50 entries. - invalid_package_code (HTTP 400, invalid_request_error): `package_code` must look like `H150` (1 to 20 letters or digits). - invalid_quantity (HTTP 400, invalid_request_error): `quantity` must be an integer between 1 and 100. - duplicate_package (HTTP 400, invalid_request_error): The same package appears twice in `items`. Merge the quantities. - too_many_keys (HTTP 400, invalid_request_error): A request can create at most 100 keys in total. - package_unavailable (HTTP 400, invalid_request_error): The package does not exist or has no wholesale price. See `GET /packages`. - invalid_limit (HTTP 400, invalid_request_error): `limit` must be an integer between 1 and 100. - invalid_cursor (HTTP 400, invalid_request_error): `starting_after` is not a UUID or is not an object of this list. - invalid_status (HTTP 400, invalid_request_error): Unknown value in the `status` filter. - invalid_kind (HTTP 400, invalid_request_error): Unknown value in the `kind` filter. - invalid_batch_id (HTTP 400, invalid_request_error): `batch_id` must be a UUID. - insufficient_balance (HTTP 402, insufficient_balance): The balance does not cover the total of the purchase. Nothing was charged or created. - resource_missing (HTTP 404, invalid_request_error): The object does not exist or belongs to another reseller (same answer), or the endpoint does not exist. - method_not_allowed (HTTP 405, invalid_request_error): HTTP method not supported. See the `Allow` header. - idempotency_key_reused (HTTP 409, invalid_request_error): The `Idempotency-Key` was already used with a different body. Use a new key for a new operation. - payload_too_large (HTTP 413, invalid_request_error): The body is larger than 24000 bytes. - rate_limit_exceeded (HTTP 429, rate_limit_error): Rate limit reached. Wait the number of seconds in the `Retry-After` header. - internal_error (HTTP 500, api_error): Unexpected error. Retry later; for POSTs, reuse the same `Idempotency-Key`. - payment_provider_error (HTTP 502, api_error): The PIX provider failed to create the charge. Retry later. - service_unavailable (HTTP 503, api_error): The service is temporarily unavailable. Retry with backoff. ## Pagination List endpoints return `{"object": "list", "data": [...], "has_more": bool}`, newest first. Use `limit` (1 to 100, default 20) and, to get the next page, pass the `id` of the last object you received as `starting_after`. Stop when `has_more` is `false`. ```bash curl "https://evolutionboost.xyz/api/v1/keys?status=free&limit=100&starting_after=6e7f8a9b-0c1d-4e2f-9a3b-4c5d6e7f8a9b" \ -H "Authorization: Bearer $EVB_API_KEY" ``` ## Idempotency Every `POST` that moves money or creates keys requires an `Idempotency-Key` header. Generate a new UUID for each operation and reuse it only to retry that same operation (timeouts, network errors, 5xx). A retry never charges twice: it returns the original result. - `POST /keys` retried with the same key and body: `200` with the same batch and the header `Idempotent-Replayed: true` (the first call returns `201`). - `POST /deposits` retried with the same key and amount: `200` with the same deposit and the same PIX code (no new charge). - Same key with a different body: `409 idempotency_key_reused`. - Keys are scoped to your reseller account and do not expire. Never reuse a key for a new operation. ## Rate limits Limits are counted per API key (authentication failures, per IP). Going over returns `429 rate_limit_exceeded` with a `Retry-After` header in seconds. Wait that long before retrying. - Read endpoints (every GET): 120 per minute, per API key - POST /keys: 30 per minute, per API key - POST /deposits: 5 per 5 minutes, per API key - Authentication failures: 20 per minute, per IP ## Quickstart The recommended flow, from an empty balance to keys in hand: 1. Check what you can sell and your balance: `GET /packages` and `GET /balance`. 2. Top up: `POST /deposits` with `amount_cents` (R$ 10,00 to R$ 5.000,00). Pay the returned `br_code` (PIX copy-and-paste) or the QR in `br_code_base64`, then poll `GET /deposits/{id}` every 5 to 10 seconds until `status` is `paid`. 3. Buy keys: `POST /keys` with `items` and a fresh `Idempotency-Key`. The response has the full text of every key. 4. Track them: `GET /keys?status=free` (not redeemed yet) or `GET /keys?status=redeemed`. ```bash export EVB_API_KEY="evb_live_..." # 1. Packages and balance curl https://evolutionboost.xyz/api/v1/packages -H "Authorization: Bearer $EVB_API_KEY" curl https://evolutionboost.xyz/api/v1/balance -H "Authorization: Bearer $EVB_API_KEY" # 2. Deposit R$ 500,00, pay the PIX, poll until "paid" curl -X POST https://evolutionboost.xyz/api/v1/deposits \ -H "Authorization: Bearer $EVB_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"amount_cents": 50000}' curl https://evolutionboost.xyz/api/v1/deposits/9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b -H "Authorization: Bearer $EVB_API_KEY" # 3. Buy 10 keys of H150 curl -X POST https://evolutionboost.xyz/api/v1/keys \ -H "Authorization: Bearer $EVB_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"items": [{"package_code": "H150", "quantity": 10}]}' # 4. Keys not redeemed yet curl "https://evolutionboost.xyz/api/v1/keys?status=free" -H "Authorization: Bearer $EVB_API_KEY" ``` ## API reference ### Me Who you are: reseller, API key in use and balance. A good first call to test your integration. #### The Reseller object The reseller that owns the API key. - object (string (reseller)): Always `reseller`. - id (string): Reseller id. - name (string): Display name. - code (string): Reseller code. It is the first part of the keys you buy. - status (string (active | revoked)): Only `active` resellers can call the API. - token (TokenInfo): The API key used in this request. - balance (Balance): Current balance. #### GET /me — Retrieve the reseller Returns the reseller that owns the API key, the key used and the current balance. Rate limit: 120 per minute, per API key. Request examples: curl: ```bash curl https://evolutionboost.xyz/api/v1/me \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/me', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/me", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — The reseller. ```json { "object": "reseller", "id": "5f0c2a3e-8d41-4b6a-9e2f-1c7d3b9a6e10", "name": "ACME Games", "code": "ACME", "status": "active", "token": { "name": "Store backend", "prefix": "xxxxxxxx" }, "balance": { "object": "balance", "balance_cents": 125000, "currency": "BRL", "updated_at": "2026-10-17T14:10:03.000Z" } } ``` Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. ### Packages Plans available to resellers, with your wholesale price. #### The Package object A plan you can buy keys for, with your wholesale price. - object (string (package)): Always `package`. - code (string): Package code used in `POST /keys` (for example `H150`). - hours (integer): Farming hours granted by one key. - account_limit (integer): Steam accounts the customer can farm at the same time. - price_cents (integer): Your wholesale price per key, in cents of BRL. - currency (string (BRL)): Always `BRL`. #### GET /packages — List packages Lists the packages you can buy keys for, with your wholesale price per key. Packages without a wholesale price are not listed and cannot be bought. Not paginated (`has_more` is always `false`). Rate limit: 120 per minute, per API key. Request examples: curl: ```bash curl https://evolutionboost.xyz/api/v1/packages \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/packages', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/packages", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — The list of packages. ```json { "object": "list", "data": [ { "object": "package", "code": "H150", "hours": 150, "account_limit": 3, "price_cents": 499, "currency": "BRL" }, { "object": "package", "code": "H600", "hours": 600, "account_limit": 6, "price_cents": 1099, "currency": "BRL" }, { "object": "package", "code": "H1200", "hours": 1200, "account_limit": 12, "price_cents": 1899, "currency": "BRL" } ], "has_more": false } ``` Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. ### Balance Your prepaid balance in BRL. Deposits credit it; key purchases debit it. #### The Balance object The current wallet balance of the reseller. - object (string (balance)): Always `balance`. - balance_cents (integer): Available balance in cents of BRL. - currency (string (BRL)): Always `BRL`. - updated_at (string | null): Last balance change; `null` if the wallet was never used. #### GET /balance — Retrieve the balance Returns the current balance of your wallet, in cents of BRL. Rate limit: 120 per minute, per API key. Request examples: curl: ```bash curl https://evolutionboost.xyz/api/v1/balance \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/balance', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/balance", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — The balance. ```json { "object": "balance", "balance_cents": 125000, "currency": "BRL", "updated_at": "2026-10-17T14:10:03.000Z" } ``` Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. ### Ledger Every balance movement, immutable, with the balance after each one. #### The LedgerEntry object An immutable balance movement. - object (string (ledger_entry)): Always `ledger_entry`. - id (string): Entry id (also the pagination cursor). - kind (string (deposit | key_purchase | adjustment | refund)): `deposit` (PIX paid), `key_purchase` (keys bought), `adjustment` (manual, by the Evolution Boost team) or `refund`. - amount_cents (integer): Signed amount: positive credits, negative debits. - balance_after_cents (integer): Balance right after this movement. - currency (string (BRL)): Always `BRL`. - ref_type (string | null): What originated it, for example `deposit` or `key_batch`; usually `null` for adjustments. - ref_id (string | null): Id of the deposit or of the key batch. - description (string | null): Short human-readable description (may be in Portuguese). - created_at (string): When the movement happened. #### GET /ledger — List ledger entries Lists balance movements, newest first. Paginated. Rate limit: 120 per minute, per API key. Parameters: - limit [query, integer, optional]: Number of objects to return, between 1 and 100. Default 20. - starting_after [query, string, optional]: Cursor: the `id` of the last object of the previous page. Returns the objects that come after it. - kind [query, string (deposit | key_purchase | adjustment | refund), optional]: Only movements of this kind. Request examples: curl: ```bash curl "https://evolutionboost.xyz/api/v1/ledger?kind=key_purchase&limit=20" \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/ledger?kind=key_purchase&limit=20', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/ledger?kind=key_purchase&limit=20", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — A page of ledger entries. ```json { "object": "list", "data": [ { "object": "ledger_entry", "id": "7d6c5b4a-3f2e-4d1c-9b0a-8f7e6d5c4b3a", "kind": "key_purchase", "amount_cents": -5990, "balance_after_cents": 125000, "currency": "BRL", "ref_type": "key_batch", "ref_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "description": "10x H150, 1x H600", "created_at": "2026-10-17T14:10:03.000Z" }, { "object": "ledger_entry", "id": "2e3f4a5b-6c7d-4e8f-a9b0-c1d2e3f4a5b6", "kind": "deposit", "amount_cents": 50000, "balance_after_cents": 130990, "currency": "BRL", "ref_type": "deposit", "ref_id": "9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b", "description": "Deposito PIX", "created_at": "2026-10-17T14:02:41.000Z" } ], "has_more": true } ``` Errors: - 400 invalid_limit: `limit` must be an integer between 1 and 100. - 400 invalid_cursor: `starting_after` is not a UUID or is not an object of this list. - 400 invalid_kind: Unknown value in the `kind` filter. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. ### Deposits PIX charges that credit your balance. From R$ 10,00 to R$ 5.000,00 each, at most 3 pending at a time. #### The Deposit object A PIX charge that credits your balance once paid. - object (string (deposit)): Always `deposit`. - id (string): Deposit id. - amount_cents (integer): Amount in cents of BRL. - currency (string (BRL)): Always `BRL`. - status (string (pending | paid | failed | expired)): `pending` until the PIX is paid; `paid` means the balance was credited; `failed` or `expired` will never be credited. - br_code (string | null): PIX copy-and-paste code. Only while `pending`. - br_code_base64 (string | null): QR code as a PNG data URL (`data:image/png;base64,...`). Only while `pending`. - expires_at (string | null): When the PIX charge expires (set by the payment provider). - created_at (string): Creation time. - paid_at (string | null): When the payment was confirmed. #### POST /deposits — Create a deposit Creates a PIX charge for `amount_cents`. Pay `br_code` (copy-and-paste) or the QR in `br_code_base64`; the balance is credited automatically once the payment is confirmed. Then poll `GET /deposits/{id}`. At most 3 pending deposits at a time. Rate limit: 5 per 5 minutes, per API key. Parameters: - Idempotency-Key [header, string, required]: Unique key per operation (a UUID is ideal), 1 to 255 visible ASCII characters. Retrying with the same key never charges twice. Body (JSON): - amount_cents [integer, required]: Amount in cents of BRL, from 1000 (R$ 10,00) to 500000 (R$ 5.000,00). Request examples: curl: ```bash curl -X POST https://evolutionboost.xyz/api/v1/deposits \ -H "Authorization: Bearer $EVB_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"amount_cents":50000}' ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/deposits', { method: 'POST', headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID(), // reuse it only to retry this same call }, body: JSON.stringify({ "amount_cents": 50000 }), }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import uuid import requests response = requests.post( "https://evolutionboost.xyz/api/v1/deposits", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", "Idempotency-Key": str(uuid.uuid4()), # reuse it only to retry this same call }, json={ "amount_cents": 50000 }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — The pending deposit with the PIX code. A retry with the same `Idempotency-Key` returns the same deposit. ```json { "object": "deposit", "id": "9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b", "amount_cents": 50000, "currency": "BRL", "status": "pending", "br_code": "00020101021226850014br.gov.bcb.pix...6304A1B2", "br_code_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...", "expires_at": "2026-10-18T14:00:00.000Z", "created_at": "2026-10-17T14:00:00.000Z", "paid_at": null } ``` Errors: - 400 idempotency_key_required: POST without the `Idempotency-Key` header. - 400 invalid_idempotency_key: `Idempotency-Key` must have 1 to 255 visible ASCII characters, no spaces. - 400 invalid_json: The body is empty, is not JSON or is not a JSON object. - 400 invalid_amount: `amount_cents` must be an integer between 1000 and 500000. - 400 too_many_pending_deposits: You already have 3 pending deposits. Pay one or wait for it to expire. - 409 idempotency_key_reused: The `Idempotency-Key` was already used with a different body. Use a new key for a new operation. - 413 payload_too_large: The body is larger than 24000 bytes. - 502 payment_provider_error: The PIX provider failed to create the charge. Retry later. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. #### GET /deposits/{id} — Retrieve a deposit Returns a deposit. While it is `pending`, this call also checks the payment with the PIX provider, so polling it every 5 to 10 seconds is how you learn that the balance was credited. A deposit of another reseller returns 404. Rate limit: 120 per minute, per API key. Parameters: - id [path, string, required]: Deposit id. Request examples: curl: ```bash curl https://evolutionboost.xyz/api/v1/deposits/9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/deposits/9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/deposits/9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — The deposit. ```json { "object": "deposit", "id": "9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b", "amount_cents": 50000, "currency": "BRL", "status": "paid", "br_code": null, "br_code_base64": null, "expires_at": "2026-10-18T14:00:00.000Z", "created_at": "2026-10-17T14:00:00.000Z", "paid_at": "2026-10-17T14:02:41.000Z" } ``` Errors: - 404 resource_missing: The object does not exist or belongs to another reseller (same answer), or the endpoint does not exist. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. #### GET /deposits — List deposits Lists your deposits, newest first. Paginated. Unlike `GET /deposits/{id}`, the list does not check pending payments with the provider. Rate limit: 120 per minute, per API key. Parameters: - limit [query, integer, optional]: Number of objects to return, between 1 and 100. Default 20. - starting_after [query, string, optional]: Cursor: the `id` of the last object of the previous page. Returns the objects that come after it. - status [query, string (pending | paid | failed | expired), optional]: Only deposits with this status. Request examples: curl: ```bash curl "https://evolutionboost.xyz/api/v1/deposits?status=paid&limit=20" \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/deposits?status=paid&limit=20', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/deposits?status=paid&limit=20", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — A page of deposits. ```json { "object": "list", "data": [ { "object": "deposit", "id": "9b1e4c77-2f3a-4d8e-b5c6-0a1f2e3d4c5b", "amount_cents": 50000, "currency": "BRL", "status": "paid", "br_code": null, "br_code_base64": null, "expires_at": "2026-10-18T14:00:00.000Z", "created_at": "2026-10-17T14:00:00.000Z", "paid_at": "2026-10-17T14:02:41.000Z" }, { "object": "deposit", "id": "3c8f1a20-6b7d-4e9f-8a1b-2c3d4e5f6a7b", "amount_cents": 100000, "currency": "BRL", "status": "paid", "br_code": null, "br_code_base64": null, "expires_at": "2026-10-11T09:00:00.000Z", "created_at": "2026-10-10T09:00:00.000Z", "paid_at": "2026-10-10T09:01:15.000Z" } ], "has_more": false } ``` Errors: - 400 invalid_limit: `limit` must be an integer between 1 and 100. - 400 invalid_cursor: `starting_after` is not a UUID or is not an object of this list. - 400 invalid_status: Unknown value in the `status` filter. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. ### Keys Buy license keys with your balance and look up the keys you own. #### The Key object A license key that belongs to you. - object (string (key)): Always `key`. - id (string): Key id (also the pagination cursor). - key (string | null): Full key text. `null` for old keys that cannot be recovered (use `key_prefix`). - key_prefix (string): First three parts of the key, safe to show. - package_code (string): Package of the key. - hours (integer | null): Hours granted by the key. - status (string (free | redeemed | revoked | suspended)): `free` (not redeemed yet), `redeemed`, `revoked` or `suspended`. - batch_id (string | null): Purchase batch that created the key. - created_at (string): Creation time. - redeemed_at (string | null): When a customer redeemed it. #### POST /keys — Buy keys Debits the wholesale price from your balance and creates the keys in one atomic operation. If the balance is not enough, nothing is charged or created (`402 insufficient_balance`). Up to 100 keys and 50 items per request. The response contains the full text of every key. Rate limit: 30 per minute, per API key. Parameters: - Idempotency-Key [header, string, required]: Unique key per operation (a UUID is ideal), 1 to 255 visible ASCII characters. Retrying with the same key never charges twice. Body (JSON): - items [PurchaseItem[], required]: What to buy: 1 to 50 objects `{package_code, quantity}`, each package at most once. - items[].package_code [string, required]: Package code from `GET /packages`. - items[].quantity [integer, optional]: Number of keys, 1 to 100. Default 1. For a single package you can also send `{"package_code": "H150", "quantity": 10}` instead of `items`. Request examples: curl: ```bash curl -X POST https://evolutionboost.xyz/api/v1/keys \ -H "Authorization: Bearer $EVB_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"items":[{"package_code":"H150","quantity":2},{"package_code":"H600","quantity":1}]}' ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/keys', { method: 'POST', headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID(), // reuse it only to retry this same call }, body: JSON.stringify({ "items": [ { "package_code": "H150", "quantity": 2 }, { "package_code": "H600", "quantity": 1 } ] }), }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import uuid import requests response = requests.post( "https://evolutionboost.xyz/api/v1/keys", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", "Idempotency-Key": str(uuid.uuid4()), # reuse it only to retry this same call }, json={ "items": [ { "package_code": "H150", "quantity": 2 }, { "package_code": "H600", "quantity": 1 } ] }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 201 — The batch was bought. ```json { "object": "key_batch", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "total_cents": 2097, "balance_cents": 122903, "currency": "BRL", "keys": [ { "object": "key", "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "key": "ACME-H150-AAAA-AAAA-AAAA-AAAA", "key_prefix": "ACME-H150-AAAA", "package_code": "H150", "hours": 150, "status": "free", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "created_at": "2026-10-17T14:10:03.000Z", "redeemed_at": null }, { "object": "key", "id": "6e7f8a9b-0c1d-4e2f-9a3b-4c5d6e7f8a9b", "key": "ACME-H150-BBBB-BBBB-BBBB-BBBB", "key_prefix": "ACME-H150-BBBB", "package_code": "H150", "hours": 150, "status": "free", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "created_at": "2026-10-17T14:10:03.000Z", "redeemed_at": null }, { "object": "key", "id": "b4c5d6e7-f8a9-4b0c-8d1e-2f3a4b5c6d7e", "key": "ACME-H600-CCCC-CCCC-CCCC-CCCC", "key_prefix": "ACME-H600-CCCC", "package_code": "H600", "hours": 600, "status": "free", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "created_at": "2026-10-17T14:10:03.000Z", "redeemed_at": null } ] } ``` HTTP 200 — Retry with the same `Idempotency-Key` and body: the original batch, nothing charged again. Idempotent-Replayed: `true` when the response is a replay. (same body as the response above) Errors: - 400 idempotency_key_required: POST without the `Idempotency-Key` header. - 400 invalid_idempotency_key: `Idempotency-Key` must have 1 to 255 visible ASCII characters, no spaces. - 400 invalid_json: The body is empty, is not JSON or is not a JSON object. - 400 missing_items: Send `items` (non-empty) or `package_code`. - 400 invalid_items: `items` must be an array of objects. - 400 too_many_items: `items` accepts at most 50 entries. - 400 invalid_package_code: `package_code` must look like `H150` (1 to 20 letters or digits). - 400 invalid_quantity: `quantity` must be an integer between 1 and 100. - 400 duplicate_package: The same package appears twice in `items`. Merge the quantities. - 400 too_many_keys: A request can create at most 100 keys in total. - 400 package_unavailable: The package does not exist or has no wholesale price. See `GET /packages`. - 402 insufficient_balance: The balance does not cover the total of the purchase. Nothing was charged or created. - 409 idempotency_key_reused: The `Idempotency-Key` was already used with a different body. Use a new key for a new operation. - 413 payload_too_large: The body is larger than 24000 bytes. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. #### GET /keys — List keys Lists your keys, newest first. Paginated. Filter by status (`free` = not redeemed yet), package or purchase batch. Responses that include the key text are audited. Rate limit: 120 per minute, per API key. Parameters: - limit [query, integer, optional]: Number of objects to return, between 1 and 100. Default 20. - starting_after [query, string, optional]: Cursor: the `id` of the last object of the previous page. Returns the objects that come after it. - status [query, string (free | redeemed | all), optional]: `free` (not redeemed), `redeemed` or `all` (default; also includes revoked and suspended keys). - package_code [query, string, optional]: Only keys of this package. - batch_id [query, string, optional]: Only keys of this purchase batch. Request examples: curl: ```bash curl "https://evolutionboost.xyz/api/v1/keys?status=free&package_code=H150&limit=50" \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/keys?status=free&package_code=H150&limit=50', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/keys?status=free&package_code=H150&limit=50", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — A page of keys. ```json { "object": "list", "data": [ { "object": "key", "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "key": "ACME-H150-AAAA-AAAA-AAAA-AAAA", "key_prefix": "ACME-H150-AAAA", "package_code": "H150", "hours": 150, "status": "free", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "created_at": "2026-10-17T14:10:03.000Z", "redeemed_at": null }, { "object": "key", "id": "6e7f8a9b-0c1d-4e2f-9a3b-4c5d6e7f8a9b", "key": "ACME-H150-BBBB-BBBB-BBBB-BBBB", "key_prefix": "ACME-H150-BBBB", "package_code": "H150", "hours": 150, "status": "free", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "created_at": "2026-10-17T14:10:03.000Z", "redeemed_at": null } ], "has_more": true } ``` Errors: - 400 invalid_limit: `limit` must be an integer between 1 and 100. - 400 invalid_cursor: `starting_after` is not a UUID or is not an object of this list. - 400 invalid_status: Unknown value in the `status` filter. - 400 invalid_package_code: `package_code` must look like `H150` (1 to 20 letters or digits). - 400 invalid_batch_id: `batch_id` must be a UUID. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable. #### GET /keys/{id} — Retrieve a key Returns one key by its `id` (UUID). To check whether a key you sold was redeemed, take its `id` from `GET /keys`: the key text never goes in the URL, where proxies and logs could record it. A key of another reseller, an unknown id or a malformed value all return the same 404. Responses that include the key text are audited. Rate limit: 120 per minute, per API key. Parameters: - id [path, string, required]: Key id (UUID), as returned by GET /keys or POST /keys. Request examples: curl: ```bash curl https://evolutionboost.xyz/api/v1/keys/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d \ -H "Authorization: Bearer $EVB_API_KEY" ``` Node.js: ```js const response = await fetch('https://evolutionboost.xyz/api/v1/keys/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d', { headers: { Authorization: `Bearer ${process.env.EVB_API_KEY}`, }, }); const data = await response.json(); if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`); console.log(data); ``` Python: ```python import os import requests response = requests.get( "https://evolutionboost.xyz/api/v1/keys/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", headers={ "Authorization": f"Bearer {os.environ['EVB_API_KEY']}", }, timeout=30, ) data = response.json() if not response.ok: raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}") print(data) ``` Responses: HTTP 200 — The key. ```json { "object": "key", "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "key": "ACME-H150-AAAA-AAAA-AAAA-AAAA", "key_prefix": "ACME-H150-AAAA", "package_code": "H150", "hours": 150, "status": "redeemed", "batch_id": "d2a7f3c1-4b5e-4f60-9a8b-7c6d5e4f3a21", "created_at": "2026-10-17T14:10:03.000Z", "redeemed_at": "2026-10-17T18:22:09.000Z" } ``` Errors: - 404 resource_missing: The object does not exist or belongs to another reseller (same answer), or the endpoint does not exist. Plus the common errors: invalid_api_key, reseller_inactive, rate_limit_exceeded, method_not_allowed, internal_error, service_unavailable.