# Evolution Boost Evolution Boost boosts Steam hours and farms trading cards 24/7 on its own servers, even with your PC off. It is for players who want to raise their playtime or collect trading card drops without keeping their computer on. Up to 32 games per Steam account, with Card Farmer (farms the games that still have card drops) and Auto Restart (reconnects when Steam drops the session). Steam accounts are added with the Steam app QR code or with login and password, with Steam Guard support. How to buy: create an account at https://evolutionboost.xyz/app and buy a plan (hour balance and Steam account limit) with PIX in the dashboard, or redeem a key bought from an authorized reseller (https://evolutionboost.xyz/en/revendedores). The balance goes down by each minute of boosting on each active account. Plans (prices in BRL, paid with PIX): 150 hours, up to 3 Steam accounts: BRL 6.99; 600 hours, up to 6 Steam accounts: BRL 14.99; 1200 hours, up to 12 Steam accounts: BRL 24.99; 2400 hours, up to 24 Steam accounts: BRL 49.99. # 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.