{"openapi":"3.1.0","info":{"title":"LittleFox Customer API","version":"1.2.0","description":"Balance, digital catalog, purchases and history. Prices can be displayed in rubles or US dollars. Your balance is charged in rubles, with precision to one kopek. Monetary fields ending in _kopeks are integers expressed in kopeks (100 = 1 RUB). Optional currency=USD converts display strings using the shared shop rate, never settlement amounts. Descriptions are portable plain text plus safe HTML. Preserve the same Idempotency-Key and body after a timeout. HTTP 202 requires polling the order. No response is not evidence of a failed purchase."},"servers":[{"url":"/api/v1"}],"security":[{"bearerAuth":[]},{"apiKey":[]}],"paths":{"/me":{"get":{"operationId":"getBalance","parameters":[{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"$ref":"#/components/schemas/Account"}}}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}}},"/products":{"get":{"operationId":"listProducts","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"lang","in":"query","schema":{"type":"string","enum":["ru","en"]}},{"name":"available","in":"query","description":"Omit or set false to include out-of-stock products. Set true for in-stock products only. Refresh the catalog periodically; restocked products retain the same ID.","schema":{"type":"boolean","default":false}},{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"type":"object","properties":{"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"items":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"page":{"type":"integer"},"limit":{"type":"integer"},"has_more":{"type":"boolean"},"total":{"type":"integer"},"pages":{"type":"integer"}}}}}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}}},"/products/{id}":{"get":{"operationId":"getProduct","parameters":[{"name":"lang","in":"query","schema":{"type":"string","enum":["ru","en"]}},{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"$ref":"#/components/schemas/Product"}}}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}}},"/orders":{"get":{"operationId":"listOrders","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"client_order_id","in":"query","schema":{"type":"string","maxLength":128}},{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"type":"object","properties":{"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"items":{"type":"array","items":{"$ref":"#/components/schemas/OrderSummary"}},"page":{"type":"integer"},"limit":{"type":"integer"},"has_more":{"type":"boolean"}}}}}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}},"post":{"operationId":"createOrder","description":"Creates a real purchase paid from the key owner's balance. Persist key and body before sending. Retry with exactly the same key/body. A new key can create a new purchase. User-scoped keys survive API key rotation. Currency changes affect response display only and do not create a second order. Always pass max_total_kopeks from exact catalog amounts; client prices and rates are rejected.","parameters":[{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[A-Za-z0-9:_-]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["product_id","quantity","max_total_kopeks"],"properties":{"product_id":{"type":"integer","minimum":1},"quantity":{"type":"integer","minimum":1,"maximum":100},"max_total_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency.","minimum":1,"maximum":100000000},"client_order_id":{"type":"string","maxLength":128}}}}}},"responses":{"200":{"description":"Existing delivered order","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"$ref":"#/components/schemas/Order"}}}}}},"201":{"description":"New delivered order","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"$ref":"#/components/schemas/Order"}}}}}},"202":{"description":"Processing or automatic result verification; poll GET /orders/{id}. Do not repurchase.","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"402":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"413":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"415":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}}},"/orders/{id}":{"get":{"operationId":"getOrder","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"$ref":"#/components/schemas/Order"}}}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}}},"/transactions":{"get":{"operationId":"listTransactions","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":30}},{"name":"currency","in":"query","description":"Display currency only, independent of lang. Default RUB preserves existing integrations. Balance charges are calculated in rubles. Fields ending in _kopeks are expressed in kopeks (100 = 1 RUB).","schema":{"type":"string","enum":["RUB","USD"],"default":"RUB"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","data"],"properties":{"ok":{"const":true},"data":{"type":"object","properties":{"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"items":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"page":{"type":"integer"},"limit":{"type":"integer"},"has_more":{"type":"boolean"}}}}}}}},"400":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"401":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"403":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"409":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}},"429":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}},"headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retrying."}}},"503":{"description":"Request rejected; inspect error.code. Purchase errors may include the order in data.","content":{"application/json":{"schema":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"data":{"$ref":"#/components/schemas/Order"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"ExchangeRate":{"type":"object","required":["base","quote","rate","updated_at"],"properties":{"base":{"const":"USD"},"quote":{"const":"RUB"},"rate":{"type":"string","description":"Exact decimal string: RUB per 1 USD. Convert kopeks / 100 / rate for display only."},"updated_at":{"type":"string","format":"date-time"}}},"Account":{"type":"object","properties":{"telegram_id":{"type":"string"},"username":{"type":["string","null"]},"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"balance_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"balance":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"held_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"held":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"limits":{"type":"object","properties":{"requests_per_minute":{"type":"integer"}}},"api_access":{"const":"enabled"}}},"Product":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string","description":"Plain text without internal formatting commands. Links keep both label and URL; custom emoji use ordinary fallback symbols."},"description_html":{"type":"string","description":"HTML subset: strong, em, u, s, code, pre, blockquote, a and br. No scripts, inline styles, event handlers or Telegram-only markup. Spoiler contents are ordinary visible text."},"category":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}}},"price_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"price":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"is_test":{"type":"boolean","description":"True for the paid test product. Costs exactly 100 kopeks (1 RUB) per unit and delivers fictional email | password data on example.com. Purchases appear in normal history and statistics."},"api_only":{"type":"boolean"},"stock_unlimited":{"type":"boolean","description":"When true, stock is null and availability does not decrease after purchases."},"stock":{"type":["integer","null"],"minimum":0,"description":"Available quantity, or null for unlimited stock. Zero-stock products remain in the unfiltered catalog."},"available":{"type":"boolean","description":"False when stock is zero. Show Out of stock and disable purchasing until a later catalog refresh returns true."},"wholesale_tiers":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"min_quantity":{"type":"integer"},"unit_price_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"unit_price":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."}}}}}},"OrderSummary":{"type":"object","properties":{"id":{"type":"string"},"client_order_id":{"type":["string","null"]},"status":{"type":"string","enum":["processing","recovering","delivered","failed","refunded"]},"channel":{"const":"api"},"is_test":{"type":"boolean","description":"True when the reserved product uses fictional test delivery."},"product":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}}},"quantity":{"type":"integer"},"unit_price_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"unit_price":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"total_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"total":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"held_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"held":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"charged_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"charged":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"refunded_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"refunded":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"failure_code":{"type":["string","null"]},"failure_message":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"Order":{"allOf":[{"$ref":"#/components/schemas/OrderSummary"},{"type":"object","properties":{"delivery_data":{"type":["string","null"],"description":"Complete original product delivery, present only when status=delivered. Preserve as an opaque string."}}}]},"Transaction":{"type":"object","properties":{"id":{"type":"integer"},"amount_kopeks":{"type":"integer","description":"Amount in kopeks (100 = 1 RUB). Balance charges are calculated in rubles, with precision to one kopek, regardless of the display currency."},"amount":{"type":"string","pattern":"^-?[0-9]+\\.[0-9]{2}$","description":"Display amount rounded to two decimals in currency. Never convert this value back for payment."},"currency":{"type":"string","enum":["RUB","USD"]},"settlement_currency":{"const":"RUB"},"exchange_rate":{"oneOf":[{"$ref":"#/components/schemas/ExchangeRate"},{"type":"null"}],"description":"Current response conversion, also for historical amounts. Null for RUB. One rate snapshot per response; not a purchase quote."},"type":{"type":"string"},"order_id":{"type":["string","null"]},"channel":{"type":["string","null"]},"created_at":{"type":"string"}}}}}}