{"openapi":"3.1.0","info":{"title":"Bifrost Crypto API","version":"1","description":"Payins, payouts, balances, statements, prices and fixed addresses. Full guides: https://bifrostcrypto.com/en/docs"},"servers":[{"url":"https://bridge.bifrostcrypto.com"}],"security":[{"ApiKey":[]}],"tags":[{"name":"Payments Payout","description":"Endpoints for creating and tracking payouts (withdrawals). POST /v1/payout takes one payout object or a list of up to 50, and always answers with a summary and one result per item."},{"name":"Deposits Payin","description":"Endpoints for managing deposits and receipts. POST /v1/payin accepts one object, or an array with a single item, and rejects a batch with 400 invalid_parameters (details.reason batch_not_allowed_use_single_object). List and check only return payins created through the API. Response status values are lowercase: pending, completed, failed, reversed (a completed deposit the network later undid; the credit was removed). A payin is marked completed once the amount received reaches minimum_payment percent of crypto_amount, so a completed payin can still be partially paid: before delivering, compare received_amount with crypto_amount (both in crypto_currency)."},{"name":"Queries","description":"Endpoints for querying balances, statements, and account information."},{"name":"Prices","description":"Endpoints for querying prices and exchange rates between currencies. Prices are strings in pt-BR number format (\"65.432,10\")."},{"name":"Fixed Wallets","description":"Endpoints for managing fixed (permanent) deposit addresses assigned per customer. Every transfer to a fixed address becomes a completed payin and is notified to the fixed-address webhook URL set in the panel; see Receiving on a fixed address under Create Fixed Wallet."}],"paths":{"/v1/payout":{"post":{"operationId":"create-payout-single","summary":"Create Payout Single","description":"Creates one payout (withdrawal) to a destination wallet. The body is a single payout object, and the response has the same shape as a batch of one: 200 when the payout is created, 400 when it is refused. A refusal after validation comes in results[0].error, not at the top level; only request-level problems (invalid parameters, balance pre-check, malformed body) answer with a top-level error. In a created result, crypto_amount is the net amount the recipient receives (lower than what you sent when feetakenfromamount is 1), fiat_amount is its value in fiat_currency, network_fee is the network fee for the transfer (reported even when your account does not pay it) and memo is null unless the token uses one.\n\nBatch: Creates up to 50 payouts in one request. Send an array of payout objects with the same fields as Create Payout Single. Items are processed one by one, each in its own transaction: a refused item is reported on its own index and the rest of the batch still goes out. The HTTP status is 200 when every item was created, 207 when some were created and some refused, and 400 when every item was refused; in all three cases the body carries summary and one entry per item in results, in the order sent. If every item fails validation, the answer is instead a top-level invalid_parameters with no results. More than 50 items returns 400 max_payouts_exceeded and nothing is processed.","tags":["Payments Payout"],"x-required-scopes":["payout:write"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional, up to 255 characters (a longer key is ignored and the request runs without idempotency). Scoped to your account and kept for 24 hours: resending the same key returns the original status and body instead of processing again, even if the body differs. While the first request is still running (up to 15 minutes) a resend gets 409 idempotency_key_in_progress. Not stored when the request fails before any payout is attempted (top-level 4xx or 500), so a retry with the same key is processed normally.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"payment_processing_completed","summary":{"total_requested":1,"successful":1,"failed":0},"results":[{"index":0,"reference_id":"order_12345","internal_reference":"f47ac10b-58cc-4372-a567-0e02b2c3d479","crypto_amount":"100.5","fiat_amount":"100.50000000","crypto_currency":"USDT","fiat_currency":"USD","network_fee":"0.00100000","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","memo":null,"network":"Ethereum","process_by":"crypto_amount","status":"created"}]}}}}}},"400":{"description":"Payout refused","content":{"application/json":{"examples":{"payout_refused":{"value":{"message":"payment_processing_completed","summary":{"total_requested":1,"successful":0,"failed":1},"results":[{"index":0,"reference_id":"order_12345","error":{"code":"insufficient_balance","message":"Insufficient balance for this operation"}}]}},"reference_id_already_used":{"value":{"message":"payment_processing_completed","summary":{"total_requested":1,"successful":0,"failed":1},"results":[{"index":0,"reference_id":"order_12345","internal_reference":"f47ac10b-58cc-4372-a567-0e02b2c3d479","duplicate":true,"original_status":"pending","original_created_at":"2026-01-16 10:00:00","error":{"code":"duplicate_payment_reference","message":"A payout with this reference_id already exists"}}]}},"invalid_parameters":{"value":{"error":{"code":"invalid_parameters","message":"Invalid parameters provided","details":{"fields":{"0.crypto_amount":"Crypto amount must be a positive decimal number","0.network":"Invalid network"}}}}},"not_enough_balance":{"value":{"error":{"code":"insufficient_total_balance","message":"Insufficient balance to cover all payouts","details":{"crypto_currency":"USDT","available":"50.00000000","required":"100.500000000000000000"}}}},"request_level_errors":{"value":{"error":{"code":"json_parse_exception","message":"Exception while parsing JSON payload"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Request-level errors","content":{"application/json":{"examples":{"request_level_errors":{"value":{"error":{"code":"json_parse_exception","message":"Exception while parsing JSON payload"}}}}}}},"409":{"description":"Idempotency-Key still running","content":{"application/json":{"examples":{"idempotency_key_still_running":{"value":{"error":{"code":"idempotency_key_in_progress","message":"A request with this Idempotency-Key is still being processed"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Request-level errors","content":{"application/json":{"examples":{"request_level_errors":{"value":{"error":{"code":"json_parse_exception","message":"Exception while parsing JSON payload"}}}}}}}},"x-errors":[{"status":"400","code":"json_parse_exception · json_parse_failed","when":"The body is missing or is not valid JSON.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_payment_list","when":"The body is neither a payout object nor a non-empty list.","action":"Fix the request before sending it again."},{"status":"400","code":"max_payouts_exceeded","when":"More than 50 payouts in one request.","action":"Split into requests of up to 50."},{"status":"400","code":"invalid_parameters","when":"Every item failed validation; details.fields is keyed by index.field.","action":"Fix the request before sending it again."},{"status":"400","code":"insufficient_total_balance","when":"The items of one currency add up to more than the available balance. Nothing is debited.","action":"Top up the balance or send fewer payouts."},{"status":"200 · 207 · 400","code":"results[].error.code","when":"An item was refused after validation (see the Item refusal codes table).","action":"Fix and resend only the refused items, with a new Idempotency-Key."},{"status":"404","code":"user_not_found · record_not_found","when":"The account setup is incomplete.","action":"Contact support."},{"status":"409","code":"idempotency_key_in_progress","when":"A request with this Idempotency-Key is still running.","action":"Wait and retry with the same key."},{"status":"500","code":"error_fetching_active_currencies","when":"The token catalogue could not be loaded. Nothing was processed.","action":"Nothing was changed. Retry later."},{"status":"500","code":"internal_error","when":"Unexpected failure; summary and results show what was created.","action":"Resend only the items counted in summary.not_processed."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"wallet":{"type":"string","description":"Destination address, 20 to 120 characters (surrounding spaces are trimmed). A length outside that range fails validation (invalid_parameters). The format is then checked against the network: EVM is 0x plus 40 hex characters; Tron, Bitcoin and the other networks use their own formats. A mismatch returns invalid_format on that item."},"crypto_currency":{"type":"string","description":"Token symbol, case-sensitive (e.g.: USDT, BTC, ETH). Must be active for withdrawals; usdt is refused."},"process_by":{"type":"string","description":"crypto_amount or fiat_amount. Selects which amount is used; the other amount, if sent, is ignored."},"reference_id":{"type":"string","description":"Your reference for this payout, 1 to 255 characters (string or integer). Unique per account across all payouts. Sending one that already exists creates nothing: the item is refused with duplicate_payment_reference and duplicate: true, carrying the original payout's references. The duplicate is detected only after the amount, balance and daily-limit checks, so a resend can also be refused by one of those."},"network":{"type":"string","description":"One of: Bitcoin, Ethereum, BinanceSmartChain, Tron, Solana, Ripple, Cardano, Dogecoin, Polygon, Avalanche, ArbitrumOne, Celo, Optimism, Arbitrum, Cronos, Base, BitcoinCash, BitcoinSV, BitcoinGold, Monero, OpBnb, Xlayer, Litecoin, TON. Case-insensitive; the aliases in Network aliases are also accepted (erc20, bsc, trc20...) and the payout is stored and returned with the canonical name. Withdrawals must be enabled for the token on that network, otherwise the item returns invalid_network_or_withdrawals_disabled, unsupported_token_or_withdrawals_disabled or token_network_mismatch."},"feetakenfromamount":{"type":"number","description":"0 or 1 (number or string). 1 = fees deducted from the amount (the recipient receives less; the debit is the amount you sent). 0 = fees added on top of the debit (the recipient receives the full amount). When your account pays the network fee and holds enough of the network's native coin (e.g. ETH on Ethereum), that fee is debited from the native balance instead of the token."},"webhook_url":{"type":"string","description":"Callback URL for status updates, up to 756 characters. Must be https:// and resolve to a public address; a private, local or blocked destination fails validation (invalid_parameters on webhook_url)."},"fiat_currency":{"type":"string","description":"Required when process_by is fiat_amount (otherwise the item returns fiat_currency_required). Fiat code, case-insensitive (e.g. USD, BRL). When omitted with crypto_amount, your account's preferred currency is used, or USD, to compute fiat_amount in the response."},"crypto_amount":{"type":"string","description":"Required when process_by is crypto_amount (otherwise the item returns invalid_crypto_amount). Plain decimal only: digits with an optional dot, string or JSON number. Scientific notation, hex, thousands separators, signs and surrounding spaces are rejected. Decimals beyond the token's precision are truncated."},"fiat_amount":{"type":"string","description":"Required when process_by is fiat_amount (otherwise the item returns invalid_fiat_amount). Converted to crypto at the current price. Same format rules as crypto_amount."},"customer_info":{"type":"string","description":"Your customer identifier, up to 200 characters, no whitespace."},"memo":{"type":"string","description":"Required for tokens that need a destination memo, such as TON (otherwise the item returns memo_required). When sent it must be 8 to 15 digits, for any token; it is discarded for tokens that do not use one."}},"required":["wallet","crypto_currency","process_by","reference_id","network","feetakenfromamount","webhook_url"]},{"type":"array","maxItems":50,"items":{"type":"object","properties":{"wallet":{"type":"string","description":"Destination address, 20 to 120 characters (surrounding spaces are trimmed). A length outside that range fails validation (invalid_parameters). The format is then checked against the network: EVM is 0x plus 40 hex characters; Tron, Bitcoin and the other networks use their own formats. A mismatch returns invalid_format on that item."},"crypto_currency":{"type":"string","description":"Token symbol, case-sensitive (e.g.: USDT, BTC, ETH). Must be active for withdrawals; usdt is refused."},"process_by":{"type":"string","description":"crypto_amount or fiat_amount. Selects which amount is used; the other amount, if sent, is ignored."},"reference_id":{"type":"string","description":"Your reference for this payout, 1 to 255 characters (string or integer). Unique per account across all payouts. Sending one that already exists creates nothing: the item is refused with duplicate_payment_reference and duplicate: true, carrying the original payout's references. The duplicate is detected only after the amount, balance and daily-limit checks, so a resend can also be refused by one of those."},"network":{"type":"string","description":"One of: Bitcoin, Ethereum, BinanceSmartChain, Tron, Solana, Ripple, Cardano, Dogecoin, Polygon, Avalanche, ArbitrumOne, Celo, Optimism, Arbitrum, Cronos, Base, BitcoinCash, BitcoinSV, BitcoinGold, Monero, OpBnb, Xlayer, Litecoin, TON. Case-insensitive; the aliases in Network aliases are also accepted (erc20, bsc, trc20...) and the payout is stored and returned with the canonical name. Withdrawals must be enabled for the token on that network, otherwise the item returns invalid_network_or_withdrawals_disabled, unsupported_token_or_withdrawals_disabled or token_network_mismatch."},"feetakenfromamount":{"type":"number","description":"0 or 1 (number or string). 1 = fees deducted from the amount (the recipient receives less; the debit is the amount you sent). 0 = fees added on top of the debit (the recipient receives the full amount). When your account pays the network fee and holds enough of the network's native coin (e.g. ETH on Ethereum), that fee is debited from the native balance instead of the token."},"webhook_url":{"type":"string","description":"Callback URL for status updates, up to 756 characters. Must be https:// and resolve to a public address; a private, local or blocked destination fails validation (invalid_parameters on webhook_url)."},"fiat_currency":{"type":"string","description":"Required when process_by is fiat_amount (otherwise the item returns fiat_currency_required). Fiat code, case-insensitive (e.g. USD, BRL). When omitted with crypto_amount, your account's preferred currency is used, or USD, to compute fiat_amount in the response."},"crypto_amount":{"type":"string","description":"Required when process_by is crypto_amount (otherwise the item returns invalid_crypto_amount). Plain decimal only: digits with an optional dot, string or JSON number. Scientific notation, hex, thousands separators, signs and surrounding spaces are rejected. Decimals beyond the token's precision are truncated."},"fiat_amount":{"type":"string","description":"Required when process_by is fiat_amount (otherwise the item returns invalid_fiat_amount). Converted to crypto at the current price. Same format rules as crypto_amount."},"customer_info":{"type":"string","description":"Your customer identifier, up to 200 characters, no whitespace."},"memo":{"type":"string","description":"Required for tokens that need a destination memo, such as TON (otherwise the item returns memo_required). When sent it must be 8 to 15 digits, for any token; it is discarded for tokens that do not use one."}},"required":["wallet","crypto_currency","process_by","reference_id","network","feetakenfromamount","webhook_url"]}}]},"examples":{"single":{"value":{"wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_currency":"USDT","fiat_currency":"USD","crypto_amount":"100.50","process_by":"crypto_amount","reference_id":"order_12345","network":"Ethereum","feetakenfromamount":0,"webhook_url":"https://your-site.com/webhook","customer_info":"customer123"}},"batch":{"value":[{"wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_currency":"USDT","fiat_currency":"USD","crypto_amount":"100.50","process_by":"crypto_amount","reference_id":"order_12345","network":"Ethereum","feetakenfromamount":0,"webhook_url":"https://your-site.com/webhook","customer_info":"customer123"},{"wallet":"0x8Ba1f109551bD432803012645Ac136ddd64DBA72","crypto_currency":"BNB","crypto_amount":"0.5","process_by":"crypto_amount","reference_id":"order_12346","network":"BinanceSmartChain","feetakenfromamount":1,"webhook_url":"https://your-site.com/webhook"}]}}}}}}},"/v1/list-payout":{"get":{"operationId":"list-payouts","summary":"List Payouts","description":"Lists the payouts created through the API (payouts made in the panel are not included), newest first (created_at descending), with filters and pagination. Each payout carries the same fields as Check Specific Payout; crypto_amount is the net amount sent to the wallet and status is pending, completed, failed or refunded. summary counts pending, completed and failed payouts matching the same filters, across all pages. meta.filters echoes the filters applied, with status in its public value; dates are not echoed.","tags":["Payments Payout"],"x-required-scopes":["payout:read"],"parameters":[{"name":"page","in":"query","required":false,"description":"Page number, default 1. 0 or a non-numeric value is treated as 1; a negative number returns invalid_page_number.","schema":{"type":"string"},"example":"1"},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1 to 100, default 50. 0 or a non-numeric value is treated as 50; above 100 or negative returns invalid_per_page_limit.","schema":{"type":"string"},"example":"50"},{"name":"status","in":"query","required":false,"description":"pending, completed or failed (case-insensitive). Any other value returns invalid_status_filter. Refunded payouts are listed only without this filter.","schema":{"type":"string"},"example":"pending"},{"name":"crypto_currency","in":"query","required":false,"description":"Filter by token symbol","schema":{"type":"string"},"example":"USDT"},{"name":"network","in":"query","required":false,"description":"Filter by a network name from the catalog, exact and case-sensitive (e.g. Ethereum, BinanceSmartChain, Tron). An unknown name returns invalid_network_filter.","schema":{"type":"string"},"example":"Ethereum"},{"name":"date_from","in":"query","required":false,"description":"Start date (YYYY-MM-DD), inclusive from 00:00:00. An unreadable date returns invalid_date_from. Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-01"},{"name":"date_to","in":"query","required":false,"description":"End date (YYYY-MM-DD), inclusive until 23:59:59. An unreadable date returns invalid_date_to. Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-31"},{"name":"reference_id","in":"query","required":false,"description":"Filter by your reference_id (exact match)","schema":{"type":"string"},"example":"order_12345"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"payments_retrieved_success","payments":[{"internal_reference":"f47ac10b-58cc-4372-a567-0e02b2c3d479","reference_id":"order_12345","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_currency":"USDT","fiat_currency":"USD","crypto_amount":"100.500000000000000000","fiat_amount":"100.50","process_by":"crypto_amount","percent_rate":"1.50","network_fee":"0.00100000","network":"Ethereum","status":"pending","txid":null,"webhook_url":"https://your-site.com/webhook","feetakenfromamount":"0","created_at":"2026-01-16 10:00:00","updated_at":"2026-01-16 10:00:00"}],"summary":{"total_pending":1,"total_completed":0,"total_failed":0},"meta":{"current_page":1,"per_page":50,"total":1,"total_pages":1,"filters":{"status":"pending","crypto_currency":"USDT"}}}}}}}},"400":{"description":"Invalid query parameter","content":{"application/json":{"examples":{"invalid_query_parameter":{"value":{"error":{"code":"invalid_per_page_limit","message":"Invalid per_page value"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."}},"x-errors":[{"status":"400","code":"invalid_page_number","when":"page is negative.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_per_page_limit","when":"per_page is negative or above 100.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_status_filter","when":"status is not one of the accepted values.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_network_filter","when":"network is not a known network name (case-sensitive).","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_date_from · invalid_date_to","when":"A date could not be read.","action":"Send YYYY-MM-DD."},{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."}]}},"/v1/check-payout/{internal_reference}":{"get":{"operationId":"check-payout","summary":"Check Specific Payout","description":"Returns one payout created through the API, by the internal_reference returned when it was created. status is pending, completed, failed or refunded, and txid is null while there is no transaction hash. crypto_amount is the net amount sent to the wallet. A payout made in the panel, or belonging to another account, returns 404.","tags":["Payments Payout"],"x-required-scopes":["payout:read"],"parameters":[{"name":"internal_reference","in":"path","required":true,"description":"internal_reference of the payout (a UUID). Fewer than 10 or more than 756 characters returns invalid_reference_id.","schema":{"type":"string"},"example":"f47ac10b-58cc-4372-a567-0e02b2c3d479"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"payment_retrieved_success","payment":{"internal_reference":"f47ac10b-58cc-4372-a567-0e02b2c3d479","reference_id":"order_12345","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_currency":"USDT","fiat_currency":"USD","crypto_amount":"100.500000000000000000","fiat_amount":"100.50","process_by":"crypto_amount","percent_rate":"1.50","network_fee":"0.00100000","network":"Ethereum","status":"completed","txid":"0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060","webhook_url":"https://your-site.com/webhook","feetakenfromamount":"0","created_at":"2026-01-16 10:00:00","updated_at":"2026-01-16 10:05:00"}}}}}}},"400":{"description":"Invalid reference","content":{"application/json":{"examples":{"invalid_reference":{"value":{"error":{"code":"invalid_reference_id","message":"Invalid reference ID provided"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Payout not found","content":{"application/json":{"examples":{"payout_not_found":{"value":{"error":{"code":"record_not_found","message":"Record not found","details":{"resource":"payment"}}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"x-errors":[{"status":"400","code":"invalid_reference_id","when":"internal_reference is shorter than 10 or longer than 756 characters.","action":"Fix the request before sending it again."},{"status":"404","code":"record_not_found","when":"No payout created through the API with this internal_reference exists on your account.","action":"Check the internal_reference returned on creation. Items created in the panel are not returned."}]}},"/v1/payin":{"post":{"operationId":"create-payin-single","summary":"Create Payin","description":"Creates a single deposit and answers 200 OK with a wallet address for the customer to send funds to. The payin becomes completed when the amount received reaches minimum_payment percent of crypto_amount (minimum_payment is set per account and returned by check-payin and GET /v1/summary), which may be less than the full amount: confirm received_amount before delivering. The success body is one object under data, not a batch summary. crypto_amount in the response is cut (not rounded) to the token's decimals, with trailing zeros removed (\"50.00\" comes back as \"50\"). fiat_amount is the value you sent; when you did not send one it is crypto_amount × price with 8 decimals, or null if no price is available. The response has no expires_at: read it from check-payin. This endpoint has no Idempotency-Key: reference_id is what prevents a second payin. If a request times out, resend it with the same reference_id; a duplicate_reference_id answer means the first one was created, and GET /v1/list-payin?reference_id=… returns it. The error codes are listed under Errors.","tags":["Deposits Payin"],"x-required-scopes":["payin:write"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"deposit_created_successfully","data":{"reference_id":"invoice_67890","internal_reference":"f531c319-6957-45c6-a154-d4944ca3eee3","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_amount":"50","fiat_amount":"50.00000000","crypto_currency":"USDT","fiat_currency":"USD","network":"BinanceSmartChain","status":"created"}}}}}}},"400":{"description":"Duplicate reference_id","content":{"application/json":{"examples":{"duplicate_reference_id":{"value":{"error":{"code":"duplicate_reference_id","message":"A payin with this reference_id already exists"}}},"invalid_parameters":{"value":{"error":{"code":"invalid_parameters","message":"Invalid parameters provided","details":{"fields":{"crypto_currency":"The crypto_currency field must be one of: USDT,BTC,ETH."}}}}},"amount_outside_the_token_limits":{"value":{"error":{"code":"amount_out_of_limits","message":"Amount is outside the allowed limits","details":{"message":"Amount below minimum limit","crypto_amount":"0.5","crypto_currency":"USDT","min_allowed":"1.000000000000000000","max_allowed":"unlimited","process_by":"crypto_amount"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"The account setup is incomplete."},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Failure on our side."},"502":{"description":"The deposit address could not be created right now."},"503":{"description":"Temporarily unavailable","content":{"application/json":{"examples":{"temporarily_unavailable":{"value":{"error":{"code":"no_wallet_available","message":"No deposit address is available right now"}}}}}}}},"x-errors":[{"status":"400","code":"invalid_parameters","when":"A field failed validation (details.fields), the body is empty (details.reason invalid_or_empty_data), a batch was sent (batch_not_allowed_use_single_object) or webhook_url is not allowed (details.reason unsafe_url).","action":"Fix the request before sending it again."},{"status":"400","code":"json_parse_exception","when":"The body is not valid JSON.","action":"Fix the request before sending it again."},{"status":"400","code":"duplicate_reference_id","when":"A payin with this reference_id already exists.","action":"If it was a resend after a timeout, fetch it with GET /v1/list-payin?reference_id=…"},{"status":"400","code":"crypto_amount_required · fiat_amount_required · fiat_currency_required","when":"The amount or currency required by process_by is missing.","action":"Fix the request before sending it again."},{"status":"400","code":"memo_required","when":"The token needs a memo.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_network_or_deposits_disabled · unsupported_token_or_deposits_disabled · token_network_mismatch · token_not_supported_or_inactive","when":"The token or network does not accept deposits for your account.","action":"Choose another token or network."},{"status":"400","code":"amount_out_of_limits · value_below_minimum · value_above_maximum","when":"The amount is outside the token limits; details carries them.","action":"Fix the request before sending it again."},{"status":"400","code":"crypto_amount_does_not_correspond_to_fiat_amount_provided","when":"crypto_amount and fiat_amount differ by more than 30% at the current price.","action":"Fix the request before sending it again."},{"status":"404","code":"record_not_found","when":"The account setup is incomplete.","action":"Contact support."},{"status":"500","code":"internal_error · error_fetching_active_currencies · token_type_not_found · receipt_creation_failed · database_transaction_failed","when":"Failure on our side.","action":"Retry later with the same reference_id."},{"status":"502","code":"external_processor_error","when":"The deposit address could not be created right now.","action":"Retry later with the same reference_id."},{"status":"503","code":"no_processor_configured · no_wallet_available · price_not_available_for_conversion · price_not_available_for_validation · service_unavailable","when":"Temporarily unavailable.","action":"Retry later with the same reference_id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"crypto_currency":{"type":"string","description":"Token symbol, case-sensitive (USDT, not usdt). It must be enabled on your account and active for deposits on the chosen network; otherwise invalid_parameters (details.fields.crypto_currency), unsupported_token_or_deposits_disabled or token_network_mismatch."},"process_by":{"type":"string","description":"Which amount drives the deposit: crypto_amount or fiat_amount."},"reference_id":{"type":"string","description":"Your reference for this deposit, 1 to 255 characters, trimmed. Must be unique on your account; a repeat returns duplicate_reference_id."},"network":{"type":"string","description":"One of: Bitcoin, Ethereum, BinanceSmartChain, Tron, Solana, Ripple, Cardano, Dogecoin, Polygon, Avalanche, ArbitrumOne, Celo, Optimism, Arbitrum, Cronos, Base, BitcoinCash, BitcoinSV, BitcoinGold, Monero, OpBnb, Xlayer, Litecoin, TON. Case-insensitive here (binancesmartchain works), and the aliases in Network aliases are also accepted (erc20, bsc, trc20...); the payin is stored and returned with the canonical name. A network without active deposits returns invalid_network_or_deposits_disabled."},"webhook_url":{"type":"string","description":"Callback URL for status updates. Up to 756 characters, https://, no user:password in the URL, on a standard port, and the host must resolve to a public IPv4 address. A refused URL returns 400 invalid_parameters with details.field webhook_url and details.reason unsafe_url."},"fiat_currency":{"type":"string","description":"Fiat code from the accepted fiats, case-insensitive. Required when process_by is fiat_amount (fiat_currency_required). When omitted, your account's preferred currency is used, then USD."},"crypto_amount":{"type":"string","description":"Required when process_by is crypto_amount (crypto_amount_required). Greater than 0, digits on both sides of an optional dot (\".5\" and \"5.\" are refused). Extra decimals beyond the token's precision are cut. Ignored and recalculated when process_by is fiat_amount. A JSON number is accepted; a string is recommended."},"fiat_amount":{"type":"string","description":"Required when process_by is fiat_amount (fiat_amount_required); same format as crypto_amount. When process_by is crypto_amount and you also send fiat_amount, crypto_amount must be within ±30% of fiat_amount ÷ current price, or the request fails with crypto_amount_does_not_correspond_to_fiat_amount_provided (or 503 price_not_available_for_validation without a price)."},"customer_info":{"type":"string","description":"Your customer identifier. Up to 200 characters, no whitespace."},"expires_at":{"type":"number","description":"Lifetime of the deposit in seconds, integer from 1 to 86400. Default 14400 (4 hours). The resulting date is returned as expires_at (Y-m-d H:i:s) by check-payin and list-payin."},"memo":{"type":"string","description":"Required for tokens configured to need a memo, such as TON (memo_required otherwise). Numeric string of 8 to 15 digits; this format is checked whenever memo is sent, and the value is ignored on tokens that do not use one."}},"required":["crypto_currency","process_by","reference_id","network","webhook_url"]},"example":{"crypto_currency":"USDT","fiat_currency":"USD","crypto_amount":"50.00","process_by":"crypto_amount","reference_id":"invoice_67890","network":"BinanceSmartChain","webhook_url":"https://your-site.com/webhook-deposit","customer_info":"customer456","expires_at":14400}}}}}},"/v1/list-payin":{"get":{"operationId":"list-payins","summary":"List Payins","description":"Lists deposits created through the API (not those created in the panel), newest first (created_at descending), with filters and pagination. Answers 200 OK. summary counts pending, completed, failed and reversed deposits matching the same filters. minimum_payment is the percentage of crypto_amount that marks the payin completed; received_amount is what actually arrived, and payment_status says partial, exact or overpaid (null before any payment). A reversed deposit carries reversal with reversed_at, partial (true when part of the payin is still credited) and amounts (balance key and amount removed); reversal is null otherwise. meta.filters echoes the filters applied, with status in its public value. Fields that need explanation are described below.","tags":["Deposits Payin"],"x-required-scopes":["payin:read"],"parameters":[{"name":"page","in":"query","required":false,"description":"Page number (default: 1). 0 or a non-numeric value falls back to 1; a negative value returns invalid_page_number.","schema":{"type":"string"},"example":"1"},{"name":"per_page","in":"query","required":false,"description":"Items per page, 1-100 (default: 50). 0 or a non-numeric value falls back to 50; above 100 or negative returns invalid_per_page_limit.","schema":{"type":"string"},"example":"50"},{"name":"status","in":"query","required":false,"description":"Filter by status: pending, completed, failed or reversed (any case). completed excludes reversed deposits. Anything else returns invalid_status_filter.","schema":{"type":"string"},"example":"completed"},{"name":"crypto_currency","in":"query","required":false,"description":"Filter by crypto currency symbol (exact match)","schema":{"type":"string"},"example":"USDT"},{"name":"network","in":"query","required":false,"description":"Filter by a network name from the catalog, exact and case-sensitive (BinanceSmartChain, not binancesmartchain). An unknown name returns invalid_network_filter.","schema":{"type":"string"},"example":"BinanceSmartChain"},{"name":"date_from","in":"query","required":false,"description":"Start date (YYYY-MM-DD), inclusive from 00:00:00. An unparseable date returns invalid_date_from. No maximum range. Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-01"},{"name":"date_to","in":"query","required":false,"description":"End date (YYYY-MM-DD), inclusive until 23:59:59. An unparseable date returns invalid_date_to. Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-31"},{"name":"reference_id","in":"query","required":false,"description":"Filter by reference_id (exact match)","schema":{"type":"string"},"example":"invoice_67890"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"deposits_retrieved_success","deposits":[{"internal_reference":"f531c319-6957-45c6-a154-d4944ca3eee3","reference_id":"invoice_67890","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_currency":"USDT","invoice_currency":"USDT","invoice_amount":"50.00","fiat_currency":"USD","crypto_amount":"50.00","received_amount":"0.00000000","fiat_amount":"50.00","process_by":"crypto_amount","percent_rate":"2.50","network_fee":"0.00000000","minimum_payment":"10.00","network":"BinanceSmartChain","status":"pending","payment_status":null,"txid":null,"payments":[],"webhook_url":"https://your-site.com/webhook-deposit","is_wallet_fixed":false,"reversal":null,"created_at":"2026-01-16 10:00:00","updated_at":"2026-01-16 10:00:00","expires_at":"2026-01-16 14:00:00"}],"summary":{"total_pending":1,"total_completed":0,"total_failed":0,"total_reversed":0},"meta":{"current_page":1,"per_page":50,"total":1,"total_pages":1,"filters":{"status":"pending","crypto_currency":"USDT"}}}}}}}},"400":{"description":"Invalid filter","content":{"application/json":{"examples":{"invalid_filter":{"value":{"error":{"code":"invalid_network_filter","message":"Invalid network filter"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."}},"x-errors":[{"status":"400","code":"invalid_page_number","when":"page is negative.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_per_page_limit","when":"per_page is negative or above 100.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_status_filter","when":"status is not one of the accepted values.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_network_filter","when":"network is not a known network name (case-sensitive).","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_date_from · invalid_date_to","when":"A date could not be read.","action":"Send YYYY-MM-DD."},{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."}]}},"/v1/check-payin/{internal_reference}":{"get":{"operationId":"check-payin","summary":"Check Specific Payin","description":"Checks the status of a specific deposit by internal_reference and answers 200 OK. Only deposits created through the API are found. status is pending, completed, failed or reversed. completed means received_amount reached minimum_payment percent of crypto_amount, not necessarily the full amount: compare received_amount with crypto_amount before delivering. reversed means the network undid a payment that had been credited; reversal then gives reversed_at, partial and the amounts removed per balance key (null when there was no reversal). Unlike the list, this object does not include payments, payment_status, invoice_currency or invoice_amount. Errors: 400 invalid_reference_id when internal_reference is shorter than 10 or longer than 756 characters; 404 record_not_found (details.resource receipt) when it does not exist on your account.","tags":["Deposits Payin"],"x-required-scopes":["payin:read"],"parameters":[{"name":"internal_reference","in":"path","required":true,"description":"Internal deposit reference","schema":{"type":"string"},"example":"f531c319-6957-45c6-a154-d4944ca3eee3"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"receipt_retrieved_success","receipt":{"internal_reference":"f531c319-6957-45c6-a154-d4944ca3eee3","reference_id":"invoice_67890","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","crypto_currency":"USDT","fiat_currency":"USD","crypto_amount":"50.00000000","received_amount":"0.00000000","fiat_amount":"50.00","process_by":"crypto_amount","percent_rate":"2.50","network_fee":"0.00000000","minimum_payment":"10.00","network":"BinanceSmartChain","status":"pending","txid":null,"webhook_url":"https://your-site.com/webhook-deposit","is_wallet_fixed":false,"reversal":null,"created_at":"2026-01-16 10:00:00","updated_at":"2026-01-16 10:00:00","expires_at":"2026-01-16 14:00:00"}}},"partially_paid":{"value":{"message":"receipt_retrieved_success","receipt":{"internal_reference":"f531c319-6957-45c6-a154-d4944ca3eee3","reference_id":"invoice_67890","crypto_currency":"USDT","crypto_amount":"50.00000000","received_amount":"20.00000000","minimum_payment":"10.00","status":"completed","reversal":null,"...":"..."}}},"reversed_deposit":{"value":{"message":"receipt_retrieved_success","receipt":{"internal_reference":"f531c319-6957-45c6-a154-d4944ca3eee3","reference_id":"invoice_67890","status":"reversed","reversal":{"reversed_at":"2026-01-16 10:12:40","partial":false,"amounts":[{"balance":"balance_tether","amount":"48.75000000"}]},"...":"..."}}}}}}},"400":{"description":"internal_reference is shorter than 10 or longer than 756 characters."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Payin not found","content":{"application/json":{"examples":{"payin_not_found":{"value":{"error":{"code":"record_not_found","message":"Record not found","details":{"resource":"receipt"}}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"x-errors":[{"status":"400","code":"invalid_reference_id","when":"internal_reference is shorter than 10 or longer than 756 characters.","action":"Fix the request before sending it again."},{"status":"404","code":"record_not_found","when":"No payin created through the API with this internal_reference exists on your account.","action":"Check the internal_reference returned on creation. Items created in the panel are not returned."}]}},"/v1/balances":{"get":{"operationId":"get-balances","summary":"Get Balances","description":"Returns gross balances plus amounts held by deposits that are not final yet, with 200 OK. balances has one key per supported currency (balance_<name>). Which key holds each token is returned as balance_key by GET /v1/summary/tokens: there is one balance per token, shared by every network, so USDT received on any network adds up in the same key. each a decimal string with 8 places; an account that never moved funds gets the same keys at \"0.00000000\". The key set grows when a currency is added, so iterate the keys instead of hard-coding them. available and locked are always objects and only include currencies that currently have a hold; when nothing is held both are {} and the spendable amount is balances. available is balances minus locked, never below zero. A payout is checked against available when a hold exists.","tags":["Queries"],"x-required-scopes":["balances:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"balances_retrieved_success","balances":{"balance_bitcoin":"0.00000000","balance_avalanche":"5.00000000","balance_ethereum":"0.50000000","balance_tether":"1000.00000000","balance_usdcoin":"500.00000000","balance_brz":"0.00000000","balance_binancecoin":"2.00000000","balance_cardano":"0.00000000","balance_solana":"10.00000000","balance_polygon":"100.00000000","balance_tron":"50.00000000","balance_brl1":"0.00000000","balance_ethenausde":"0.00000000","balance_dai":"0.00000000","balance_paypalusd":"0.00000000","balance_usdd":"0.00000000","balance_eurc":"0.00000000","balance_trueusd":"0.00000000","balance_usd1":"0.00000000","balance_tethergold":"0.00000000","balance_paxgold":"0.00000000","balance_pleasurecoin":"0.00000000","balance_dolz":"0.00000000","balance_floki":"0.00000000","balance_shibainu":"0.00000000","balance_pepe":"0.00000000","balance_dogecoin":"0.00000000","balance_ton":"0.00000000","balance_monero":"0.00000000","balance_litecoin":"0.00000000","balance_cronos":"0.00000000","balance_okb":"0.00000000","balance_usdg":"0.00000000"},"available":{"balance_tether":"900.00000000"},"locked":{"balance_tether":"100.00000000"}}}}}}},"400":{"description":"The client IP address could not be determined."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"x-errors":[{"status":"400","code":"invalid_ip","when":"The client IP address could not be determined.","action":"Contact support."}]}},"/v1/statements":{"get":{"operationId":"list-statements","summary":"List Statements","description":"Lists the balance movements caused by API operations (payins, payouts, their fees, payout refunds and deposit reversals), newest first. Movements made only in the panel are not returned. Without dates, the last 30 days are returned; the widest range accepted is 90 days (inclusive). filters echoes the window actually used and adds date_range_defaulted: true when you did not send both dates. amount is a string with 8 decimals. origin is null for manual operations; on incoming lines only origin.type is kept (reference, sequence and total are null). Data can be up to 5 minutes old.","tags":["Queries"],"x-required-scopes":["statements:read"],"parameters":[{"name":"page","in":"query","required":false,"description":"Page number (default: 1)","schema":{"type":"string"},"example":"1"},{"name":"per_page","in":"query","required":false,"description":"Items per page (default: 50, max: 50). Above 50 the request is refused with invalid_pagination; it is not clamped.","schema":{"type":"string"},"example":"50"},{"name":"direction","in":"query","required":false,"description":"Direction: in (incoming) or out (outgoing). Lowercase, case-sensitive.","schema":{"type":"string"},"example":"out"},{"name":"type","in":"query","required":false,"description":"Type: DEPOSIT (payin credit), WITHDRAWAL (payout debit), RATE (percentage fee), FEE (network fee), WITHDRAWAL_REFUND (amount of a failed payout returned to your balance), DEPOSIT_REVERSAL (credit removed after the network undid a deposit). Uppercase, case-sensitive. Any other value returns 400 invalid_parameters.","schema":{"type":"string"},"example":"WITHDRAWAL"},{"name":"balance","in":"query","required":false,"description":"Filter by balance. Accepts any key returned by Get Balances (the balance_key of each token in GET /v1/summary/tokens, e.g. balance_tether for USDT); exact, case-sensitive match. Anything else is refused with 400 invalid_parameters (details.field = \"balance\").","schema":{"type":"string"},"example":"balance_tether"},{"name":"date_from","in":"query","required":false,"description":"Start date (YYYY-MM-DD, inclusive). Omitted, it is 29 days before date_to (a 30-day inclusive window). Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-01"},{"name":"date_to","in":"query","required":false,"description":"End date (YYYY-MM-DD, inclusive). Omitted, it is today when date_from is also omitted, otherwise date_from + 29 days. Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-31"},{"name":"reference_id","in":"query","required":false,"description":"Exact reference ID (max 255 characters)","schema":{"type":"string"},"example":"order_12345"},{"name":"amount_from","in":"query","required":false,"description":"Minimum amount (numeric, >= 0)","schema":{"type":"string"},"example":"10.00"},{"name":"amount_to","in":"query","required":false,"description":"Maximum amount (numeric, >= 0, not lower than amount_from)","schema":{"type":"string"},"example":"1000.00"},{"name":"origin_type","in":"query","required":false,"description":"Filter by the origin of the statement line. recurring_transfer selects lines created by a recurring transfer.","schema":{"type":"string"},"example":"recurring_transfer"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"statements_retrieved_success","statements":[{"direction":"out","type":"WITHDRAWAL","amount":"150.50000000","balance":"balance_tether","internal_reference":"f47ac10b-58cc-4372-a567-0e02b2c3d479","origin":{"type":"recurring_transfer","reference":"RT-1a2b3c4d","sequence":3,"total":12},"created_at":"2026-01-20 14:32:10","updated_at":"2026-01-20 14:32:10","reference_id":"order_12345"},{"direction":"in","type":"DEPOSIT","amount":"1000.00000000","balance":"balance_tether","internal_reference":"f531c319-6957-45c6-a154-d4944ca3eee3","origin":null,"created_at":"2026-01-18 09:05:44","updated_at":"2026-01-18 09:05:44","reference_id":"invoice_998"}],"filters":{"balance":"balance_tether","date_from":"2026-01-01","date_to":"2026-01-31"},"meta":{"current_page":1,"per_page":50,"total":2,"total_pages":1}}}}}}},"400":{"description":"Date range too wide","content":{"application/json":{"examples":{"date_range_too_wide":{"value":{"error":{"code":"date_range_too_wide","message":"The requested date range exceeds the maximum allowed","details":{"max_days":90}}}},"invalid_filter":{"value":{"error":{"code":"invalid_parameters","message":"Invalid parameters provided","details":{"field":"balance"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"The query failed."}},"x-errors":[{"status":"400","code":"invalid_pagination","when":"page below 1 or per_page above 50.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_parameters","when":"direction, type, balance or origin_type is not an accepted value; details.field names it.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_format","when":"A date is not YYYY-MM-DD; details.field names it.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_date_range","when":"date_from is after date_to.","action":"Fix the request before sending it again."},{"status":"400","code":"date_range_too_wide","when":"The window is longer than details.max_days (90).","action":"Query the period in smaller windows."},{"status":"400","code":"invalid_amount","when":"amount_from or amount_to is not a number ≥ 0, or amount_from is above amount_to.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_reference_id","when":"reference_id is longer than 255 characters.","action":"Fix the request before sending it again."},{"status":"500","code":"database_error","when":"The query failed.","action":"Nothing was changed. Retry later."}]}},"/v1/statements/summary":{"get":{"operationId":"statements-summary","summary":"Statements Summary","description":"Returns counts and aggregated amounts of the same movements List Statements returns, grouped by balance (currency). Only balances, directions and types with records in the period are included in the response. Without dates, the last 30 days are summarised; the widest range accepted is 90 days (inclusive). total_amount is a string with 8 decimals. With no records in the period, by_balance is an empty array ([]), not an object. Data can be up to 5 minutes old.","tags":["Queries"],"x-required-scopes":["statements:read"],"parameters":[{"name":"date_from","in":"query","required":false,"description":"Start date of the period (inclusive). Format: YYYY-MM-DD. Omitted, it is 29 days before date_to (a 30-day inclusive window). Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-01-01"},{"name":"date_to","in":"query","required":false,"description":"End date of the period (inclusive). Format: YYYY-MM-DD. Omitted, it is today when date_from is also omitted, otherwise date_from + 29 days. Read in UTC−03:00.","schema":{"type":"string"},"example":"2026-03-31"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"statement_summary_retrieved_success","filters":{"date_from":"2026-01-01","date_to":"2026-03-31"},"summary":{"by_balance":{"balance_bitcoin":{"total_count":16,"by_direction":{"in":{"count":12,"total_amount":"0.05000000"},"out":{"count":4,"total_amount":"0.02000000"}},"by_type":{"DEPOSIT":{"count":10,"total_amount":"0.04000000"},"WITHDRAWAL":{"count":4,"total_amount":"0.02000000"},"FEE":{"count":1,"total_amount":"0.00100000"},"RATE":{"count":1,"total_amount":"0.00050000"}}},"balance_ethereum":{"total_count":8,"by_direction":{"in":{"count":5,"total_amount":"1.20000000"},"out":{"count":3,"total_amount":"0.50000000"}},"by_type":{"DEPOSIT":{"count":5,"total_amount":"1.20000000"},"WITHDRAWAL":{"count":3,"total_amount":"0.50000000"}}}},"totals":{"total_statements":24,"balances_used":["balance_bitcoin","balance_ethereum"]}}}},"called_without_dates":{"value":{"message":"statement_summary_retrieved_success","filters":{"date_from":"2026-08-13","date_to":"2026-09-11","date_range_defaulted":true},"summary":{"...":"..."}}}}}}},"400":{"description":"Date range too wide","content":{"application/json":{"examples":{"date_range_too_wide":{"value":{"error":{"code":"date_range_too_wide","message":"The requested date range exceeds the maximum allowed","details":{"max_days":90}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"The query failed."}},"x-errors":[{"status":"400","code":"invalid_format","when":"A date is not YYYY-MM-DD; details.field names it.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_date_range","when":"date_from is after date_to.","action":"Fix the request before sending it again."},{"status":"400","code":"date_range_too_wide","when":"The window is longer than details.max_days (90).","action":"Query the period in smaller windows."},{"status":"500","code":"database_error","when":"The query failed.","action":"Nothing was changed. Retry later."}]}},"/v1/summary":{"get":{"operationId":"complete-summary","summary":"Complete Summary","description":"Returns complete summary including accepted tokens and their configurations, accepted fiats, user information (fees, settings), and user-specific network rates. user_info.minimum_payment is the percentage of a payin's crypto_amount that must arrive for it to be marked completed (100 = the full amount, also used when the account has no value set). Rates and limits are numeric strings without trailing zeros (\"1\", \"2.5\"). network_rates is keyed by network and only lists networks with an override; its user_pays_* flags are null when the network inherits the account setting. With no overrides, network_rates is an empty array ([]), not an object. Data can be up to 5 minutes old. Rates are explained below. accepted_tokens follows the same rules as Accepted Tokens: This is the platform catalogue of active tokens, one entry per token and network. It is not filtered by your account and does not say whether a token accepts deposits, payouts or both on that network. Availability is checked when you create the operation: a payin needs the token enabled on your account and deposits active on that network (otherwise invalid_parameters on crypto_currency, unsupported_token_or_deposits_disabled or token_network_mismatch); a payout needs withdrawals active on that network (otherwise invalid_parameters, unsupported_token_or_withdrawals_disabled or token_network_mismatch). balance_key is the key of the token in GET /v1/balances and in the balance filter of List Statements.","tags":["Queries"],"x-required-scopes":["statements:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"summary_retrieved_success","data":{"accepted_tokens":[{"symbol":"USDT","contract_address":"0xdac17f958d2ee523a2206206994597c13d831ec7","network":"Ethereum","variant":null,"balance_key":"balance_tether","min_receipt":"10","max_receipt":"unlimited","min_withdrawal":"20","max_withdrawal":"50000","network_fee":"0.001"}],"accepted_fiats":[{"code":"USD","name":"US Dollar","symbol":"$"}],"user_info":{"minimum_payment":"10","receipt_rate":"2.5","payment_rate":"1.5","deposit_rate":"2.5","withdrawal_rate":"1.5","user_pays_payment_network_fee":true,"user_pays_receipt_network_fee":false,"user_pays_deposit_network_fee":false,"user_pays_withdrawal_network_fee":true},"network_rates":{"Ethereum":{"payment_rate":"1","receipt_rate":"2","deposit_rate":"2","withdrawal_rate":"1","user_pays_payment_network_fee":true,"user_pays_receipt_network_fee":null,"user_pays_deposit_network_fee":null,"user_pays_withdrawal_network_fee":null}},"summary_stats":{"total_tokens":15,"total_fiats":5,"total_network_overrides":1,"generated_at":"2026-01-16 10:00:00"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"The account setup is incomplete."},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."},"503":{"description":"Token or fiat catalogue unavailable","content":{"application/json":{"examples":{"token_or_fiat_catalogue_unavailable":{"value":{"error":{"code":"service_unavailable","message":"Service temporarily unavailable"}}}}}}}},"x-errors":[{"status":"404","code":"record_not_found","when":"The account setup is incomplete.","action":"Contact support."},{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."},{"status":"503","code":"service_unavailable","when":"The token or fiat catalogue could not be loaded.","action":"Nothing was changed. Retry later."}]}},"/v1/summary/tokens":{"get":{"operationId":"accepted-tokens","summary":"Accepted Tokens","description":"Returns only the list of accepted tokens with their configurations. This is the platform catalogue of active tokens, one entry per token and network. It is not filtered by your account and does not say whether a token accepts deposits, payouts or both on that network. Availability is checked when you create the operation: a payin needs the token enabled on your account and deposits active on that network (otherwise invalid_parameters on crypto_currency, unsupported_token_or_deposits_disabled or token_network_mismatch); a payout needs withdrawals active on that network (otherwise invalid_parameters, unsupported_token_or_withdrawals_disabled or token_network_mismatch). balance_key is the key of the token in GET /v1/balances and in the balance filter of List Statements. variant is the on-chain contract variant (lowercase) or null. Limits and network_fee are numeric strings without trailing zeros; max_receipt and max_withdrawal mean no ceiling when they are \"unlimited\", \"0\" or null. If the catalogue cannot be loaded, the answer is 503 service_unavailable; an unexpected failure is 500 internal_error.","tags":["Queries"],"x-required-scopes":["prices:read","statements:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"tokens_retrieved_success","tokens":[{"symbol":"USDT","contract_address":"0xdac17f958d2ee523a2206206994597c13d831ec7","network":"Ethereum","variant":null,"balance_key":"balance_tether","min_receipt":"10","max_receipt":"unlimited","min_withdrawal":"20","max_withdrawal":"50000","network_fee":"0.001"}],"meta":{"total":15,"generated_at":"2026-01-16 10:00:00"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."},"503":{"description":"The token catalogue could not be loaded."}},"x-errors":[{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."},{"status":"503","code":"service_unavailable","when":"The token catalogue could not be loaded.","action":"Nothing was changed. Retry later."}]}},"/v1/summary/fiats":{"get":{"operationId":"accepted-fiats","summary":"Accepted Fiats","description":"Returns only the list of accepted fiat currencies. If the catalogue cannot be loaded, the answer is 503 service_unavailable; an unexpected failure is 500 internal_error.","tags":["Queries"],"x-required-scopes":["prices:read","statements:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"fiats_retrieved_success","fiats":[{"code":"USD","name":"US Dollar","symbol":"$"},{"code":"EUR","name":"Euro","symbol":"€"},{"code":"BRL","name":"Brazilian Real","symbol":"R$"}],"meta":{"total":5,"generated_at":"2026-01-16 10:00:00"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."},"503":{"description":"The fiat catalogue could not be loaded."}},"x-errors":[{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."},{"status":"503","code":"service_unavailable","when":"The fiat catalogue could not be loaded.","action":"Nothing was changed. Retry later."}]}},"/v1/get-price":{"get":{"operationId":"get-price","summary":"Get Price","description":"Gets the conversion price between two currencies (crypto or fiat). Conversion types: same_currency, crypto_to_fiat, fiat, crypto_to_crypto, reversed_* (the inverse of a stored quote, e.g. reversed_crypto_to_fiat for USD to USDT). price is always a string in pt-BR number format: comma as decimal separator and dot as thousands separator. Decimals: same_currency is always \"1,00\"; fiat has 6 decimals; crypto_to_fiat, crypto_to_crypto and reversed_* have 2 decimals when the value is 1 or more (\"65.432,10\") and 8 significant digits below 1 (\"0,000012340000\" for a token worth 0.00001234), so low-value tokens never read as zero. Do not parseFloat it directly (\"65.432,10\" would read as 65.432): remove the dots, then replace the comma with a dot. Identical currency codes always answer same_currency, even for a code that is not listed.","tags":["Prices"],"x-required-scopes":["prices:read"],"parameters":[{"name":"currency1","in":"query","required":true,"description":"Source currency (crypto or fiat). Letters and digits, 2 to 16 characters; trimmed and uppercased before lookup, so usdt is accepted.","schema":{"type":"string"},"example":"USDT"},{"name":"currency2","in":"query","required":true,"description":"Target currency (crypto or fiat). Same format as currency1.","schema":{"type":"string"},"example":"USD"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"success":true,"data":{"from":"USDT","to":"USD","price":"1,00","type":"crypto_to_fiat","last_updated":"2026-01-16T10:00:00-03:00"}}}}}}},"400":{"description":"Invalid parameters","content":{"application/json":{"examples":{"invalid_parameters":{"value":{"error":{"code":"invalid_currency","message":"Parameter currency2 is not a valid currency code"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Price not found","content":{"application/json":{"examples":{"price_not_found":{"value":{"error":{"code":"price_not_found","message":"Price not found for USDT/XYZ"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."}},"x-errors":[{"status":"400","code":"missing_parameters","when":"currency1 or currency2 is missing or empty.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_parameters","when":"A parameter was sent more than once.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_currency","when":"A code is not 2 to 16 letters and digits.","action":"Fix the request before sending it again."},{"status":"404","code":"price_not_found","when":"No quote links the two currencies, directly or inverted.","action":"Check the pair with GET /v1/get-currencies."},{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."}]}},"/v1/get-currencies":{"get":{"operationId":"get-currencies","summary":"List Available Currencies","description":"Lists all available currencies (crypto and fiat) for price queries. Active fiats come first, then each active crypto symbol once (even when the token runs on several networks), sorted by symbol. For cryptos, name repeats the symbol. An unexpected failure answers 500 internal_error.","tags":["Prices"],"x-required-scopes":["prices:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"success":true,"data":{"currencies":[{"currency":"USD","name":"US Dollar","type":"fiat"},{"currency":"BTC","name":"BTC","type":"crypto"},{"currency":"USDT","name":"USDT","type":"crypto"}],"total":20}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"Unexpected failure."}},"x-errors":[{"status":"500","code":"internal_error","when":"Unexpected failure.","action":"Nothing was changed. Retry later."}]}},"/v1/fixed-wallets/supported":{"get":{"operationId":"fixed-wallets-supported","summary":"Supported Networks","description":"Returns the networks and tokens enabled for fixed addresses.","tags":["Fixed Wallets"],"x-required-scopes":["wallets:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"fixed_wallets_supported_success","supported":[{"type":"evm","label":"EVM","networks":["Ethereum","BinanceSmartChain"],"tokens":[{"network":"Ethereum","token":"USDT","symbol":"USDT"},{"network":"BinanceSmartChain","token":"USDT","symbol":"USDT"}]},{"type":"tron","label":"Tron","networks":["Tron"],"tokens":[{"network":"Tron","token":"USDT","symbol":"USDT"}]}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/fixed-wallets/config":{"get":{"operationId":"fixed-wallets-config-get","summary":"Get Config","description":"Returns the user's fixed addresses config (limits, enabled status and webhook_url). Per-type maps are null when the account uses the single global limit. When a per-type map is set it replaces the global limit of that origin, and types missing from the map cannot be created. Returns 403 feature_disabled if the feature is disabled for the user.","tags":["Fixed Wallets"],"x-required-scopes":["wallets:read"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"fixed_wallets_config_success","config":{"enabled":1,"max_wallets_panel":5,"max_wallets_panel_per_type":null,"max_wallets_external_api":1000,"max_wallets_external_api_per_type":{"evm":800,"tron":200},"webhook_url":"https://your-site.com/webhook-fixed-wallets"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Feature disabled","content":{"application/json":{"examples":{"feature_disabled":{"value":{"error":{"code":"feature_disabled","message":"This feature is not enabled for the account"}}}}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"x-errors":[{"status":"403","code":"feature_disabled","when":"Fixed addresses are not enabled for the account.","action":"Contact support."}]},"put":{"operationId":"fixed-wallets-config-update","summary":"Update Config","description":"Registers, updates or removes the webhook_url for fixed addresses. The webhook_url field is required: send \"\" or null to remove the URL. A body without the field is refused with 400 invalid_parameters instead of clearing the stored URL. Returns 403 feature_disabled if the feature is disabled.","tags":["Fixed Wallets"],"x-required-scopes":["wallets:write"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"fixed_wallets_config_update_success","webhook_url":"https://your-site.com/webhook-fixed-wallets"}}}}}},"400":{"description":"Field missing or invalid","content":{"application/json":{"examples":{"field_missing_or_invalid":{"value":{"error":{"code":"invalid_parameters","message":"Invalid parameters provided","details":{"fields":{"webhook_url":"The webhook_url field is required; send an empty value to remove it."}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Fixed addresses are not enabled for the account."},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"The change could not be saved."}},"x-errors":[{"status":"400","code":"invalid_parameters","when":"webhook_url is missing, not a string or null, not a valid URL, or longer than 756 characters; details.fields explains.","action":"Fix the request before sending it again."},{"status":"400","code":"invalid_webhook_url","when":"The URL is well formed but not allowed (not HTTPS, private address, non-standard port).","action":"Fix the request before sending it again."},{"status":"403","code":"feature_disabled","when":"Fixed addresses are not enabled for the account.","action":"Contact support."},{"status":"500","code":"config_update_failed","when":"The change could not be saved.","action":"Nothing was changed. Retry later."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"webhook_url":{"type":["string","null"],"description":"Callback URL for fixed address deposit notifications. Must be a valid, public HTTPS URL (max 756 chars); private or reserved hosts and blocked ports are refused. Send \"\" or null to remove it."}},"required":["webhook_url"]},"example":{"webhook_url":"https://your-site.com/webhook-fixed-wallets"}}}}}},"/v1/fixed-wallets":{"get":{"operationId":"list-fixed-wallets","summary":"List Fixed Wallets","description":"Lists the fixed addresses assigned to your account via the external API, with optional filters, newest first. Addresses created in the panel are not listed. count is the number of items in this page, not a grand total. allowance is the remaining creation budget for the external API origin, in one of two shapes: mode global ({limit, used, remaining, supported_types}, shared by every type) or mode per_type ({items: [{type, label, limit, used, remaining}]}, one entry per type you may create). allowance is null when fixed addresses are not enabled for the account (the list itself still answers 200). In global mode used counts every address ever assigned through the API, revoked ones included; in per_type mode only addresses still in STATUS_ASSIGNED count.","tags":["Fixed Wallets"],"x-required-scopes":["wallets:read"],"parameters":[{"name":"type","in":"query","required":false,"description":"Filter by wallet type, lowercase exact match (e.g.: evm, tron, bitcoin)","schema":{"type":"string"},"example":"evm"},{"name":"status","in":"query","required":false,"description":"Filter by status: STATUS_ASSIGNED (active) or STATUS_REVOKED (revoked after inactivity)","schema":{"type":"string"},"example":"STATUS_ASSIGNED"},{"name":"customer_info","in":"query","required":false,"description":"Filter by customer identifier (exact match)","schema":{"type":"string"},"example":"customer123"},{"name":"limit","in":"query","required":false,"description":"Items to return (default: 100). Out-of-range values are clamped to 1..500, not refused.","schema":{"type":"string"},"example":"100"},{"name":"offset","in":"query","required":false,"description":"Number of items to skip (default: 0). Negative values become 0.","schema":{"type":"string"},"example":"0"}],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"fixed_wallets_list_success","wallets":[{"customer_info":"customer123","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","type":"evm","status":"STATUS_ASSIGNED","origin":"external_api","last_transaction_at":null,"created_at":"2026-01-16 10:00:00","updated_at":"2026-01-16 10:00:00","networks":["Ethereum","BinanceSmartChain"],"accepted_tokens":[{"network":"Ethereum","token":"USDT","symbol":"USDT"},{"network":"BinanceSmartChain","token":"USDT","symbol":"USDT"}],"pending_revocation":false,"revoke_at":null}],"count":1,"allowance":{"mode":"global","limit":1000,"used":1,"remaining":999,"supported_types":[{"type":"evm","label":"EVM"},{"type":"tron","label":"Tron"}]}}},"per_type_allowance":{"value":{"message":"fixed_wallets_list_success","wallets":[],"count":0,"allowance":{"mode":"per_type","items":[{"type":"evm","label":"EVM","limit":800,"used":12,"remaining":788},{"type":"tron","label":"Tron","limit":200,"used":0,"remaining":200}]}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"operationId":"create-fixed-wallet","summary":"Create Fixed Wallet","description":"Assigns a fixed (permanent) address to your account for the given chain family (type). A single address serves every network of the same family (e.g. an evm address works across all EVM networks). A new assignment answers 201 with fixed_wallets_assign_success. If customer_info is provided and already has an active (STATUS_ASSIGNED) address of the same type, the existing one is returned with 200 and fixed_wallets_already_assigned. That reuse check ignores origin, so it can return an address created in the panel (origin: panel), which List Fixed Wallets does not show. The reuse is checked before the limits, so it never consumes allowance.","tags":["Fixed Wallets"],"x-required-scopes":["wallets:write"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"examples":{"success":{"value":{"message":"fixed_wallets_assign_success","wallet":{"customer_info":"customer123","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","type":"evm","status":"STATUS_ASSIGNED","origin":"external_api","last_transaction_at":null,"created_at":"2026-01-16 10:00:00","updated_at":"2026-01-16 10:00:00","networks":["Ethereum","BinanceSmartChain"],"accepted_tokens":[{"network":"Ethereum","token":"USDT","symbol":"USDT"}],"pending_revocation":false,"revoke_at":null}}},"existing_address_reused":{"value":{"message":"fixed_wallets_already_assigned","wallet":{"customer_info":"customer123","wallet":"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0","type":"evm","status":"STATUS_ASSIGNED","origin":"external_api","last_transaction_at":"2026-02-03 18:21:07","created_at":"2026-01-16 10:00:00","updated_at":"2026-02-03 18:21:07","networks":["Ethereum","BinanceSmartChain"],"accepted_tokens":[{"network":"Ethereum","token":"USDT","symbol":"USDT"}],"pending_revocation":false,"revoke_at":null}}}}}}},"400":{"description":"type missing or longer than 20, or customer_info with spaces or longer than 255; details.fields."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Fixed addresses are not enabled for the account."},"409":{"description":"Limit reached","content":{"application/json":{"examples":{"limit_reached":{"value":{"error":{"code":"limit_reached","message":"Fixed address limit reached"}}}}}}},"422":{"description":"type is not listed in Supported Networks."},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"description":"The address could not be assigned."},"502":{"description":"The address could not be created right now."}},"x-errors":[{"status":"400","code":"invalid_parameters","when":"type missing or longer than 20, or customer_info with spaces or longer than 255; details.fields.","action":"Fix the request before sending it again."},{"status":"403","code":"feature_disabled","when":"Fixed addresses are not enabled for the account.","action":"Contact support."},{"status":"403","code":"limit_not_allowed","when":"Your limit for this type is zero, or the type is not in your per-type map.","action":"Contact support."},{"status":"409","code":"limit_reached","when":"You already hold the maximum number of fixed addresses.","action":"Check allowance in List Fixed Wallets."},{"status":"409","code":"no_wallet_available","when":"No address of that type is available right now.","action":"Nothing was changed. Retry later."},{"status":"422","code":"type_not_supported","when":"type is not listed in Supported Networks.","action":"Fix the request before sending it again."},{"status":"500","code":"assign_failed","when":"The address could not be assigned.","action":"Nothing was changed. Retry later."},{"status":"502","code":"external_processor_error","when":"The address could not be created right now.","action":"Nothing was changed. Retry later."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"Chain family enabled for fixed addresses (e.g.: evm, tron, solana, bitcoin). See the type field in Supported Networks. Max 20 chars, case-insensitive."},"customer_info":{"type":"string","description":"Customer identifier (no spaces, max 255). Enables idempotent reuse of the same address per customer."}},"required":["type"]},"example":{"type":"evm","customer_info":"customer123"}}}}}}},"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-Bifrost-Invoke"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable snake_case code. Branch on this."},"message":{"type":"string","description":"Free English text for logs."},"details":{"type":"object","additionalProperties":true}}}}}},"responses":{"Unauthorized":{"description":"Missing or invalid API key, or invalid request signature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Scope, IP whitelist, account access or e-mail verification refused the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"TooManyRequests":{"description":"Rate limit or failed-authentication block. Honour Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}