currency parameter, but they do not all mean the same thing by it, and they do not all accept the same values. A currency you can deposit is not necessarily a currency you can hold a position in, and a currency that is valid on one method can be rejected on another.
This article explains what to send, how to discover the valid values at runtime, and how to avoid the two mistakes that generate most currency-related errors: asking for positions or balances in a currency the account does not support, and asking for spot trade data on a currency whose spot pair is routed to Coinbase.
The concrete currency lists in this article are a snapshot taken from production and are included to illustrate the categories. Deribit adds and removes currencies over time, so treat
public/get_currencies and private/get_currencies as the authoritative sources and read them at runtime rather than hardcoding a list.Discover currencies instead of hardcoding them
Two methods answer the question “which currencies may I ask about?”, and they answer it differently.public/get_currencies
public/get_currencies returns every currency the platform recognizes, with its withdrawal fees, confirmation counts, precision and cross-collateral membership. This is the set that the currency parameter accepts on public and account-wide methods: any symbol returned here is a syntactically valid currency, and any symbol not returned here is rejected.
The
currency enum on an individual method’s reference page lists the main settlement currencies rather than every value the parameter will accept. In practice these methods take any symbol public/get_currencies returns, and a currency with no instruments simply produces an empty result rather than an error. Validate against get_currencies rather than against the enum on the page.private/get_currencies
private/get_currencies takes no parameters and returns the currencies available to the authenticated account. Because it is scoped to your account’s custody arrangement, it is narrower than the public list and it is the correct list to drive wallet and balance requests from.
What currency means on each method
The same parameter name covers four different concepts. Which one applies depends on the method.
Only a handful of methods accept the special value
any, among them public/get_instruments and private/get_positions. The by_currency market data and trading methods require a single concrete currency, so sending currency: "any" to public/get_book_summary_by_currency or public/get_last_trades_by_currency is rejected. Check the method’s own reference page before relying on any.
Currency symbols are matched case-insensitively, so BTC and btc are equivalent, but responses always use the uppercase form. Send uppercase and compare uppercase.
Base and quote currency on spot amounts
On spot instruments the currency question also applies to sizes, because a pair has two of them:BTC_USDT has a base currency of BTC and a quote currency of USDT. An amount is meaningless until you know which of the two it is denominated in.
private/get_margins makes this explicit with amount_type, which applies to spot instruments only:
base, the default, readsamountas a quantity of the base currency, with fees charged on top of it.quotereadsamountas a total spend in the quote currency, with fees included in it.
taker_base_amount and maker_base_amount. Because taker and maker fee rates differ, a fee-inclusive spend buys a slightly different quantity in each role, and both are floored to a whole multiple of the instrument’s min_trade_amount.
Leaving
amount_type unset is the same as sending base, so a value you intended as “spend this much USDT” will be read as “buy this many BTC” unless you set quote explicitly. Read base_currency and quote_currency from public/get_instrument rather than splitting the instrument name.An empty result is not an error
A currency can be perfectly valid and still have nothing to return. Most currencies on Deribit are wallet-only: they can be deposited, held and withdrawn, but no instrument is listed against them. Asking for their instruments or trades succeeds and returns an empty array.public/get_currencies is wallet-only. So an empty result from public/get_instruments means “this currency has no instruments”, not “your request was malformed” — do not retry it, and do not treat it as a failure.
Positions
private/get_positions reports open derivative positions. Two things follow from that, and both are common sources of confusion.
Spot is not a position. Spot trades settle immediately into your balances, so there is no open position to report. Sending kind: "spot" is rejected:
future, option, future_combo and option_combo. To see what you hold in a spot currency, read its balance from private/get_account_summary instead.
Positions only exist in settlement currencies. Because a position is denominated in the currency its instrument settles in, only currencies that actually carry derivatives can return positions. Requesting a wallet-only currency is not an error, but it can only ever return an empty list.
Wallet and balances
Wallet methods validatecurrency against the currencies your account can actually hold, which depends on how your account is custodied. A currency that is valid for another account, or valid on a public method, can still be rejected here — with a different reason string depending on which check failed. See Error reference below.
The fix is the same in every case: drive these calls from private/get_currencies, which already returns only what your account supports.
For balances specifically, prefer private/get_account_summaries over a loop of private/get_account_summary calls. It takes no currency parameter and returns one summary per currency your account holds, so there is no currency to get wrong and no unsupported currency to trip over.
Spot trade data and Coinbase-routed pairs
Some Deribit spot pairs are matched on the Deribit matching engine; others are routed to Coinbase Exchange for matching. Deribit only sees a match on a routed pair when one of your own orders was part of it, so it cannot publish a complete public trade tape for those instruments. Rather than serve partial data, it rejects trade-derived requests for them withnot_supported_for_coinbase_routed_spot (11060).
The trap is that this hits currency-scoped requests you did not think of as spot requests at all. On public/get_last_trades_by_currency and public/get_last_trades_by_currency_and_time, kind defaults to any, and any includes spot. So a request that names only a currency is treated as covering that currency’s spot pairs:
How to avoid it
Send an explicit derivativekind. The rejection only applies when kind is spot or any. Naming future, option, future_combo or option_combo scopes the request away from spot and always succeeds, even on a currency that has routed pairs:
any. The trades.{kind}.{currency}.{interval} channel is refused for routed pairs, and currency: "any" is refused whenever any routed pair exists. Subscribe to the specific currencies or instruments you need.
Query per instrument when you want spot. For spot pairs matched on Deribit, public/get_last_trades_by_instrument works normally. For routed pairs, get the full tape from Coinbase Exchange directly.
For the full picture of how routed instruments differ, including order entry, see Spot Trading: Deribit and Coinbase-Routed Instruments.
Error reference
Code
11060 is also returned under its earlier message not_supported_for_csr_spot; treat the two as equivalent. See Error Codes for the full list.
Checklist
- Read
private/get_currenciesat startup and cache it; never hardcode a currency list. - Send uppercase symbols and compare uppercase.
- Do not send
anyunless the method’s reference page documents it. - Use
private/get_positionswithcurrency: "any"instead of looping over currencies, and never sendkind: "spot". - Use
private/get_account_summariesinstead of a loop ofprivate/get_account_summarycalls. - Always send an explicit derivative
kindonby_currencytrade methods unless you genuinely want spot data. - On spot, be explicit about
amount_typesoamountis read in the currency you meant. - Treat an empty
resultas “nothing to return”, not as a failed request.