{
    "openapi": "3.1.1",
    "info": {
        "title": "Cytrongift API",
        "version": "1.2.1",
        "description": "Browse the buy-back catalogue, sell gift cards and game keys, request payouts and manage your [Cytrongift](https://cytrongift.com/) account through a JSON API.\n\n## Base address\n\n`https://api.cytrongift.com/v1`. Add any endpoint path below to this URL. The same API with test money lives at `https://sandbox.cytrongift.com/v1`, see [Sandbox](#sandbox).\n\n## Envelope\n\nSuccessful requests return `{ \"ok\": 1, \"data\": { } }`. Errors return `{ \"ok\": 0, \"error\": { \"id\": \"3003\", \"code\": 401, \"desc\": \"\", \"advice\": \"\", \"extra\": { } } }`.\n\n`error.code` matches the HTTP status. `desc` explains what went wrong; `advice` tells you what to do next. Both follow `Accept-Language`; use `ru` for Russian. Error ids fall into three groups: 3xxx for authentication and limits, 4xxx for business rules, and 5xxx for transport and service errors.\n\n> [!NOTE] Handle errors by id\n> Use `error.id` in your code. The wording of `desc` and `advice` may change between releases, but the id stays the same.\n\n## Authentication\n\nStart in [Apps & API](https://cytrongift.com/en/account/apps/) in your Cytrongift account. Request access, wait for the approval email, then create a key. You get a public **Key ID** (`ck_...`) and a **Secret** (`cs_...`). The secret is shown only once.\n\nTo sign a request, send these three headers:\n\n```text\nX-Api-Key: ck_...\nX-Timestamp: 1788605154\nX-Signature: hex( hmac_sha256( METHOD + \"\\n\" + PATH + \"\\n\" + TIMESTAMP + \"\\n\" + RAW_BODY, secret ) )\n```\n\n- `PATH` is the endpoint path without `/v1` or the query string, for example `/account/balance`.\n- `TIMESTAMP` is Unix time in seconds. It must be within 300 seconds of the server clock, or you get `3002`.\n- `RAW_BODY` is the exact body you send, byte for byte. Use an empty string for `multipart/form-data`.\n\nYou can also call `POST /auth` with a signed request to get a Bearer token. Send it as `Authorization: Bearer ...` on endpoints that accept either authentication method. The token lasts up to a day and stays linked to the application that created it.\n\n> [!WARNING] Keep the secret on your backend\n> Save it when you create the key; you cannot view it again. Never put it in browser code or a mobile app bundle. Lost it? Rotate the key in [Apps & API](https://cytrongift.com/en/account/apps/). The old key keeps working for 24 hours, giving you time to update your integration.\n\nEach application has a set of approved **scopes**. Check the scope listed for the endpoint you want to call. Without it, the request returns `3014`. A paused or disabled application returns `3013`; a revoked or expired key returns `3012`.\n\n## Limits\n\nThe default limit is 60 requests per minute. An application can have a higher limit; requests are counted per key, before authentication. Exceed the limit and you get HTTP `429`, error `3011`, and a `Retry-After` header. Every answer carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (seconds left in the current minute), so a client can pace itself before the refusal.\n\n> [!TIP] Wait before retrying\n> Wait the number of seconds in `Retry-After` before trying again. Retrying in a tight loop will keep hitting the limit. Need a higher limit? Send support your application name.\n\nDuring maintenance, every endpoint except `/health` returns HTTP `503` with error `5008`.\n\n## Content types and pagination\n\nFor `POST` and `PATCH`, send `application/json`; an unsupported content type returns `4000`. The exception is `POST /uploads/images`, which takes `multipart/form-data`. `GET` requests need no `Content-Type`.\n\nList endpoints use cursor pagination: `?cursor=123&limit=20`. The response includes `items`, `limit`, `cursor`, `next_cursor` and `filters`. Use `next_cursor` for the next page; `null` means you have reached the end. Catalogue lists run from lower to higher ids. Account and withdrawal lists run from higher to lower ids.\n\n## Webhooks\n\nRegister up to 5 https addresses with `POST /account/webhooks`; the answer shows the `secret` once. Each finished sale or payout and each decision on your application is delivered as one JSON POST: `event` (`order.completed`, `order.rejected`, `withdrawal.completed`, `withdrawal.rejected`, `application.approved`, `application.rejected`, `application.paused`), `entity`, `id`, `status`, `amount` and `currency` for money events, `name` and `reason` for application events, `user_id` and `at`. The headers `X-Event` and `X-Delivery-Id` repeat the event and the delivery number; `X-Signature` is `hmac_sha256(body, secret)` in hex. Verify it before you act.\n\nAnswer `2xx` within 10 seconds. A `5xx`, a timeout or a connection failure is retried with growing delays, 5 attempts at most; a `410` switches the address off; any other `4xx` drops that delivery. Deliveries are at least once: keep the delivery id and skip one you have already handled.\n\n## Money\n\nAmounts use the site currency (USD), with up to two decimal places. Catalogue prices are different: each `price` uses the item's `currency_id`. To convert it to a payout in site currency, use `price / payments[currency_id].rate`.\n\n\n## Sandbox\n\n`https://sandbox.cytrongift.com/v1`. The same API against a separate database with test money: every path, envelope, signature rule and error id is the one above. Only the address and the key differ, so a client built here runs on the live address after a change of base URL and key pair.\n\n### Get access\n\n1. Open [Apps & API](https://cytrongift.com/en/account/apps/) in your Cytrongift account and request API access, exactly as for the live API. One approval covers both addresses.\n2. Once the application is approved, press **Sandbox key** on the same page. You get a Key ID that starts with `cks_` and a Secret (`cs_...`) shown once; the live key stays separate.\n3. Point your client at the sandbox address and sign requests the usual way. The example clients take the base URL as their first argument:\n\n```bash\nCYTRON_API_KEY=cks_... CYTRON_API_SECRET=cs_... php client.php https://sandbox.cytrongift.com/v1\n```\n\n4. Call `GET /health`: on the sandbox it reports `\"sandbox\": true`, and every sandbox answer carries the header `X-Sandbox: 1`.\n\n> [!WARNING] One key per address\n> A sandbox key on the live address, or a live key on the sandbox, answers `401` with error `3016`. Keep the two key pairs apart in your configuration and switch both together with the base URL.\n\n### What is different\n\n| Area | On the sandbox |\n|---|---|\n| Balance | Every account starts with **1000 USD** of test money. No money moves and nothing is reviewed by a person. |\n| Orders and payouts | Settled by the sandbox itself **two minutes** after creation: most complete, **every third is rejected**, so both outcomes can be rehearsed. |\n| Catalogue | Brands, platforms, cards, keys, payout methods and prices are a **daily copy** of the live ones. |\n| Account data | Members, orders and payouts of the live site are never there; the sandbox account is a twin with the same ID. |\n| Webhooks | The same deliveries as on the live API, signed the same way, with one more header: `X-Sandbox: 1`. |\n| Limits | **60 requests a minute**, not raised. Uploads, tokens and the rest of the account endpoints work as on the live address. |\n\n> [!TIP] Rehearse both outcomes\n> Create three orders, register a webhook address and wait two minutes: two orders complete and one is rejected, so your handler sees `order.completed` and `order.rejected` with the `X-Sandbox: 1` header before it ever meets live money.\n",
        "contact": {
            "name": "Cytrongift support",
            "url": "https://cytrongift.com/en/support/"
        },
        "x-changelog": [
            {
                "version": "1.2.1",
                "date": "2026-10-30",
                "changes": [
                    "`GET /catalog/country2data` is now `GET /catalog/countries`; the old path answers `404` with error `5005`.",
                    "`GET /config`: the `links.news` entry is now `links.blog`.",
                    "The Sandbox chapter of the guide is a step-by-step walkthrough; the documentation page links every Apps & API mention to the account page."
                ]
            },
            {
                "version": "1.2.0",
                "date": "2026-10-30",
                "changes": [
                    "Sandbox: the same API at `https://sandbox.cytrongift.com/v1` with test money, settled by itself; a sandbox key (`cks_`) comes from the Apps & API page of an approved application, see the Sandbox chapter of the guide.",
                    "`GET /health` reports `sandbox` (true on the sandbox address) and every sandbox answer and webhook carries the `X-Sandbox: 1` header.",
                    "Error `3016`: a key used on the other address answers `401` instead of an unknown-key refusal."
                ]
            },
            {
                "version": "1.1.0",
                "date": "2026-10-29",
                "changes": [
                    "Webhooks: register up to five https addresses with `POST /account/webhooks`, list them with `GET /account/webhooks` and drop one with `POST /account/webhooks/delete`; every delivery is signed with the secret shown once.",
                    "Application decisions reach your Telegram chat and webhooks as `application.approved`, `application.rejected` and `application.paused`, beside the finished orders and payouts.",
                    "Every answer carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`, so a client can pace itself before a `429`.",
                    "The documentation page gained the Webhooks chapter, the Changelog, the error table in JSON, CSV and XML, and the clients as one download."
                ]
            }
        ]
    },
    "servers": [
        {
            "url": "https://api.cytrongift.com/v1",
            "description": "Live"
        },
        {
            "url": "https://sandbox.cytrongift.com/v1",
            "description": "Sandbox: test money, no reviews, keys from the same cabinet"
        }
    ],
    "tags": [
        {
            "name": "Service",
            "description": "Check service health, read configuration and look up bonus tiers."
        },
        {
            "name": "Catalogue",
            "description": "Browse the cards and game keys we buy, plus the available payout methods. These endpoints are public."
        },
        {
            "name": "Auth",
            "description": "Create, refresh and revoke tokens for API access."
        },
        {
            "name": "Account",
            "description": "Read your balance, orders and bonus level, update your profile, manage webhooks."
        },
        {
            "name": "Uploads",
            "description": "Upload card and receipt photos before attaching them to an order."
        },
        {
            "name": "Sell",
            "description": "Create orders to sell gift cards and game keys."
        },
        {
            "name": "Withdrawals",
            "description": "Request payouts and check their status and history."
        },
        {
            "name": "Support",
            "description": "Create support tickets you can also follow in your account."
        }
    ],
    "security": [
        {
            "HmacSignature": []
        },
        {
            "BearerToken": []
        }
    ],
    "paths": {
        "/health": {
            "get": {
                "tags": [
                    "Service"
                ],
                "summary": "Health check",
                "description": "Checks the database and cache. Returns `200` when both respond, or `503` if either check fails.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "status": "ok",
                                        "service": "cytrongift-api",
                                        "version": "1.2.1",
                                        "sandbox": false,
                                        "timestamp": 1788605154,
                                        "checks": {
                                            "database": "ok",
                                            "cache": "ok"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "503": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": []
            }
        },
        "/config": {
            "get": {
                "tags": [
                    "Service"
                ],
                "summary": "Service configuration",
                "description": "Returns service metadata, the allowed values used by write endpoints, and public website links. The `links` object includes support, developer, news and agreement URLs for each language.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "service": "cytrongift-api",
                                        "version": "1.2.1",
                                        "currency_code": "USD",
                                        "currency_symbol": "$",
                                        "languages": [
                                            "en",
                                            "ru"
                                        ],
                                        "card_types": {
                                            "ALL": 0,
                                            "ECODE": 1,
                                            "PCARD": 2
                                        },
                                        "order_status": {
                                            "PROCESSING": 0,
                                            "COMPLETE": 1,
                                            "REJECTED": 2,
                                            "UNDER_REVIEW": 3
                                        },
                                        "signature_window": 300,
                                        "rate_limit_minute": 60,
                                        "timestamp": 1788605157,
                                        "links": {
                                            "support": "https://cytrongift.com/en/support/",
                                            "developer": "https://api.cytrongift.com/docs/",
                                            "blog": {
                                                "en": "https://cytrongift.com/en/blog/",
                                                "ru": "https://cytrongift.com/ru/blog/"
                                            },
                                            "agreement": {
                                                "en": "https://cytrongift.com/en/pages/terms.html",
                                                "ru": "https://cytrongift.com/ru/pages/terms.html"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/bonus": {
            "get": {
                "tags": [
                    "Service"
                ],
                "summary": "Bonus tiers",
                "description": "Returns the public table of bonus tiers.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "levels": [
                                            {
                                                "level": 1,
                                                "threshold": 10000,
                                                "bonus_percent": 0.05
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/catalog/brands": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Brands",
                "description": "Lists brands with at least one gift card currently accepted for sale. Each item includes `id`, `name_ru`, `name_en`, `icon` and `sort`. The `icon` is an absolute URL, or an empty string if no icon is set.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "id": 1,
                                                "name_ru": "Amazon",
                                                "name_en": "Amazon",
                                                "icon": "https://cytrongift.com/uploads/brands/amazon.svg",
                                                "sort": 1
                                            }
                                        ],
                                        "total": 1
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/catalog/platforms": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Platforms",
                "description": "Lists platforms with at least one game currently accepted for sale. Each item includes `id`, `name_ru`, `name_en`, `icon`, `receipt_required` and `sort`.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "id": 1,
                                                "name_ru": "Steam",
                                                "name_en": "Steam",
                                                "icon": "",
                                                "receipt_required": false,
                                                "sort": 1
                                            }
                                        ],
                                        "total": 1
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/catalog/payments": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Payout methods",
                "description": "Returns payout methods and the exchange rates used to calculate payouts. Each item includes `id`, `code`, `currency`, `network`, `name_ru`, `name_en`, `icon`, `example`, `rate`, `rate_date`, `round`, `needs_fio` and `sort`.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "id": 2,
                                                "code": "BTC",
                                                "currency": "BTC",
                                                "network": "",
                                                "name_ru": "Bitcoin",
                                                "name_en": "Bitcoin",
                                                "icon": "",
                                                "example": "1A1zP1...",
                                                "rate": 79728.1,
                                                "rate_date": 1788605000,
                                                "round": 8,
                                                "needs_fio": false,
                                                "sort": 1
                                            }
                                        ],
                                        "total": 1
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/catalog/cards": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Gift cards",
                "description": "Returns a paginated list of gift cards. Each item includes `id`, `name_ru`, `name_en`, `icon`, `price`, `currency_id`, `country_id`, `brand_id` and `sort`. The `price` is in the currency identified by `currency_id`.",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "query",
                        "description": "Filter by brand id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "country_id",
                        "in": "query",
                        "description": "Filter by country id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Match part of the item name.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "description": "Return items with ids greater than this cursor.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Items per page: 1 to 500.",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "id": 1,
                                                "name_ru": "Amazon 100 USD",
                                                "name_en": "Amazon 100 USD",
                                                "icon": "",
                                                "price": 85,
                                                "currency_id": 1,
                                                "country_id": 9,
                                                "brand_id": 1,
                                                "sort": 0
                                            }
                                        ],
                                        "limit": 50,
                                        "cursor": 0,
                                        "next_cursor": null,
                                        "filters": {
                                            "brand_id": null,
                                            "country_id": null,
                                            "search": ""
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/catalog/games": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Game keys",
                "description": "Returns a paginated list of game keys. Items have the same fields as gift cards, with `platform_id` instead of `brand_id`.",
                "parameters": [
                    {
                        "name": "platform_id",
                        "in": "query",
                        "description": "Filter by platform id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "country_id",
                        "in": "query",
                        "description": "Filter by country id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "description": "Match part of the item name.",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "description": "Return items with ids greater than this cursor.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Items per page: 1 to 500.",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [],
                                        "limit": 50,
                                        "cursor": 0,
                                        "next_cursor": null,
                                        "filters": []
                                    }
                                }
                            }
                        }
                    }
                },
                "security": []
            }
        },
        "/catalog/countries": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Countries by brand or platform",
                "description": "Pass either `platform_id` or `brand_id`; omitting both returns `4012`. If you send both, `platform_id` takes priority.\n\nEach item includes `country_id`, `title` in the requested language, `code` (a lowercase ISO 3166-1 alpha-2 code) and `flag`.",
                "parameters": [
                    {
                        "name": "brand_id",
                        "in": "query",
                        "description": "Brand id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "platform_id",
                        "in": "query",
                        "description": "Platform id.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "country_id": 9,
                                                "title": "USA",
                                                "code": "us",
                                                "flag": "/templates/frontend/cytron/images/flags/us.svg"
                                            }
                                        ],
                                        "total": 1,
                                        "filters": {
                                            "brand_id": 1
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": []
            }
        },
        "/auth": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Get a bearer token",
                "description": "Sign this request with your application key. An existing token cannot be used to create another one.\n\nThe token stays linked to the application that signed the request. `ttl` is limited to 300 through 86400 seconds; if omitted, the site default applies.",
                "requestBody": {
                    "required": false,
                    "description": "Optional.",
                    "content": {
                        "application/json": {
                            "example": {
                                "ttl": 3600
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "token_type": "Bearer",
                                        "access_token": "eyJ...",
                                        "expires_in": 3600,
                                        "expires_at": 1788608789,
                                        "merchant_id": 8269
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "503": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    }
                ]
            }
        },
        "/account/balance": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Balance",
                "description": "Returns your current account balance, read directly from the account record.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "balance": 250,
                                        "referrals_earned": 0,
                                        "referrals_count": 0,
                                        "currency_code": "USD",
                                        "currency_symbol": "$"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "account:read"
            }
        },
        "/account/bonus": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Bonus level",
                "description": "Returns your bonus level based on completed payouts. `next_level` is `null` if you have reached the highest tier.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "user": {
                                            "id": 8269,
                                            "login": "seller",
                                            "fullname": "",
                                            "email": "s@example.com"
                                        },
                                        "current": {
                                            "level": 0,
                                            "bonus_percent": 0,
                                            "unlock_amount": 10000,
                                            "progress_to_next": 0,
                                            "next_level": 1
                                        },
                                        "levels": [
                                            {
                                                "level": 1,
                                                "threshold": 10000,
                                                "bonus_percent": 0.05
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "account:read"
            }
        },
        "/account/analytics": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Order totals",
                "description": "Returns order totals grouped by status. `processing` includes statuses 0 and 3.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "complete": {
                                            "amount": 0,
                                            "quantity": 0,
                                            "orders": 0
                                        },
                                        "processing": {
                                            "amount": 0,
                                            "quantity": 0,
                                            "orders": 0
                                        },
                                        "rejected": {
                                            "amount": 0,
                                            "quantity": 0,
                                            "orders": 0
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "account:read"
            }
        },
        "/account/transactions": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Orders",
                "description": "Returns your orders, newest first. Pass `id` to fetch a single order directly in `data`, without the list wrapper. If the order does not belong to your account, you get `4007`.\n\nEach item includes `id`, `uuid`, `type`, `status` (`processing|complete|rejected|under_review`), `status_id`, `gift_id`, `brand_id`, `country_id`, `item`, `amount`, `total`, `net_total`, `quantity`, `cards_type`, `cards_list`, `user_images`, `receipt_images`, `user_comment`, `admin_comment`, `date_create`, `date_created` and `date_complete`.\n\nEach image entry includes a `url` pointing to `GET /account/order-image`.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "description": "Return one order directly in `data`, without the list wrapper.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "description": "`cards` or `games`",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "description": "Return items with ids less than this cursor.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Items per page: 1 to 200.",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [],
                                        "limit": 20,
                                        "cursor": 0,
                                        "next_cursor": null,
                                        "filters": {
                                            "type": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:read"
            }
        },
        "/account/order-image": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Order image",
                "description": "Streams an order image as `image/webp` with `Cache-Control: private, no-store`. Use the `token` from the image's `url`; no other image identifier is needed. If it does not identify an image in your account, you get `4007`.",
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "description": "The token from the image URL.",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The image as a binary WebP response.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": []
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:read"
            }
        },
        "/account/settings": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Profile settings",
                "description": "Returns your profile fields.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "id": 8269,
                                        "login": "seller",
                                        "email": "s@example.com",
                                        "email_verified": false,
                                        "firstname": "",
                                        "lastname": "",
                                        "fullname": "",
                                        "country": "USA",
                                        "country_id": 9,
                                        "city": "Berlin",
                                        "telegram": "seller",
                                        "whatsapp": "",
                                        "phone": "",
                                        "userpic": ""
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "account:read"
            },
            "patch": {
                "tags": [
                    "Account"
                ],
                "summary": "Update profile settings",
                "description": "Send only the fields you want to change: `phone`, `whatsapp`, `fullname`, `city`, `telegram` or `country_id`. An empty object returns `4012`.\n\nPhone fields accept 10 to 13 digits or an empty value. Names accept letters, spaces, apostrophes and hyphens, with a length of 2 to 128 characters. A leading `@` is removed from `telegram`; the remaining value must match `[a-zA-Z0-9_]{3,32}`. Use a `country_id` from `/catalog/country2data`.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "city": "Berlin",
                                "telegram": "@seller"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "updated": true,
                                        "settings": {
                                            "id": 8269,
                                            "city": "Berlin"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "profile:write"
            }
        },
        "/account/webhooks": {
            "get": {
                "tags": [
                    "Account"
                ],
                "summary": "Webhooks",
                "description": "Lists the delivery addresses of your account with the events they receive. The secret is never shown again; register the address again to get a new one.",
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "id": 12,
                                                "url": "https://partner.example.com/cytrongift/hook",
                                                "enabled": true,
                                                "events": [
                                                    "order.completed",
                                                    "order.rejected",
                                                    "withdrawal.completed",
                                                    "withdrawal.rejected",
                                                    "application.approved",
                                                    "application.rejected",
                                                    "application.paused"
                                                ],
                                                "created_at": 1788605154
                                            }
                                        ],
                                        "limit": 5
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "account:read"
            },
            "post": {
                "tags": [
                    "Account"
                ],
                "summary": "Add a webhook",
                "description": "Registers an https address for the events listed under Webhooks in the guide. The answer carries the `secret` once; registering an address you already hold issues a new secret for it. An address held by another account returns `4008`, an invalid one `4082`, the sixth address `4085`.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "url": "https://partner.example.com/cytrongift/hook"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "id": 12,
                                        "url": "https://partner.example.com/cytrongift/hook",
                                        "enabled": true,
                                        "events": [
                                            "order.completed",
                                            "order.rejected",
                                            "withdrawal.completed",
                                            "withdrawal.rejected",
                                            "application.approved",
                                            "application.rejected",
                                            "application.paused"
                                        ],
                                        "created_at": 1788605154,
                                        "secret": "7f3a...c9e1"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "profile:write"
            }
        },
        "/account/webhooks/delete": {
            "post": {
                "tags": [
                    "Account"
                ],
                "summary": "Delete a webhook",
                "description": "Drops one address of your account; deliveries still waiting for it are cancelled. An unknown id, or one held by another account, returns `4007`.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "id": 12
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "id": 12,
                                        "deleted": true
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "profile:write"
            }
        },
        "/uploads/images": {
            "post": {
                "tags": [
                    "Uploads"
                ],
                "summary": "Upload images",
                "description": "Upload card or receipt photos as `multipart/form-data`. For the HMAC signature, use an empty body.\n\nSend `type` as `card` or `receipt` (default: `card`), plus up to 10 images in `files[]`. For a single image, you can also use `file`. JPEG, PNG, GIF and WebP are accepted; the format is checked from the file contents. Each image must fit within the site's upload size limit.\n\nImages are converted to WebP, with the longest side limited to 2048 px. Originals are not kept. Attach the uploaded images to an order within 24 hours; unused uploads are deleted after that.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "card",
                                            "receipt"
                                        ]
                                    },
                                    "files[]": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [
                                            {
                                                "upload_id": "941c...29f",
                                                "type": "card",
                                                "mime": "image/webp",
                                                "size": 13352,
                                                "w": 2048,
                                                "h": 1365,
                                                "created_at": 1788605305
                                            }
                                        ],
                                        "total": 1
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "415": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:write"
            }
        },
        "/uploads/delete": {
            "post": {
                "tags": [
                    "Uploads"
                ],
                "summary": "Delete an unused upload",
                "description": "Deletes an upload before it is attached to an order. An attached file returns `4066`, an upload owned by another account returns `4008`, and an unknown id returns `4007`.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "upload_id": "941c...29f"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "upload_id": "941c...29f",
                                        "deleted": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:write"
            }
        },
        "/sell/cards": {
            "post": {
                "tags": [
                    "Sell"
                ],
                "summary": "Sell gift cards",
                "description": "Creates a gift card order with status 0. Set `type` to 0 for any form, 1 for an e-code, or 2 for a physical card. The `gift_id` must be available for sale and match `brand_id` and `country_id`; a mismatch returns `4063`.\n\nSet `quantity` from 1 to 1000. You can add a `comment` of up to 1000 characters. In `cards`, send one code per line, with 4 to 92 characters per code. Codes are required unless `type` is 2; physical cards require `card_upload_ids` instead. Missing card data returns `4064`. Uploads must belong to your account, match the required type and be unused by any other order.\n\nIn the response, `amount` is the payout per item, `total` includes the bonus for the whole order, and `net_total` is the total before the bonus.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "type": 1,
                                "country_id": 9,
                                "brand_id": 1,
                                "gift_id": 1,
                                "quantity": 2,
                                "comment": "",
                                "cards": "CODE-1\\nCODE-2",
                                "card_upload_ids": [],
                                "receipt_upload_ids": []
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "order_id": 75791,
                                        "uuid": "455f...",
                                        "status": 0,
                                        "amount": 3.75,
                                        "total": 7.5,
                                        "net_total": 0,
                                        "quantity": 2,
                                        "files": {
                                            "cards": [],
                                            "receipts": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "409": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:write"
            }
        },
        "/sell/games": {
            "post": {
                "tags": [
                    "Sell"
                ],
                "summary": "Sell game keys",
                "description": "Works like `/sell/cards`, using `platform_id` instead of `brand_id`. If the platform has `receipt_required` enabled, include `receipt_upload_ids`; missing receipts return `4012`.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "type": 1,
                                "country_id": 9,
                                "platform_id": 1,
                                "gift_id": 1,
                                "quantity": 1,
                                "cards": "KEY-1",
                                "receipt_upload_ids": []
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "order_id": 75792,
                                        "uuid": "9a1c...",
                                        "status": 0,
                                        "amount": 12,
                                        "total": 12,
                                        "net_total": 0,
                                        "quantity": 1,
                                        "files": {
                                            "cards": [],
                                            "receipts": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    },
                    "409": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:write"
            }
        },
        "/withdrawal/create": {
            "post": {
                "tags": [
                    "Withdrawals"
                ],
                "summary": "Request a payout",
                "description": "Set `amount` to a positive number with up to 2 decimal places. It is deducted from your balance as soon as the request is created. Use `amount_type` 0 for your main balance or 1 for your referral balance.\n\nChoose a `method_id` from `/catalog/payments` with a current rate. The `wallet` must match the method's format, or you get `4053`. Include `fio` if the method has `needs_fio` enabled.\n\nUse `request_id` to make retries safe. It must match `[a-zA-Z0-9_-]{16,128}`. Repeating the same request with the same id returns the original record with `duplicate: true`. Reusing that id with different content returns HTTP `409` with error `4065`. If you omit the field, you can pass the value in the `Idempotency-Key` header instead.\n\nIf your balance is too low, you get `4054`, with `available` and `requested` amounts in `extra`.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "amount": 10.5,
                                "method_id": 2,
                                "wallet": "1A1zP1...",
                                "fio": "John Doe",
                                "amount_type": 0,
                                "request_id": "wd_01K1A8T4S7Q2M5N9P3R6"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "id": 15870,
                                        "uuid": "f28f...",
                                        "status": 0,
                                        "amount": 10.5,
                                        "amount_converted": 0.00013169,
                                        "amount_type": 0,
                                        "method_id": 2,
                                        "wallet": "1A1zP1...",
                                        "date_create": 1788605258,
                                        "request_id": "wd_01K1A8T4S7Q2M5N9P3R6",
                                        "duplicate": false
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "409": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "withdrawals:write"
            }
        },
        "/withdrawal/transactions": {
            "get": {
                "tags": [
                    "Withdrawals"
                ],
                "summary": "Payout history",
                "description": "Returns your payouts, newest first. Each item includes `id`, `uuid`, `type`, `status` (`processing|complete|rejected`), `status_id`, `amount`, `amount_converted`, `amount_type`, `wallet`, `fio`, `tx_out`, `date_create`, `date_result` and `method`.\n\nThe `method` object contains `id`, `currency`, `name_ru` and `name_en` as they were when the payout was created.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "query",
                        "description": "Return one payout directly in `data`, without the list wrapper.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "description": "`main` or `referral`",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "description": "Return items with ids less than this cursor.",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Items per page: 1 to 200.",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "items": [],
                                        "limit": 20,
                                        "cursor": 0,
                                        "next_cursor": null,
                                        "filters": {
                                            "type": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "orders:read"
            }
        },
        "/support/create": {
            "post": {
                "tags": [
                    "Support"
                ],
                "summary": "Create a support ticket",
                "description": "Creates a ticket you can also follow in your account on the website. If you omit `name` or `email`, the values from your profile are used.\n\nThe `subject` must be 3 to 64 characters; the `message`, 20 to 8192. The same flood protection as on the website applies (`3011`). The response includes `code` for guest access to the conversation.",
                "requestBody": {
                    "required": true,
                    "description": "",
                    "content": {
                        "application/json": {
                            "example": {
                                "subject": "Question",
                                "message": "At least twenty characters of text.",
                                "name": "John Doe",
                                "email": "john@example.com",
                                "lang": "en"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "ticket_id": 1888,
                                        "code": "b296...",
                                        "status": 0,
                                        "name": "John Doe",
                                        "email": "john@example.com",
                                        "subject": "Question",
                                        "date": 1788605297
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    },
                    {
                        "BearerToken": []
                    }
                ],
                "x-scope": "support:write"
            }
        },
        "/auth/identity": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Get tokens for a verified user",
                "description": "For first-party applications only: kind `first_party`, scope `identity:assert`. Sign the request with the application key.\n\nBefore calling this endpoint, verify the provider's credentials on your own server: for example, Telegram `initData` with the bot token, or a Discord OAuth code. The API looks up the account by `provider` and `provider_uid`. If none exists, it creates one from `profile` (`first_name`, `last_name`, `username`, `photo_url`, `language_code`) and applies `referral_code` to the new account.\n\nThe response contains an opaque token pair for the user. You can pass a `device` label of up to 64 characters. `ttl` is limited to 300 through 86400 seconds for the access token. The token inherits the application's scopes except `identity:assert`.\n\nIf the Telegram id is still linked to a legacy account, you get `4084` with `link_required`. The user needs to link that account on the website first.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "example": {
                                "provider": "telegram",
                                "provider_uid": "123456789",
                                "profile": {
                                    "first_name": "Ada",
                                    "last_name": "",
                                    "username": "ada",
                                    "photo_url": "",
                                    "language_code": "ru"
                                },
                                "referral_code": "ada7",
                                "device": "Mini App iPhone",
                                "ttl": 3600
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "token_type": "Bearer",
                                        "access_token": "ut_...",
                                        "expires_in": 3600,
                                        "expires_at": 1788608789,
                                        "refresh_token": "rt_...",
                                        "refresh_expires_at": 1791197189,
                                        "scopes": [
                                            "catalog:read",
                                            "account:read",
                                            "orders:read",
                                            "orders:write"
                                        ],
                                        "user": {
                                            "id": 9001,
                                            "login": "ada",
                                            "ref_code": "ada7",
                                            "created": true
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    },
                    "409": {
                        "$ref": "#/components/responses/Error"
                    },
                    "429": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "HmacSignature": []
                    }
                ],
                "x-scope": "identity:assert"
            }
        },
        "/auth/refresh": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Refresh user tokens",
                "description": "Exchanges a refresh token for a new token pair. Each refresh token works once; the old pair becomes invalid as soon as the new one is issued. A reused or revoked refresh token returns `3009`; an expired one returns `3008`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "example": {
                                "refresh_token": "rt_...",
                                "ttl": 3600
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "token_type": "Bearer",
                                        "access_token": "ut_...",
                                        "expires_in": 3600,
                                        "expires_at": 1788608789,
                                        "refresh_token": "rt_...",
                                        "refresh_expires_at": 1791197189,
                                        "scopes": [
                                            "catalog:read",
                                            "account:read",
                                            "orders:read",
                                            "orders:write"
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    },
                    "403": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": []
            }
        },
        "/auth/logout": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Revoke a user token",
                "description": "Immediately revokes the opaque user token used for this request. JWTs cannot be revoked through this endpoint and return `4082`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "example": []
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "A successful response with the result in `data`.",
                        "content": {
                            "application/json": {
                                "example": {
                                    "ok": 1,
                                    "data": {
                                        "revoked": true
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    }
                },
                "security": [
                    {
                        "BearerToken": []
                    }
                ]
            }
        }
    },
    "components": {
        "securitySchemes": {
            "HmacSignature": {
                "type": "apiKey",
                "in": "header",
                "name": "X-Api-Key",
                "description": "Your application key id. Send it with `X-Timestamp` and `X-Signature`; see Authentication for the signing steps."
            },
            "BearerToken": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT",
                "description": "A bearer token sent in the `Authorization` header."
            }
        },
        "responses": {
            "Error": {
                "description": "An error response. Use `error.id` to look up the error and what to do next.",
                "content": {
                    "application/json": {
                        "example": {
                            "ok": 0,
                            "error": {
                                "id": "3003",
                                "code": 401,
                                "desc": "Signature does not match",
                                "advice": "Sign METHOD, PATH, TIMESTAMP and the raw body, separated by newlines, with your API secret.",
                                "extra": []
                            }
                        }
                    }
                }
            }
        }
    }
}