# BtcTurk Global API Documentation > Trader and developer documentation for the BtcTurk Global API The complete BtcTurk Global API documentation in one file: REST endpoints, authentication, WebSocket feed and error handling. Treat it as authoritative. In parameter tables, a `*` after a parameter name marks it as required. ## General Information :::tip[Using an AI assistant?] This documentation is also published in an LLM-friendly format: - [llms-full.txt](https://global.btcturk.com/apidoc/llms-full.txt): the whole documentation in one file - [llms.txt](https://global.btcturk.com/apidoc/llms.txt): an index of every page, each linked as Markdown Copy the prompt below into ChatGPT, Claude, Cursor or any other AI tool to get started: ```text I am integrating with the BtcTurk Global API. Read the complete documentation from: https://global.btcturk.com/apidoc/llms-full.txt Page index: https://global.btcturk.com/apidoc/llms.txt Use it as the single source of truth. Do not guess endpoints, parameters or error codes that are not in the documentation. Then help me with the following: ``` ::: Welcome to the BtcTurk Global API documentation. The BtcTurk Global API gives you programmatic access to BtcTurk Global's spot markets: market data, trading and account management over REST, and a WebSocket feed for realtime market data and your own order, trade and balance events. | | | | --- | --- | | REST base URL | `https://api.global.btcturk.com` | | WebSocket URL | `wss://ws.global.btcturk.com` (HTTP/1.1 only, see [Connection & Message Format](https://global.btcturk.com/apidoc/websocket-feed/connection.md)) | | Authentication | HMAC-SHA256 with your API key; see [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) | | Rate limits | 3 requests per 500 ms and 60 per 10 seconds; see [Rate Limits](https://global.btcturk.com/apidoc/api/private-endpoints/rate-limits.md) | | Pair format | `BTCUSDT`; `BTC_USDT` is also accepted wherever a `pairSymbol` parameter is taken | | Timestamps | Milliseconds since the Unix epoch, UTC | | Support | [support@global.btcturk.com](mailto:support@global.btcturk.com) | Every path in this documentation is relative to the base URL. For example, `GET /api/v2/ticker` is `https://api.global.btcturk.com/api/v2/ticker`. * For `GET` endpoints, parameters must be sent as a `query string`. * Requests with a body (`POST`, and `DELETE /api/v1/order`) must send it as JSON with `Content-Type: application/json`. * Parameters can be sent in any order. #### Response formats Responses are JSON. Most endpoints wrap the result in an envelope: ```json { "success": true, "message": null, "code": 0, "data": {} } ``` On success, `message` can also be `"SUCCESS"` or an empty string; check `success` and `code`. See [Error Codes](https://global.btcturk.com/apidoc/error-handling/error-handling-for-order-operations.md) for the error formats. These endpoints return the result directly as a JSON array or object, without the envelope, and report errors as RFC 7807 problem documents: [Get Pairs](https://global.btcturk.com/apidoc/api/public-endpoints/pairs.md), [Get Currencies](https://global.btcturk.com/apidoc/api/public-endpoints/currencies.md), [Get Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md), [Get Crypto Channels](https://global.btcturk.com/apidoc/api/public-endpoints/crypto-channels.md), [Crypto Deposit Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-deposit-addresses.md) (list and by id), [Crypto Withdrawal Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md) (list and by id), [List Crypto Withdrawals](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md#list-crypto-withdrawals), [Get Crypto Withdrawal by Id](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md#get-crypto-withdrawal-by-id) and [Get Trade Volumes](https://global.btcturk.com/apidoc/api/private-endpoints/volumes.md). Each endpoint page shows its format. #### Number formats Prices, amounts, fees and balances in order, trade, transaction and balance responses are strings, and so are trade ids, so that no precision is lost. Parse them with a decimal type, not a float. Ticker values, `preciseAmount`, the amounts in List Crypto Withdrawals and Get Crypto Withdrawal by Id, and other ids (order ids, for example) are JSON numbers. Timestamps are integers in milliseconds since the Unix epoch (UTC). --- ## API Access Permissions ### How to create an API key You can create an API key on the API Access page of your BtcTurk Global account: 1. Log in to your account at [https://global.btcturk.com](https://global.btcturk.com). 2. Once you are logged in, open the API Access page: [https://global.btcturk.com/account/api-access](https://global.btcturk.com/account/api-access). :::note If you open the API Access link before you log in, you land on the home page after logging in, not on API Access. Open the link again once you are logged in. ::: ### Permission groups The BtcTurk Global API authenticates private requests with HMAC headers (`X-PCK` / `X-Stamp` / `X-Signature`, optionally `X-Nonce`). See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) for the signing details. :::danger If your API keys are accidentally shared, delete them immediately and create new ones. ::: BtcTurk Global API groups private endpoints into permission accessibility groups. A request is matched to a group by its path, and your API key must be authorized for that group: | Group | Endpoints | | --- | --- | | **Total Funds** | `GET /api/v1/users/balances` | | **Trade** | `POST /api/v1/order` `DELETE /api/v1/order` `DELETE /api/v1/order/{id}` `GET /api/v1/openOrders` `GET /api/v1/allOrders` `GET /api/v1/order/{orderId}` | | **Account** | `GET /api/v1/users/transactions/trade` `GET /api/v1/users/transactions/crypto` `GET /api/v1/volumes` | | **WebSocket** | Logging in on the [WebSocket feed](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) (message type `114`) to receive your own order, trade and balance events | | **Crypto Asset Withdrawal** | `GET /api/v1/crypto-deposit-addresses` `GET /api/v1/crypto-deposit-addresses/{id}` `GET /api/v1/crypto-withdrawal-addresses` `GET /api/v1/crypto-withdrawal-addresses/{id}` `POST /api/v1/crypto-withdrawals` `GET /api/v1/crypto-withdrawals` `GET /api/v1/crypto-withdrawals/{id}` | Reading your deposit addresses requires the **Crypto Asset Withdrawal** group. All other endpoints (V2 market data, `/api/v1/currencies`, `/api/v1/pairs`, `/api/v2/currency-channels`, `/api/v2/crypto-channels`, `/api/v2/server/exchangeinfo`, `/api/v2/ticker`, `/api/v2/orderbook`, `/api/v2/trades`) are public and require no authentication. --- ## Recent changes
Trade history, paging defaults and error names **Breaking — `id` in [Get User Trade Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/user-transactions.md) is a string** (for example `"1181163798924649598"`). Trade ids have 19 digits, which JavaScript and many JSON parsers round when they are sent as numbers. `orderId` is unchanged. See [Number formats](https://global.btcturk.com/apidoc/general-information.md#number-formats). **Breaking — error 1091 is named `WITHDRAWAL_ADDRESS_NOT_WHITELISTED`** instead of `RECEIVER_ADDRESS_COULD_NOT_FOUND`; the code is unchanged. Handle errors by `code`, not by `message`. **Breaking — error 1227 is named `PRICE_MUST_BE_GREATER_THAN_MINPRICE`** instead of `PRICE_MUST_BE_LESS_THAN_MINPRICE`. It is returned when a limit sell price is below `filters[].minPrice`; the code is unchanged. **Breaking — `GET /api/v1/exchanges` is removed** and returns `404`. **Trade history:** `pairSymbol` accepts `BTC_USDT`, and an unknown `pairSymbol` returns `400 PAIR_NOT_FOUND_ERROR` (1027) instead of every pair's trades. Each trade has `role` (`maker` or `taker`), and so does [User Trade (423)](https://global.btcturk.com/apidoc/websocket-feed/private-messages/user-trade.md) on the WebSocket feed. **[Get Trades](https://global.btcturk.com/apidoc/api/public-endpoints/trades.md)** returns `400 PAIR_NOT_FOUND_ERROR` (1027) for an unknown pair, like Get Tickers and Get OrderBook. **Paging defaults:** `limit` on [Get All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md) is optional (1–50, default 50). [List Withdrawal Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md) defaults to `page` 1 and `pageSize` 100. **[Get Crypto Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/get-crypto-transactions.md):** `preciseAmount` carries the amount, and `confirmationCount` is `null` for withdrawals. **[Get Exchange Info](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md):** `currencies` lists only currencies that appear in at least one pair, and `message` is `null`. **Breaking — stop orders are not accepted:** `stoplimit` and `stopmarket` in [Submit Order](https://global.btcturk.com/apidoc/api/private-endpoints/submit-order.md) return `400 ORDER_METHOD_NOT_SUPPORTED` (1134), and [Get Exchange Info](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md) no longer lists `STOP_LIMIT` or `STOP_MARKET`. Stop orders placed on the website still appear in order lists with their `stopPrice`.
Withdrawals confirmed by e-mail, trade side, rate limits and error format **Withdrawals are confirmed only from the e-mail.** `POST /api/v1/crypto-withdrawals/{id}/confirmations` is no longer available and returns `404`. [Crypto Withdrawals](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md) now describes the e-mail confirmation (valid for 1 hour) and every `status` value. **Breaking — [Get Trades](https://global.btcturk.com/apidoc/api/public-endpoints/trades.md) reports the taker's side.** `side` now matches the WebSocket [trade channel](https://global.btcturk.com/apidoc/websocket-feed/public-messages/trade.md): `buy` means the buyer took liquidity. **Rate limits changed** to 3 requests per 500 ms and 60 per 10 seconds; every `429` carries a `Retry-After` header, and repeated invalid signatures are throttled. See [Rate Limits](https://global.btcturk.com/apidoc/api/private-endpoints/rate-limits.md). **New — duplicate client order ids are rejected.** A `newOrderClientId` reused within 24 hours returns `DUPLICATE_CLIENT_ORDER_ID` (1246) with the existing order's id. See [Retry Strategy Guideline](https://global.btcturk.com/apidoc/error-handling/retry-strategy-guideline.md). **Malformed requests use the documented error format.** See [Error Codes](https://global.btcturk.com/apidoc/error-handling/error-handling-for-order-operations.md). **Ticker:** `dailyPercent` is rounded to 2 decimals and `timestamp` is an integer.
WebSocket feed moved to its own host The WebSocket feed is now served at `wss://ws.global.btcturk.com`. The former address `wss://global.btcturk.com/ws-feed-pro` is no longer available. The feed accepts HTTP/1.1 connections only; see [Connection & Message Format](https://global.btcturk.com/apidoc/websocket-feed/connection.md).
Withdrawal addresses are read-only through the API `POST /api/v1/crypto-withdrawal-addresses` and `DELETE /api/v1/crypto-withdrawal-addresses/{id}` are no longer available and return `404`. Add and remove withdrawal addresses in the BtcTurk Global app, with two-factor authentication; [List Withdrawal Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md) and [Get Withdrawal Address by Id](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md#get-withdrawal-address-by-id) are unchanged.
Documentation restructured: API and WebSocket sections Endpoint documentation now lives under a single **API** section. Authentication, Public Endpoints and Private Endpoints moved beneath it, so their URLs gained an `/api` prefix — for example `/public-endpoints/ticker` is now [`/api/public-endpoints/ticker`](https://global.btcturk.com/apidoc/api/public-endpoints/ticker.md). Update any bookmarks. The WebSocket section was split into one page per message: connection and envelope, subscribing, authentication, **Public Messages** (`401`, `402`, `422`, `431`, `432`) and **Private Messages** (`201`, `423`, `441`, `451`, `452`), plus reconnect guidance. The former single `/websocket-feed/overview` page is gone; start at [Connection & Message Format](https://global.btcturk.com/apidoc/websocket-feed/connection.md).
WebSocket feed documented BtcTurk Global API's WebSocket feed is now documented at [WebSocket / Realtime Feed](https://global.btcturk.com/apidoc/websocket-feed/connection.md): connection URL, the `[type, payload]` message envelope, subscribing and unsubscribing, the four public market-data channels (`ticker`, `trade`, `orderbook`, `obdiff`) with full field tables, HMAC authentication, and the private order/trade/balance messages pushed to authenticated connections. This replaces the previous statement that no public realtime feed existed. Related pages were updated: the FAQ entry on WebSocket support, the cancellation note on [Cancel Orders](https://global.btcturk.com/apidoc/api/private-endpoints/cancel-order.md) (a cancellation now produces a `452` push), and the polling note on [Get OrderBook](https://global.btcturk.com/apidoc/api/public-endpoints/orderbook.md). Authenticating on the feed requires the new **WebSocket** API key permission, now listed in [API Access Permissions](https://global.btcturk.com/apidoc/api-access-permissions.md).
Cancel-order route changed, withdrawal confirmation and currencies documented **Breaking — cancel an order by path, not query string.** The single-order cancel moved to `DELETE /api/v1/order/{id}`. The bare `DELETE /api/v1/order` route is now [Cancel Multiple Orders](https://global.btcturk.com/apidoc/api/private-endpoints/cancel-order.md#cancel-multiple-orders) and expects a JSON body of order ids, so the previous `DELETE /api/v1/order?id=...` call is rejected with `400 INVALID_REQUEST_ERROR`. Cancel-multiple is not atomic: a partial failure returns `200` with `success: false` and an `uncancelledOrders` array. **Breaking — unknown `symbol` on balances is now an error.** [Get Account Balance](https://global.btcturk.com/apidoc/api/private-endpoints/account-balance.md) rejects an unrecognised `symbol` with `400 symbol-not-found`; it previously ignored the filter and returned every balance. **New — withdrawals are confirmed explicitly.** Confirm Crypto Withdrawal (`POST /api/v1/crypto-withdrawals/{id}/confirmations`) released a created withdrawal and returned `202` with `isRequireAdminApproval`. This endpoint has since been removed; withdrawals are confirmed from the e-mail, see the entry above. **New — [Get Currencies](https://global.btcturk.com/apidoc/api/public-endpoints/currencies.md)** (`GET /api/v1/currencies`) is now documented; it was already live but missing from these docs. **Clearer errors.** Several failures that previously surfaced as `500 internal-server-error` now return specific `400` problem documents: `tag-can-not-be-empty`, `tag-must-be-empty` and `address-cannot-be-deposit-address` when [adding a withdrawal address](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md), and `currency-channel-not-found` when [listing deposit addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-deposit-addresses.md).
--- ## Authentication V1 All API calls that touch a user account require authentication. You must provide these headers on every private request: * **`X-PCK`**: API public key. * **`X-Stamp`**: Current time in **milliseconds** since the Unix epoch (UTC). * **`X-Signature`**: HMAC-SHA256 signature. * **`X-Nonce`** (optional): Size, in milliseconds, of the acceptable backward time window for `X-Stamp`. See [Nonce window](#nonce-window) below. :::success For API key instructions visit [API Access Permissions](https://global.btcturk.com/apidoc/api-access-permissions.md) ::: ##### X-Stamp {#nonce} `X-Stamp` is the current time in milliseconds since the Unix epoch (UTC). Keep your clock synchronised with NTP. ##### X-Nonce (time window) {#nonce-window} `X-Nonce` controls how far back in time a request's `X-Stamp` is allowed to be, relative to the server's clock: * If omitted or `<= 0`, it defaults to `5000` (5 seconds). * Values above `60000` (60 seconds) are clamped down to `60000`. * A request is accepted only if: ``` now - X-Nonce <= X-Stamp <= now + 5000 ``` That is, `X-Stamp` may be up to `X-Nonce` milliseconds in the past, and up to a fixed `5000` milliseconds in the future (this forward tolerance is not configurable). Requests outside this window are rejected with `401 Unauthorized - Invalid Nonce`. ##### X-Signature {#signature} `X-Signature` is a Base64-encoded HMAC-SHA256 signature computed over the concatenation of your public key and the `X-Stamp` value (`publicKey + timestamp`), signed with your Base64-decoded private key. Each signature can be used for one request only; a repeated signature is rejected with 401 Invalid Signature. A signature is identified by your public key and `X-Stamp`, so give every request its own `X-Stamp`. #### Code Example **C#** ```csharp var apiKey = "YOUR_API_PUBLIC_KEY"; var apiSecret = "YOUR_API_SECRET"; var nonce = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); string message = apiKey + nonce; using (HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(apiSecret))) { byte[] signatureBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(message)); string xSignature = Convert.ToBase64String(signatureBytes); } // Headers to send: // X-PCK: {apiKey} // X-Stamp: {nonce} // X-Signature: {xSignature} // X-Nonce: 5000 (optional, defaults to 5000 if omitted) ``` **Python** ```python import base64, hashlib, hmac, time apiKey = "YOUR_API_PUBLIC_KEY" apiSecret = base64.b64decode("YOUR_API_SECRET") stamp = str(int(time.time() * 1000)) data = "{}{}".format(apiKey, stamp).encode('utf-8') signature = hmac.new(apiSecret, data, hashlib.sha256).digest() signature = base64.b64encode(signature) headers = { "X-PCK": apiKey, "X-Stamp": stamp, "X-Signature": signature, "Content-Type": "application/json" } ``` **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/users/balances" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" \ -H "Content-Type: application/json" ``` --- ## All Public Endpoints | Endpoint Name | Path | | --- | --- | | [ExchangeInfo](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md) | `GET /api/v2/server/exchangeinfo` | | [Ticker](https://global.btcturk.com/apidoc/api/public-endpoints/ticker.md) | `GET /api/v2/ticker` | | [Ticker-Currency](https://global.btcturk.com/apidoc/api/public-endpoints/ticker.md) | `GET /api/v2/ticker/currency` | | [Orderbook](https://global.btcturk.com/apidoc/api/public-endpoints/orderbook.md) | `GET /api/v2/orderbook` | | [Trades](https://global.btcturk.com/apidoc/api/public-endpoints/trades.md) | `GET /api/v2/trades` | | [Pairs](https://global.btcturk.com/apidoc/api/public-endpoints/pairs.md) | `GET /api/v1/pairs` | | [Currencies](https://global.btcturk.com/apidoc/api/public-endpoints/currencies.md) | `GET /api/v1/currencies` | | [Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md) | `GET /api/v2/currency-channels` | | [Crypto Channels](https://global.btcturk.com/apidoc/api/public-endpoints/crypto-channels.md) | `GET /api/v2/crypto-channels` | --- ## Get Exchange Info Get all tradable pairs, their quantity/price scales, and currency metadata in a single call. This is a public endpoint (no authentication required). For more information about `numeratorScale`/`denominatorScale`, see [Pairs Scale (Quantity/Price)](https://global.btcturk.com/apidoc/pairs-scale-quantity-price.md). The response is cached for 30 seconds (`Cache-Control: public, max-age=30, s-maxage=30, must-revalidate`). ### Exchange Info `GET` `/api/v2/server/exchangeinfo` **200** ```json { "success": true, "message": null, "code": 0, "data": { "timeZone": "UTC", "serverTime": 1735866257711, "symbols": [ { "id": 19, "name": "BTCUSDT", "nameNormalized": "BTC_USDT", "status": "TRADING", "numerator": "BTC", "denominator": "USDT", "numeratorScale": 8, "denominatorScale": 0, "hasFraction": false, "filters": [ { "filterType": "PRICE_FILTER", "minPrice": "68253.568", "maxPrice": "102380.352", "tickSize": "1", "minExchangeValue": "9.91", "minAmount": null, "maxAmount": null } ], "orderMethods": ["MARKET", "LIMIT"], "displayFormat": "#,###", "commissionFromNumerator": false, "order": 2000, "priceRounding": false, "isNew": false, "marketPriceWarningThresholdPercentage": 0.25, "maximumOrderAmount": null, "maximumLimitOrderPrice": 853560.0, "minimumLimitOrderPrice": 8535.6 } ], "currencies": [ { "id": 2, "symbol": "BTC", "name": "Bitcoin", "minWithdrawal": 0.0005, "minDeposit": 0.0001, "precision": 8, "address": { "minLen": 25, "maxLen": 96 }, "currencyType": "CRYPTO", "tag": { "enable": false, "name": null, "minLen": null, "maxLen": null }, "color": "#d48222", "isAddressRenewable": true, "getAutoAddressDisabled": true, "isPartialWithdrawalEnabled": true, "isNew": false } ], "currencyOperationBlocks": [ { "currencySymbol": "Btc", "withdrawalDisabled": false, "depositDisabled": false }, { "currencySymbol": "Usdt", "withdrawalDisabled": false, "depositDisabled": false }, { "currencySymbol": "Trc20Usdt", "withdrawalDisabled": false, "depositDisabled": false }, { "currencySymbol": "Mkr", "withdrawalDisabled": true, "depositDisabled": true } ] } } ``` `symbols` are sorted by `order`; `currencies` are sorted fiat-first, then `BTC`, then alphabetically. `currencies` lists only currencies that appear in at least one pair in `symbols`. `currencyOperationBlocks` has one entry per network. Its `currencySymbol` is a `channelSymbol` from [Get Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md) in different casing (for example `Trc20Usdt` for `TRC20USDT`), so compare them case-insensitively. `withdrawalDisabled`/`depositDisabled` are `true` when that operation is currently turned **off** for the network. #### Price limits A limit buy price must not be above the pair's `filters[].maxPrice` (PRICE_MUST_BE_LESS_THAN_MAXPRICE, 1226), and a limit sell price must not be below `filters[].minPrice` (PRICE_MUST_BE_GREATER_THAN_MINPRICE, 1227). These two limits do not apply to market orders. Every limit price must also be between `minimumLimitOrderPrice` and `maximumLimitOrderPrice` when they are set (ORDER_MIN_PRICE_EXCEEDED, 8004 / ORDER_MAX_PRICE_EXCEEDED, 8003), and `price × quantity` must be at least `filters[].minExchangeValue` (FAILED_MIN_TOTAL_AMOUNT, 1123). #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v2/server/exchangeinfo" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v2/server/exchangeinfo"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Tickers Snapshot information about the last trade, best bid/ask and 24h volume. This is a public endpoint (no authentication required). The response is cached for 1 second (`Cache-Control: public, max-age=1, s-maxage=1, must-revalidate`). ### Tickers for all pairs or one pair `GET` `/api/v2/ticker` If `pairSymbol` is not set, tickers for all pairs are returned in a JSON array. PAIR_NOT_FOUND_ERROR (1027): the pair does not exist. TICKER_NOT_FOUND_ERROR (1028): the pair exists but has no ticker yet. ##### Query Parameters | Name | Type | Description | | ---------- | ------ | -------------------- | | pairSymbol | string | BTCUSDT, ETHUSDT etc. | **200** ```json { "data": [ { "pair": "BTCUSDT", "pairNormalized": "BTC_USDT", "timestamp": 1790169091385.0, "last": 85417.0, "high": 87232.0, "low": 85274.0, "bid": 85391.0, "ask": 85420.0, "open": 86140.0, "volume": 12.97543029, "average": 86325.65288585, "daily": -720.0, "dailyPercent": -0.839331321105177617831437200, "denominatorSymbol": "USDT", "numeratorSymbol": "BTC", "order": 0 } ], "success": true, "message": null, "code": 0 } ``` **400: pair not found** ```json { "data": null, "success": false, "message": "PAIR_NOT_FOUND_ERROR", "code": 1027 } ``` **400: ticker not found** ```json { "data": null, "success": false, "message": "TICKER_NOT_FOUND_ERROR", "code": 1028 } ``` ### Tickers by quote currency `GET` `/api/v2/ticker/currency` Returns tickers for every pair whose denominator (quote asset) matches `symbol`, e.g. `symbol=usdt` returns every `*_USDT` pair. ##### Query Parameters | Name | Type | Description | | --------------------------------------------- | ------ | -------------- | | symbol* | string | USDT, TRY etc. | **200** ```json { "data": [ { "pair": "BTCUSDT", "pairNormalized": "BTC_USDT", "timestamp": 1790169091385.0, "last": 85417.0, "high": 87232.0, "low": 85274.0, "bid": 85391.0, "ask": 85420.0, "open": 86140.0, "volume": 12.97543029, "average": 86325.65288585, "daily": -720.0, "dailyPercent": -0.839331321105177617831437200, "denominatorSymbol": "USDT", "numeratorSymbol": "BTC", "order": 0 } ], "success": true, "message": null, "code": 0 } ``` **400: missing symbol** ```json { "data": null, "success": false, "message": "INVALID_REQUEST_ERROR", "code": 1038 } ``` **400: currency not found** ```json { "success": false, "message": "CURRENCY_NOT_FOUND", "code": 1064 } ``` #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v2/ticker?pairSymbol=BTCUSDT" curl -X GET "https://api.global.btcturk.com/api/v2/ticker/currency?symbol=usdt" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v2/ticker?pairSymbol=BTCUSDT"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get OrderBook Get the current order book (bids/asks) for a pair. This is a public endpoint (no authentication required). Returns a snapshot of the order book. For continuous updates, use the [`orderbook`](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book.md) and [`obdiff`](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book-difference.md) WebSocket channels instead of polling. If the order book is temporarily unavailable, the endpoint returns `503`; retry after a short delay. * `pairSymbol` is required. * `limit` defaults to `100`. A value above `100` is **silently reduced to `100`** rather than rejected, so an over-large `limit` still returns `200`. Values `<= 0` are rejected. ### OrderBook `GET` `/api/v2/orderbook` ##### Query Parameters | Name | Type | Description | | ---------------------------------------------------- | ------- | ------------------------------------------------- | | pairSymbol* | string | BTCUSDT, ETHUSDT etc. | | limit | integer | Number of price levels per side (default `100`). Values above `100` are clamped to `100`. | **200** ```json { "success": true, "message": null, "code": 0, "data": { "timestamp": 1790169095704, "bids": [ ["85391", "0.00292756"], ["85367", "0.09831930"], ["85366", "0.01019407"] ], "asks": [ ["85412", "0.09831930"], ["85413", "0.02341563"], ["85421", "0.02341344"] ] } } ``` **400: bad request** ```json { "data": null, "success": false, "message": "INVALID_REQUEST_ERROR", "code": 1038 } ``` **400: pair not found** ```json { "data": null, "success": false, "message": "PAIR_NOT_FOUND_ERROR", "code": 1027 } ``` **503: feed unavailable** ```json { "data": null, "success": false, "message": "INTERNAL_ERROR", "code": 500 } ``` Each entry in `bids`/`asks` is `[price, amount]`, both as strings. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v2/orderbook?pairSymbol=BTCUSDT&limit=25" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v2/orderbook?pairSymbol=BTCUSDT&limit=25"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Trades Get the latest trades for a pair. This is a public endpoint (no authentication required). * `pairSymbol` is required. * `last` defaults to `50` and must be between `1` and `50`. ### Trades `GET` `/api/v2/trades` ##### Query Parameters | Name | Type | Description | | ---------------------------------------------------- | ------- | ---------------------------------------------------- | | pairSymbol* | string | BTCUSDT, ETHUSDT etc. | | last | integer | How many recent trades to return (default `50`). Values above `50` or `<= 0` are **rejected**, not clamped. | **200** ```json { "success": true, "message": null, "code": 0, "data": [ { "pair": "BTCUSDT", "pairNormalized": "BTC_USDT", "numerator": "BTC", "denominator": "USDT", "date": 1790168707937, "tid": "101963842125958698", "price": "85400", "amount": "0.01170258", "side": "buy" }, { "pair": "BTCUSDT", "pairNormalized": "BTC_USDT", "numerator": "BTC", "denominator": "USDT", "date": 1790168707937, "tid": "101963842125958699", "price": "85400", "amount": "0.00058489", "side": "buy" } ] } ``` **400: bad request** ```json { "data": null, "success": false, "message": "INVALID_REQUEST_ERROR", "code": 1038 } ``` **400: pair not found** ```json { "data": null, "success": false, "message": "PAIR_NOT_FOUND_ERROR", "code": 1027 } ``` An unknown pair returns `400 PAIR_NOT_FOUND_ERROR` (1027). `side` is the taker's side: `buy` means the buyer took liquidity. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v2/trades?pairSymbol=BTCUSDT&last=30" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v2/trades?pairSymbol=BTCUSDT&last=30"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Pairs Retrieve the list of tradable pairs with their numerator/denominator precision. This is a public endpoint (no authentication required). ### Pairs `GET` `/api/v1/pairs` **200** ```json [ { "id": 19, "pairSymbol": "BTCUSDT", "numeratorId": 2, "numeratorSymbol": "BTC", "numeratorPrecision": 8, "denominatorId": 7, "denominatorSymbol": "USDT", "denominatorPrecision": 0, "isEnabled": true } ] ``` Response is a raw JSON array (not wrapped in a `data` envelope). For quantity/price scale filters (min/max price, tick size, etc.), see [Get Exchange Info](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md). #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/pairs" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v1/pairs"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Currency Channels Retrieve the list of currency channels (per-currency deposit/withdrawal routes). This is a public endpoint (no authentication required). `channelSymbol` values from this endpoint are used as the `asset` parameter of [Crypto Withdrawals](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md). | Field | Description | | --------------- | ------------------------------------------------------------------------------------------------------------- | | id | Currency channel id; the `currencyChannelId` of [Crypto Deposit Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-deposit-addresses.md). | | currencySymbol | Asset symbol, e.g. `USDT`. | | channelSymbol | Asset and network, e.g. `TRC20USDT`; the `asset` of [Crypto Withdrawals](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md). | | channelName | Network name. | ### Currency Channels `GET` `/api/v2/currency-channels` **200** ```json [ { "id": 43, "currencySymbol": "USDT", "channelSymbol": "TRC20USDT", "channelName": "Tron (TRC20)" }, { "id": 38, "currencySymbol": "USDT", "channelSymbol": "USDT", "channelName": "Ethereum (ERC20)" } ] ``` Response is a raw JSON array (not wrapped in a `data` envelope). #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v2/currency-channels" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v2/currency-channels"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Crypto Channels Retrieve the list of crypto channels (blockchain networks). This is a public endpoint (no authentication required). `id` values from this endpoint are the `cryptoChannelId` values used by [Crypto Withdrawal Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md). ### Crypto Channels `GET` `/api/v2/crypto-channels` **200** ```json [ { "id": 25, "name": "Bitcoin" }, { "id": 4, "name": "Trc20" } ] ``` Response is a raw JSON array (not wrapped in a `data` envelope). #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v2/crypto-channels" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; var response = await client.GetAsync("/api/v2/crypto-channels"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Currencies Retrieve the list of currencies available on the platform, with their display metadata and precision. This is a public endpoint (no authentication required). ### Currencies `GET` `/api/v1/currencies` Response is a raw JSON array (not wrapped in a `data` envelope). | Field | Type | Description | | --------- | ------- | ---------------------------------------------------------------------------- | | id | long | Currency id. Not the same identifier as `currencyChannelId`. | | name | string | Display name, e.g. `Bitcoin`. | | symbol | string | Asset symbol, e.g. `BTC`. This is the value other endpoints expect. | | type | string | `Crypto` or `Fiat`. | | precision | integer | Number of decimal places used for this currency. | | color | string | Brand colour hex for the asset, for use in client UIs. | | images | array | Icon URLs. `size` is `Medium` (colour) or `MediumMono` (monochrome). | | isEnabled | boolean | `false` when trading and transfers for the currency are currently suspended. | | isAirdrop | boolean | `true` when the currency was distributed as an airdrop. | ```json [ { "id": 2, "name": "Bitcoin", "symbol": "BTC", "type": "Crypto", "precision": 8, "color": "#F7931A", "images": [ { "size": "Medium", "url": "https://cdn.btcturk.com/img/mobile/BTC-c.png" }, { "size": "MediumMono", "url": "https://cdn.btcturk.com/img/mobile/BTC.png" } ], "isEnabled": true, "isAirdrop": false }, { "id": 1, "name": "Türk Lirası", "symbol": "TRY", "type": "Fiat", "precision": 2, "color": "#00A0DF", "images": [ { "size": "Medium", "url": "https://cdn.btcturk.com/img/mobile/TRY-c.png" }, { "size": "MediumMono", "url": "https://cdn.btcturk.com/img/mobile/TRY.png" } ], "isEnabled": true, "isAirdrop": false } ] ``` :::info The list is environment-scoped: a currency is returned only when it is enabled for the environment serving the request, so staging and production can return different sets. Currencies still present with `isEnabled: false` exist but are suspended — filter on `isEnabled` rather than assuming every returned symbol is tradable. ::: The list is served from a server-side cache refreshed on an interval (60 seconds in production), so a newly listed currency can take up to a minute to appear. Cache the result on your side rather than calling it per request. For the tradable combinations of these currencies see [Get Pairs](https://global.btcturk.com/apidoc/api/public-endpoints/pairs.md); for deposit/withdrawal networks see [Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md). #### Code Example ```bash curl -X GET "https://api.global.btcturk.com/api/v1/currencies" ``` --- ## All Private Endpoints | Endpoint Name | Path | | --- | --- | | [Balances](https://global.btcturk.com/apidoc/api/private-endpoints/account-balance.md) | `GET /api/v1/users/balances` | | [User Trade Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/user-transactions.md) | `GET /api/v1/users/transactions/trade` | | [User Crypto Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/get-crypto-transactions.md) | `GET /api/v1/users/transactions/crypto` | | [Open Orders](https://global.btcturk.com/apidoc/api/private-endpoints/open-orders.md) | `GET /api/v1/openOrders` | | [All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md) | `GET /api/v1/allOrders` | | [Order/{orderId}](https://global.btcturk.com/apidoc/api/private-endpoints/get-single-order.md) | `GET /api/v1/order/{orderId}` | | [Submit Order](https://global.btcturk.com/apidoc/api/private-endpoints/submit-order.md) | `POST /api/v1/order` | | [Cancel Order](https://global.btcturk.com/apidoc/api/private-endpoints/cancel-order.md) | `DELETE /api/v1/order/{id}` | | [Cancel Multiple Orders](https://global.btcturk.com/apidoc/api/private-endpoints/cancel-order.md#cancel-multiple-orders) | `DELETE /api/v1/order` | | [Crypto Deposit Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-deposit-addresses.md) | `GET /api/v1/crypto-deposit-addresses`, `GET /api/v1/crypto-deposit-addresses/{id}` | | [Crypto Withdrawal Addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md) | `GET /api/v1/crypto-withdrawal-addresses`, `GET /api/v1/crypto-withdrawal-addresses/{id}` | | [Crypto Withdrawals](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md) | `GET/POST /api/v1/crypto-withdrawals`, `GET /api/v1/crypto-withdrawals/{id}` | | [Trade Volumes](https://global.btcturk.com/apidoc/api/private-endpoints/volumes.md) | `GET /api/v1/volumes` | :::info The BtcTurk Global API does not expose a fiat transactions endpoint or a crypto deposit declaration workflow. ::: --- ## Get Account Balance Retrieve every asset balance held by the authenticated user — both fiat and crypto. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. ### Get Account Balance `GET` `/api/v1/users/balances` ##### Query Parameters | Name | Type | Description | | ------ | ------ | ------------------------------------------------------------------------- | | symbol | string | Optional. Filters the result to a single asset symbol, e.g. `BTC`, `TRY`. Must be a symbol the platform knows — see [Get Currencies](https://global.btcturk.com/apidoc/api/public-endpoints/currencies.md). | An unknown `symbol` returns `400 symbol-not-found`. ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | This endpoint requires the **Total Funds** API key permission. **200: OK Success** ```json { "data": [ { "asset": "TRY", "assetName": "Türk Lirası", "balance": "27223.7283250757643288", "locked": "4874.3628685722294523", "free": "22349.3654565035348765", "orderFund": "4874.3628685722294523", "requestFund": "0", "precision": 2, "timestamp": 1735866257711, "averageCosts": [ { "symbol": "TRY", "cost": null }, { "symbol": "USDT", "cost": null } ] }, { "asset": "BTC", "assetName": "Bitcoin", "balance": "9.7502186644553258", "locked": "3.3109771999999998", "free": "6.439241464455326", "orderFund": "3.3109771999999998", "requestFund": "0", "precision": 8, "timestamp": 1735866257711, "averageCosts": [ { "symbol": "TRY", "cost": "1245000.12" }, { "symbol": "USDT", "cost": "42500.55" } ] } ], "success": true, "message": null, "code": 0 } ``` **400: symbol not found** ```json { "title": "Symbol Not Found", "type": "symbol-not-found", "status": 400, "detail": "Symbol 'XYZ' not found" } ``` | Field | Type | Description | | ------------ | ------ | --------------------------------------------------------------------------- | | asset | string | Asset symbol, e.g. `BTC`. | | assetName | string | Full name of the asset. | | balance | string | Total balance: `free` plus `locked`. | | locked | string | Reserved amount: `orderFund` plus `requestFund`. | | free | string | Amount available to trade or withdraw. | | orderFund | string | Amount reserved by open orders. | | requestFund | string | Amount reserved by pending withdrawal requests. | | precision | int | Number of decimals used for the asset. | | timestamp | long | Time of the response, milliseconds since the Unix epoch. | | averageCosts | array | Average cost of the asset in `TRY` and in `USDT` (`symbol`, `cost`). | Note that `timestamp` is expressed in milliseconds since the Unix epoch. `averageCosts` always contains one entry for `TRY` and one for `USDT`; `cost` is `null` when no average cost has been recorded for that quote asset. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/users/balances" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" \ -H "Content-Type: application/json" ``` **C#** ```csharp var apiKey = "YOUR_API_PUBLIC_KEY"; var apiSecret = "YOUR_API_SECRET"; var stamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(); var message = apiKey + stamp; using var hmac = new HMACSHA256(Convert.FromBase64String(apiSecret)); var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(message))); using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/users/balances"); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` --- ## Get User Trade Transactions Retrieve trade (fill) history for the authenticated user. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Account** API key permission. * If `orderId` is set, it must be sent **alone** — combining it with `startDate`, `endDate`, `type`, `symbol` or `pairSymbol` returns a validation error. * You cannot combine `symbol` and `pairSymbol` in the same request. * `pairSymbol` accepts `BTCUSDT` or `BTC_USDT`. An unknown pair returns `400 PAIR_NOT_FOUND_ERROR` (1027). * At most 200 trades are returned, newest first. * With both dates, that range is used. With only `endDate`, the range is the 30 days before it. With only `startDate`, the range ends 30 days later or now, whichever is earlier. With neither, it is the last 30 days. :::info The `startDate` and `endDate` parameters must be Unix timestamps in **milliseconds**. ::: ### Trade `GET` `/api/v1/users/transactions/trade` ##### Query Parameters | Name | Type | Description | | ---------- | ------- | --------------------------------------------------------------------------------------------------------- | | orderId | long | Optional. Cannot be combined with any other parameter below. | | type | array | `buy`, `sell` (repeat the query param for multiple values) | | symbol | array | Currency symbols, e.g. `btc`, `try`. Cannot be combined with `pairSymbol`. | | pairSymbol | string | e.g. `BTCUSDT` or `BTC_USDT`. Cannot be combined with `symbol`. | | startDate | long | Unix time in milliseconds. Defaults to 30 days before `endDate`, or 30 days before now. | | endDate | long | Unix time in milliseconds. Defaults to 30 days after `startDate` or now, whichever is earlier. | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | **200** ```json { "success": true, "message": "SUCCESS", "code": 0, "data": [ { "id": "1181163798924649598", "timestamp": 1663848223334, "amount": "-0.3384", "preciseAmount": -0.3384081100000000, "fee": "-0.06297817", "tax": "-0.01133607", "price": "122.00", "numeratorSymbol": "ETHW", "denominatorSymbol": "TRY", "orderType": "sell", "role": "taker", "orderId": 10938696222, "orderClientId": null } ] } ``` `role` is `maker` or `taker`; it is `null` when the role is not known. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/users/transactions/trade?type=buy&type=sell&symbol=btc&symbol=try" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/users/transactions/trade?type=buy&type=sell&symbol=btc&symbol=try"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` :::info For crypto deposit/withdrawal ledger entries, see [Get Crypto Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/get-crypto-transactions.md). BtcTurk Global API does not expose a fiat transactions endpoint. ::: --- ## Get Crypto Transactions Retrieve the confirmed crypto deposit/withdrawal ledger for the authenticated user. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Account** API key permission. * Only entries with a `Confirmed` crypto status are returned, newest first, at most 200. * If `type` is omitted, every type is returned, deposits and withdrawals included. * The date range applies to each record's `timestamp` (its last update). With both dates, that range is used. With only `endDate`, the range is the 30 days before it. With only `startDate`, the range ends 30 days later or now, whichever is earlier. With neither, it is the last 30 days. `startDate` after `endDate` returns `400`. :::info The `startDate` and `endDate` parameters must be Unix timestamps in **milliseconds**. ::: ### Crypto `GET` `/api/v1/users/transactions/crypto` ##### Query Parameters | Name | Type | Description | | --------- | ------- | --------------------------------------------------------------------- | | type | array | `deposit`, `withdrawal`. When omitted, every type is returned. | | symbol | array | Currency symbols, e.g. `btc`, `usdt`. | | startDate | long | Unix time in milliseconds. Defaults to 30 days before `endDate`, or 30 days before now. | | endDate | long | Unix time in milliseconds. Defaults to 30 days after `startDate` or now, whichever is earlier. | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | **200** ```json { "success": true, "message": "SUCCESS", "code": 0, "data": [ { "id": 48705286, "timestamp": 1648301802887, "amount": "0.5", "preciseAmount": 0.5, "fee": "0", "tax": "0", "balanceType": "deposit", "currencySymbol": "USDT", "address": "TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "tag": null, "txHash": "0xabc...", "confirmationCount": 12, "isConfirmed": true } ] } ``` `preciseAmount` is the amount as a JSON number. `confirmationCount` is set for deposits and is `null` for withdrawals. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/users/transactions/crypto?type=deposit&symbol=usdt" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/users/transactions/crypto?type=deposit&symbol=usdt"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Crypto Deposit Addresses List and inspect the crypto deposit addresses generated for your account. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Crypto Asset Withdrawal** API key permission group. ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | ### List Deposit Addresses `GET` `/api/v1/crypto-deposit-addresses` ##### Query Parameters | Name | Type | Description | | -------------------------------------------------------- | ---- | ------------------------------------------------------- | | currencyChannelId* | long | `id` from [Get Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md) (for example `43` for USDT on Tron). | Response is a raw JSON array (not wrapped in a `data` envelope). Deposit addresses are created in the BtcTurk Global app. If the list is empty for a network, create the address in the app first. **200** ```json [ { "id": 1029384, "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "tag": null } ] ``` **400: unknown channel** ```json { "title": "Currency Channel Not Found", "type": "currency-channel-not-found", "status": 400, "detail": "Currency channel not found" } ``` An unknown `currencyChannelId` returns `400 currency-channel-not-found`. ### Get Deposit Address by Id `GET` `/api/v1/crypto-deposit-addresses/{id}` ##### Path Parameters | Name | Type | Description | | -------------------------------------- | ---- | --------------------------------- | | id* | long | Deposit address id (must be > 0) | **200** ```json { "id": 1029384, "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "tag": null } ``` **404: not found** ```json { "title": "Not Found", "type": "crypto-deposit-address-not-found", "status": 404, "detail": "Not found" } ``` An address that exists but belongs to another account returns the same `404` as one that does not exist — the endpoint does not distinguish the two. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/crypto-deposit-addresses?currencyChannelId=2" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/crypto-deposit-addresses?currencyChannelId=2"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` :::info `currencyChannelId` values come from the [Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md) endpoint. ::: --- ## Crypto Withdrawal Addresses List the whitelisted addresses that [Crypto Withdrawals](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md) can send funds to. :::info Withdrawal addresses are added and removed only in the BtcTurk Global app, with two-factor authentication. The API lets you list and read them. Withdrawals can be sent only to addresses saved this way. ::: :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Crypto Asset Withdrawal** API key permission group. ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | ### List Withdrawal Addresses `GET` `/api/v1/crypto-withdrawal-addresses` ##### Query Parameters | Name | Type | Description | | --------------- | ------- | -------------------------------------------------------------------------- | | currencySymbol | string | Max length 10. Filters by asset symbol. | | cryptoChannelId | integer | `id` from [Get Crypto Channels](https://global.btcturk.com/apidoc/api/public-endpoints/crypto-channels.md). Filters by network. | | page | integer | Page number, starting at `1`. Default `1`. | | pageSize | integer | `1`–`100`. Default `100`. | | orderBy | string | Only `Id` is accepted (case-insensitive). | | order | string | `Asc` or `Desc`. | Response is a raw JSON array. **200** ```json [ { "id": 5501, "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "receiverName": "My Cold Wallet", "currencySymbol": "BTC", "tag": null, "cryptoChannelId": 25 } ] ``` ### Get Withdrawal Address by Id `GET` `/api/v1/crypto-withdrawal-addresses/{id}` **200** ```json { "id": 5501, "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "receiverName": "My Cold Wallet", "currencySymbol": "BTC", "tag": null, "cryptoChannelId": 25 } ``` #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/crypto-withdrawal-addresses?currencySymbol=BTC" -H "X-PCK: YOUR_API_PUBLIC_KEY" -H "X-Stamp: 1735866257711" -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/crypto-withdrawal-addresses?currencySymbol=BTC"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Crypto Withdrawals Create and follow crypto withdrawals. `POST /api/v1/crypto-withdrawals` creates a withdrawal request and sends a confirmation e-mail to the account holder. Funds leave your account only after you confirm the request from that e-mail. The link is valid for 1 hour; after that the request is cancelled automatically. Use [Get Crypto Withdrawal by Id](#get-crypto-withdrawal-by-id) to follow its status. | status | Meaning | | --- | --- | | PendingForUserAction | Waiting for you to confirm from the e-mail | | PendingForAdminAction | Confirmed; waiting for a review by BtcTurk Global before it is sent | | Confirmed | Confirmed; being processed and sent | | UserCancelled | Cancelled by you | | AdminCancelled | Cancelled by BtcTurk Global | | SystemCancelled | Not confirmed within 1 hour, or stopped by an automatic check; cancelled automatically | :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Crypto Asset Withdrawal** API key permission group. ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | ### Create Crypto Withdrawal `POST` `/api/v1/crypto-withdrawals` ##### Request Body | Name | Type | Description | | --------------------------------------------- | ------ | ------------------------------------------------------------------------------ | | asset* | string | `channelSymbol` from [Get Currency Channels](https://global.btcturk.com/apidoc/api/public-endpoints/currency-channels.md), case-sensitive. It selects both the asset and the network, e.g. `TRC20USDT` for USDT on Tron, `USDT` for USDT on Ethereum, `BTC` for Bitcoin. | | amount* | string | Decimal string, up to 12 integer digits and 16 decimal digits. | | address* | string | Destination address. Must be one of your [withdrawal addresses](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawal-addresses.md) for this currency and network, added in the BtcTurk Global app. | | addressTag | string | Memo/tag, required by some networks. | | uniqueTransactionId | guid | Optional idempotency key. A new GUID is generated if omitted or empty. | * The address (and its tag, on networks that use one) must be saved as a withdrawal address for the same currency and network in the BtcTurk Global app; otherwise you receive `400` WITHDRAWAL_ADDRESS_NOT_WHITELISTED (1091). * Only one withdrawal per currency and network can be pending at a time. While one waits for your e-mail confirmation or for review, creating another returns `409` EXIST_PENDING_REQUEST (1059). * The fee is charged in addition to `amount`: your balance is debited `amount` plus `fee`. The fee is returned in `fee` when the request is created. **200** ```json { "success": true, "message": "SUCCESS", "code": 0, "data": { "id": 778899, "timestamp": 1735866257711, "type": "Withdrawal", "amount": "-0.5", "fee": "-0.0001", "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "addressTag": null, "asset": "BTC" } } ``` **400: balance not enough** ```json { "success": false, "code": 1055, "message": "BALANCE_NOT_ENOUGH" } ``` | Field | Type | Description | | ---------- | ------ | -------------------------------------------------------------------- | | id | long | Withdrawal id. | | timestamp | long | Creation time, milliseconds since the Unix epoch. | | type | string | Always `Withdrawal`. | | amount | string | Amount debited, as a negative decimal string. | | fee | string | Fee debited, as a negative decimal string; `"0"` when no fee is charged. | | address | string | Destination address. | | addressTag | string | Memo/tag, or `null`. | | asset | string | Currency symbol, e.g. `BTC`. | ### List Crypto Withdrawals `GET` `/api/v1/crypto-withdrawals` ##### Query Parameters | Name | Type | Description | | -------------------------------------------------------- | ---- | ----------------------------------------------------- | | uniqueTransactionId* | guid | The `uniqueTransactionId` used when creating the withdrawal. | Response is a raw JSON array. **200** ```json [ { "id": 778899, "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "amount": -0.5, "confirmationDate": null, "confirmCount": 2, "cryptoChannelId": 25, "cryptoStatus": "PendingForUserAction", "cryptoType": "Withdrawal", "currencyId": 2, "currencySymbol": "BTC", "fee": -0.0001, "feeCurrencyId": 2, "pairLastPrice": null, "remainingFunds": 0, "tag": null, "txHash": null, "userId": 12345, "uniqueTransactionId": "b1a2c3d4-e5f6-4789-0abc-def123456789", "createdDate": "2025-08-24T10:00:00Z", "updatedDate": "2025-08-24T10:00:05Z" } ] ``` `amount` and `fee` are JSON numbers, negative for a withdrawal. `cryptoStatus` uses the same names as `status` (see the table above), and `createdDate` is an ISO-8601 date-time string. ### Get Crypto Withdrawal by Id `GET` `/api/v1/crypto-withdrawals/{id}` **200** ```json { "id": 778899, "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "balanceAmount": -0.5, "feeBalanceAmount": -0.0001, "createdAt": "2025-08-24T10:00:00Z", "cryptoChannelId": 25, "currencyId": 2, "status": "PendingForUserAction" } ``` **404: not found** ```json { "title": "Not Found", "type": "crypto-withdrawal-not-found", "status": 404, "detail": "Not found" } ``` `balanceAmount` (the amount) and `feeBalanceAmount` (the fee) are JSON numbers, negative for a withdrawal. `createdAt` is an ISO-8601 date-time string, and `status` is the withdrawal status (see the table above). #### Code Example **curl** ```bash curl -X POST "https://api.global.btcturk.com/api/v1/crypto-withdrawals" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" \ -H "Content-Type: application/json" \ -d '{ "asset": "BTC", "amount": "0.5", "address": "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }' ``` **C#** ```csharp var payload = new { asset = "BTC", amount = "0.5", address = "bc1qxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }; var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"); using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.PostAsync("/api/v1/crypto-withdrawals", content); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` #### Expected Errors Create Crypto Withdrawal returns errors in the envelope format; handle them by `code`. | Status | Code | Message | Meaning | | --- | --- | --- | --- | | 400 | 1038 | INVALID_WITHDRAWAL_AMOUNT | `amount` is zero, negative or malformed | | 400 | 1038 | WITHDRAWAL_AMOUNT_EXCEEDED | `amount` is above the maximum for the asset | | 400 | 1038 | INVALID_ADDRESS_TAG | The address tag is missing or invalid for the network | | 400 | 1055 | BALANCE_NOT_ENOUGH | Not enough free balance for `amount` plus `fee` | | 400 | 1242 | BALANCE_NOT_ENOUGH_DUE_TO_OPEN_ORDERS | The balance is reserved by open orders; `data` holds the reserved amount | | 400 | 1064 | CURRENCY_NOT_FOUND | The currency does not exist | | 400 | 1068 | AMOUNT_BELOW_MINIMUM_WITHDRAWAL_AMOUNT | `amount` is below the minimum withdrawal | | 400 | 1081 | CURRENCY_CHANNEL_NOT_FOUND | `asset` does not match a currency channel | | 400 | 1091 | WITHDRAWAL_ADDRESS_NOT_WHITELISTED | The address is not one of your saved withdrawal addresses | | 400 | 1095 | ADDRESS_IS_NOT_VALID | The address is not valid for the network | | 400 | 1096 | ADDRESS_CAN_NOT_BE_INTERNAL | The address belongs to BtcTurk and cannot be used | | 400 | 1211 | GLVL1_CRYPTO_WTH_30D_LIMIT_EXCEED | 30-day withdrawal limit exceeded; `data` holds the remaining limit | | 400 | 1212 | GLVL1_CRYPTO_WTH_24H_LIMIT_EXCEED | 24-hour withdrawal limit exceeded; `data` holds the remaining limit | | 400 | 1218 | ACCESS_DENIED | Withdrawals are not available for this asset on your account | | 400 | 1232 | CURRENCY_WITHDRAWAL_DISABLED | Withdrawals are disabled for this network | | 400 | 8009 | SUSPICIOUS_ADDRESS | The address is flagged as suspicious | | 403 | 1229 | BLOCKED_CRYPTO_WITHDRAWAL | Crypto withdrawals are blocked for your account; `data` holds the end date | | 403 | 1240 | SUSPENDED_WITHDRAW_CRYPTO | Crypto withdrawals are suspended for your account; `data` holds the end date | | 403 | 8015 | CRYPTO_WITHDRAWAL_BLOCKED_ADDRESS | Withdrawals to this address are blocked | | 409 | 1059 | EXIST_PENDING_REQUEST | Another withdrawal for this currency and network is still pending | | 409 | 1245 | DUPLICATE_WITHDRAWAL_TRANSACTION | `uniqueTransactionId` was already used | | 500 | 500 | INTERNAL_ERROR | Unexpected error; check List Crypto Withdrawals before retrying | Any other rejection keeps its HTTP status (`400`, `403` or `409`), with code `1218` for `403` and `1038` otherwise, and gives the reason in `message`, for example `CRYPTO_WITHDRAWAL_HOLDING_72_HOURS_RULE_RESTRICTION`. Do not retry these without changing the request. When a field is rejected, the response is a list of `field` / `message` pairs instead, for example `[{ "field": "Address", "message": "MIN_LENGTH_10" }]`. Messages are `ADDRESS_REQUIRED`, `MIN_LENGTH_10`, `MAX_LENGTH_250` (address), `MAX_LENGTH_200` (address tag), `INVALID_WITHDRAWAL_AMOUNT`, `INVALID_ASSET` and `INVALID_VALUE`. If the withdrawals cannot be read, List Crypto Withdrawals returns a `500 internal-server-error` problem document. --- ## Get Trade Volumes Retrieve your daily traded volume, optionally scoped to a single pair. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Account** API key permission. * `startDate` and `endDate` are required and the range must be **30 days or less**. * Both dates must be on or after `2009-01-09`, and `startDate` must not be after `endDate`. ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | ### Volumes `GET` `/api/v1/volumes` ##### Query Parameters | Name | Type | Description | | ---------------------------------------------------- | --------- | ---------------------------------------------- | | startDate* | datetime | ISO-8601 date/time. | | endDate* | datetime | ISO-8601 date/time. | | pairId | integer | Optional. Filters to a single pair id. | Response is a raw JSON array. **200** ```json [ { "date": "2025-08-20T00:00:00Z", "pairId": 1, "volume": 0.42891234 }, { "date": "2025-08-21T00:00:00Z", "pairId": 1, "volume": 0.10234000 } ] ``` #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/volumes?startDate=2025-08-01&endDate=2025-08-24&pairId=1" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/volumes?startDate=2025-08-01&endDate=2025-08-24&pairId=1"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Open Orders List your current open orders. Only open or un-settled orders are returned. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Trade** API key permission. * `pairSymbol` is optional; when omitted, open orders for all pairs are returned. ### Open Orders `GET` `/api/v1/openOrders` ##### Query Parameters | Name | Type | Description | | ---------- | ------ | -------------------- | | pairSymbol | string | BTCUSDT, ETHUSDT etc. | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | **200** ```json { "success": true, "message": null, "code": 0, "data": { "asks": [ { "id": 16060235, "price": "85420.00", "amount": "0.09733687", "quantity": "0.09733687", "stopPrice": "0.00", "pairSymbol": "BTCUSDT", "pairSymbolNormalized": "BTC_USDT", "type": "sell", "method": "limit", "orderClientId": "da593000-6eb3-4a1c-ba26-c616122a0210", "time": 0, "updateTime": 1591286401373, "status": "Untouched", "leftAmount": "0.09733687" } ], "bids": [ { "id": 16071095, "price": "85391.00", "amount": "0.08956055", "quantity": "0.08956055", "stopPrice": "0.00", "pairSymbol": "BTCUSDT", "pairSymbolNormalized": "BTC_USDT", "type": "buy", "method": "limit", "orderClientId": "da593000-6eb3-4a1c-ba26-c616122a0210", "time": 0, "updateTime": 1591352311273, "status": "Untouched", "leftAmount": "0.08956055" } ] } } ``` Note that `time` is not populated for open orders (always `0`); use `updateTime` for a meaningful timestamp. Stop orders cannot be placed through the API, but orders you place on the BtcTurk Global website can be stop orders: their `method` is `stoplimit` or `stopmarket` and `stopPrice` is the trigger price. For other orders `stopPrice` is `"0.00"` (with `denominatorScale` decimals). #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/openOrders?pairSymbol=BTCUSDT" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/openOrders?pairSymbol=BTCUSDT"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get All Orders Retrieve orders of any status (open, filled, partial, canceled) for a specific pair. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Trade** API key permission. * `pairSymbol` is **required**. * If neither `startTime` nor `endTime` is supplied, the last 1 month of orders is returned. * `page` is zero-based (defaults to `0`). * `limit` is optional, must be between `1` and `50`, and defaults to `50`. ### All Orders `GET` `/api/v1/allOrders` ##### Query Parameters | Name | Type | Description | | ---------- | ------- | ------------------------------------------------------------------------------------ | | pairSymbol* | string | BTCUSDT, ETHUSDT etc. | | orderId | long | If set, returns orders with an id greater than or equal to this order id | | startTime | long | Unix time in milliseconds | | endTime | long | Unix time in milliseconds | | page | integer | Zero-based page number (default `0`) | | limit | integer | Page size, `1`–`50`. Default `50`. | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | **200** ```json { "success": true, "message": null, "code": 0, "data": [ { "id": 9932534, "price": "85400.00", "amount": "0.001", "quantity": "0.001", "pairSymbol": "BTCUSDT", "pairSymbolNormalized": "BTC_USDT", "type": "buy", "method": "limit", "orderClientId": "test", "time": 1543996112263, "updateTime": 1543996112263, "status": "Untouched", "stopPrice": "0", "leftAmount": "0.001" }, { "id": 9932523, "price": "85000.00", "amount": "0.01", "quantity": "0.01", "pairSymbol": "BTCUSDT", "pairSymbolNormalized": "BTC_USDT", "type": "buy", "method": "limit", "orderClientId": "test", "time": 1543500891493, "updateTime": 1543501769613, "status": "Canceled", "stopPrice": "0", "leftAmount": null } ] } ``` **400: missing pairSymbol** ```json {"success": false, "message": "PAIR_SYMBOL_IS_NECESSARY", "code": 1079} ``` `type` is `buy` or `sell`, and `method` is `limit` or `market`. `status` is `Untouched`, `Partial`, `Closed` or `Canceled`. Stop orders cannot be placed through the API, but orders you place on the BtcTurk Global website can be stop orders: their `method` is `stoplimit` or `stopmarket` and `stopPrice` is the trigger price. For other orders `stopPrice` is `"0"`. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/allOrders?pairSymbol=BTCUSDT&limit=50" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/allOrders?pairSymbol=BTCUSDT&limit=50"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Get Single Order Get a single order by `orderId`. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Trade** API key permission. The order must belong to the authenticated user, otherwise a `400 Bad Request` (`ORDER_NOT_FOUND`) is returned. ### Get Single Order `GET` `/api/v1/order/{orderId}` ##### Path Parameters | Name | Type | Description | | ----------------------------------------- | ---- | -------------------------- | | orderId* | long | `orderId` of the order | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | **200: OK Success** ```json { "success": true, "message": null, "code": 0, "data": { "id": 61912740, "price": "85400.00", "amount": "0.12345678", "quantity": "0.12345678", "stopPrice": "0", "pairSymbol": "BTCUSDT", "pairSymbolNormalized": "BTC_USDT", "type": "sell", "method": "limit", "orderClientId": "my-order-1", "time": 1647883449587, "updateTime": 1647883449587, "status": "Untouched", "leftAmount": "0.1234567800000000" } } ``` **400: Bad Request Order not found** ```json { "success": false, "message": "ORDER_NOT_FOUND", "code": 1152 } ``` `type` and `method` are lowercase in every order endpoint: `type` is `buy` or `sell`, and `method` is `limit` or `market`. `status` is `Untouched`, `Partial`, `Closed` or `Canceled`. Stop orders cannot be placed through the API, but orders you place on the BtcTurk Global website can be stop orders: their `method` is `stoplimit` or `stopmarket` and `stopPrice` is the trigger price. For other orders `stopPrice` is `"0"`. #### Code Example **curl** ```bash curl -X GET "https://api.global.btcturk.com/api/v1/order/61912740" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.GetAsync("/api/v1/order/61912740"); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` --- ## Submit an Order Create an order. Order methods are `limit` and `market`; each pair allows only the methods listed in its `orderMethods` field in [Get Exchange Info](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md): | `orderMethods` value | `orderMethod` | | --- | --- | | `MARKET` | `market` | | `LIMIT` | `limit` | A method the pair does not allow returns ORDER_METHOD_NOT_SUPPORTED (1134). Stop orders (`stoplimit`, `stopmarket`) are not supported through the API and always return ORDER_METHOD_NOT_SUPPORTED (1134). Orders can only be placed if your account has sufficient funds. Once an order is placed, your account funds will be put on hold for the duration of the order. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. This endpoint requires the **Trade** API key permission. * `quantity`, `price`, `newOrderClientId`, `orderMethod`, `orderType`, `pairSymbol` fields make up the request body. * `price` is ignored for market orders. * `pairSymbol` accepts either `BTCUSDT` or `BTC_USDT` style formatting; the underscore is stripped server-side. * `newOrderClientId` is optional (max length 50). If omitted, a GUID is generated for you. When you send it, it must be unique for your account for 24 hours. * An order identical to one of your open orders (same pair, side, price and quantity) is rejected with FAILED_ORDER_WITH_OPEN_ORDERS (1122). * The pair's `filters[].minPrice` and `maxPrice` apply to the `price` of limit orders: a buy price above `maxPrice` returns PRICE_MUST_BE_LESS_THAN_MAXPRICE (1226), and a sell price below `minPrice` returns PRICE_MUST_BE_GREATER_THAN_MINPRICE (1227). :::danger Decimal fields (`quantity`, `price`) must be sent as strings using a dot **(.)** as the decimal separator, matching the pattern `^\d{0,12}(\.\d{1,16})?$` — for example `0.1876`. ::: ### Submit Order `POST` `/api/v1/order` ##### Request Body | Name | Type | Description | | --------------------------------------------- | ------ | ------------------------------------------------------------------------- | | quantity* | string | Order size. Market **buy**: amount of the quote asset to spend, with at most `denominatorScale` decimals (e.g. `12` on BTCUSDT spends 12 USDT). All other orders: amount of the base asset, with at most `numeratorScale` decimals. | | price | string | Decimal string. Required for limit orders; ignored for market orders. | | newOrderClientId | string | Your own id for the order, up to 50 characters. Must be unique per account for 24 hours; a repeat is rejected with DUPLICATE_CLIENT_ORDER_ID (1246). A GUID is generated if omitted. | | orderMethod* | string | One of `limit`, `market`. | | orderType* | string | One of `buy`, `sell`. | | pairSymbol* | string | Max length 20, e.g. `BTCUSDT`, `ETHUSDT`. | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | **200** ```json { "success": true, "message": "SUCCESS", "code": 0, "data": { "id": 9932534, "datetime": 1543996112263, "type": "buy", "method": "limit", "price": "85400.00", "stopPrice": null, "quantity": "0.001", "pairSymbol": "BTCUSDT", "pairSymbolNormalized": "BTC_USDT", "newOrderClientId": "test" } } ``` **400: validation error** ```json { "success": false, "code": 1000, "message": "INVALID_MODEL", "data": { "quantity": ["INVALID_VALUE"] } } ``` #### Code Example **curl** ```bash curl -X POST "https://api.global.btcturk.com/api/v1/order" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" \ -H "Content-Type: application/json" \ -d '{ "quantity": "0.001", "price": "85400", "newOrderClientId": "my-order-1", "orderMethod": "limit", "orderType": "sell", "pairSymbol": "BTCUSDT" }' ``` **C#** ```csharp var payload = new { quantity = "0.001", price = "85400", newOrderClientId = "my-order-1", orderMethod = "limit", orderType = "sell", pairSymbol = "BTCUSDT" }; var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"); using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); var response = await client.PostAsync("/api/v1/order", content); Console.WriteLine(await response.Content.ReadAsStringAsync()); ``` #### Errors See [Error Codes](https://global.btcturk.com/apidoc/error-handling/error-handling-for-order-operations.md) for every error this endpoint can return. The most common are `BALANCE_NOT_ENOUGH` (1055), `FAILED_MIN_TOTAL_AMOUNT` (1123) and the scale errors 1126 and 1127. --- ## Cancel Orders Cancel a single open order by id, or cancel several open orders in one request. :::warning **For all transactions related to the private endpoint, you must authorize before sending your request.** ::: For more information you can check our [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) article. Both endpoints require the **Trade** API key permission. A `200 OK` response means the cancellation was accepted for processing, not necessarily finalized. An authenticated [WebSocket](https://global.btcturk.com/apidoc/websocket-feed/connection.md) connection receives an [order-cancelled message](https://global.btcturk.com/apidoc/websocket-feed/private-messages/order-cancelled.md) (type `452`) once it is applied; without one, poll [Get Single Order](https://global.btcturk.com/apidoc/api/private-endpoints/get-single-order.md) or [All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md) to confirm the final status. ### Cancel Order `DELETE` `/api/v1/order/{id}` ##### Path Parameters | Name | Type | Description | | ------------------------------------ | ---- | ----------------- | | id* | long | id of the order | ##### Headers | Name | Type | Description | | ------------------------------------------------ | ------- | -------------------------------------------------------------------------------------------- | | X-PCK* | string | API public key. | | X-Stamp* | integer | Current time in milliseconds since the Unix epoch (UTC). | | X-Signature* | string | HMAC-SHA256 signature. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md). | | X-Nonce | integer | Optional. Backward tolerance for `X-Stamp` in milliseconds. Default `5000`, maximum `60000`. | ##### **Request example:** * `/api/v1/order/123456789` **200** ```json {"success": true, "message": "SUCCESS", "code": 0} ``` **400: not found** ```json {"success": false, "message": "NO_ORDER_MATCHES_YOUR_REQUEST", "code": 1052} ``` ### Cancel Multiple Orders `DELETE` `/api/v1/order` Cancels every order id listed in the request body. Orders are cancelled **one by one, not atomically** — some ids can succeed while others fail. ##### Request Body | Name | Type | Description | | ------------------------------------ | ------- | ------------------------------------------------ | | id* | long[] | Order ids to cancel. Must contain at least one id. | ```json { "id": [123456789, 123456790, 123456791] } ``` :::info Read `success` before `uncancelledOrders`. A **partial failure still returns `200 OK`** with `success: false` and one entry in `uncancelledOrders` per id that could not be cancelled. `success` is `true` only when every id was cancelled, in which case `uncancelledOrders` is an empty array. ::: **200: all cancelled** ```json { "success": true, "message": null, "code": 0, "data": { "uncancelledOrders": [] } } ``` **200: partial failure** ```json { "success": false, "message": null, "code": 0, "data": { "uncancelledOrders": [ { "id": 123456790, "code": 1052, "message": "NO_ORDER_MATCHES_YOUR_REQUEST" } ] } } ``` **400: empty body** ```json {"success": false, "message": "INVALID_REQUEST_ERROR", "code": 1038} ``` A missing body, an empty `id` array, or `id: null` all return the `400` above. #### Code Example **curl** ```bash # Cancel a single order curl -X DELETE "https://api.global.btcturk.com/api/v1/order/123456789" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" # Cancel several orders curl -X DELETE "https://api.global.btcturk.com/api/v1/order" \ -H "X-PCK: YOUR_API_PUBLIC_KEY" \ -H "X-Stamp: 1735866257711" \ -H "X-Signature: COMPUTED_SIGNATURE" \ -H "Content-Type: application/json" \ -d '{ "id": [123456789, 123456790] }' ``` **C#** ```csharp using var client = new HttpClient { BaseAddress = new Uri("https://api.global.btcturk.com") }; client.DefaultRequestHeaders.Add("X-PCK", apiKey); client.DefaultRequestHeaders.Add("X-Stamp", stamp); client.DefaultRequestHeaders.Add("X-Signature", signature); // Cancel a single order var single = await client.DeleteAsync("/api/v1/order/123456789"); Console.WriteLine(await single.Content.ReadAsStringAsync()); // Cancel several orders — DELETE with a body needs an explicit HttpRequestMessage var payload = new { id = new[] { 123456789L, 123456790L } }; var request = new HttpRequestMessage(HttpMethod.Delete, "/api/v1/order") { Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json") }; var many = await client.SendAsync(request); Console.WriteLine(await many.Content.ReadAsStringAsync()); ``` --- ## Rate Limits Every request counts towards two limits: | Window | Limit | | --- | --- | | 500 milliseconds | 3 requests | | 10 seconds | 60 requests | Both are sliding windows, counted at the moment each request reaches our servers. The limits apply to your IP address and, for private requests, to your API key as well: public and private requests from the same IP address share the same limits, and all processes that use the same API key share them too. When you exceed a limit you receive `429 Too Many Requests` with a `Retry-After` header (seconds to wait): ```json { "success": false, "message": "TOO_MANY_REQUESTS", "code": 8018 } ``` Network delays can make two requests sent 500 ms apart arrive closer together, so leave a margin: sending at most one request every 200 ms keeps you safely within both limits. #### Invalid signatures After 10 requests with an invalid signature or an unknown API key within one minute, requests from the same API key or IP address are refused for 60 seconds with the same `429` response and a `Retry-After` header. #### WebSocket limits | Limit | Value | | --- | --- | | Connections per IP address | 20 | | Subscriptions per connection | 50 | | Messages you send per second, per connection | 10 | Exceeding a limit closes the connection with close code 1008 and a reason that names the limit. Each subscribe or unsubscribe request counts as one message, so when you subscribe to many channels after connecting, send at most 10 requests per second. --- ## Connection & Message Format The BtcTurk Global API has a WebSocket feed for realtime market data and, once authenticated, for your own order, trade and balance events. The feed is a standard WebSocket connection carrying JSON messages in a compact array envelope. `WSS` `wss://ws.global.btcturk.com` The feed accepts WebSocket connections over HTTP/1.1. Clients that negotiate HTTP/2 are rejected with `400`, so force HTTP/1.1 in your WebSocket library if needed. Use it instead of polling [Get Tickers](https://global.btcturk.com/apidoc/api/public-endpoints/ticker.md), [Get OrderBook](https://global.btcturk.com/apidoc/api/public-endpoints/orderbook.md) and [Get Trades](https://global.btcturk.com/apidoc/api/public-endpoints/trades.md) when you need continuous updates. ### Message envelope Every message - in both directions - is a JSON array with **exactly two elements**: ``` [, ] ``` * `` is an integer message type. * `` is a JSON object. ```json [151, { "type": 151, "channel": "ticker", "event": "BTCUSDT", "join": true }] ``` :::warning A message that is not valid JSON, is not an array, or does not have exactly two elements gets no reply. A repeated login on an authenticated connection gets no reply either. A join to an unknown channel is acknowledged with `ok: true` but delivers nothing. If you send a subscription and receive nothing at all, check the envelope shape and the channel name first. ::: Messages the server sends normally repeat the type inside the payload as a `type` field, so you can read it from either place. The one exception is [User Trade](https://global.btcturk.com/apidoc/websocket-feed/private-messages/user-trade.md), whose payload has no `type` field - read the array element there. ### Message types | Type | Message | Access | | ----- | ------------------------------------------------------------------------------ | ------------- | | `151` | [Subscribe / unsubscribe](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md) | Anonymous | | `100` | [Subscription result](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md#subscription-result) | Anonymous | | `114` | [HMAC login](https://global.btcturk.com/apidoc/websocket-feed/authentication.md), and its reply | Anonymous | | `991` | [Connection message](#connection-message) | Anonymous | | `401` | [All tickers](https://global.btcturk.com/apidoc/websocket-feed/public-messages/all-tickers.md) | Anonymous | | `402` | [Pair ticker](https://global.btcturk.com/apidoc/websocket-feed/public-messages/pair-ticker.md) | Anonymous | | `422` | [Trade](https://global.btcturk.com/apidoc/websocket-feed/public-messages/trade.md) | Anonymous | | `431` | [Full order book](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book.md) | Anonymous | | `432` | [Order book difference](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book-difference.md) | Anonymous | | `201` | [Balance updated](https://global.btcturk.com/apidoc/websocket-feed/private-messages/balance-updated.md) | Authenticated | | `423` | [User trade](https://global.btcturk.com/apidoc/websocket-feed/private-messages/user-trade.md) | Authenticated | | `441` | [Order matched](https://global.btcturk.com/apidoc/websocket-feed/private-messages/order-matched.md) | Authenticated | | `451` | [Order inserted](https://global.btcturk.com/apidoc/websocket-feed/private-messages/order-inserted.md) | Authenticated | | `452` | [Order cancelled](https://global.btcturk.com/apidoc/websocket-feed/private-messages/order-cancelled.md) | Authenticated | New message types may be added; ignore any type you do not recognise. ### Connection message Right after you connect, the server sends: ```json [991, { "type": 991, "current": "…", "min": "…" }] ``` It is informational. You do not need to reply, and you can ignore it. #### Field names in private messages | Meaning | 451 / 452 (order inserted / cancelled) | 441 (order matched) | 423 (user trade) | | --- | --- | --- | --- | | Message type | `type` | `type` | none (identify 423 by the first array element) | | Order id | `id` | `id` | `orderId` | | User id | `userId` | `user` | — | | Pair | `pairId`, `symbol` | `pair`, `symbol` | `numeratorSymbol`, `denominatorSymbol` | | Side | `orderType`: 0 = buy, 1 = sell | `isBid`: true = buy | `orderType`: `buy` / `sell` | | Your client id | `newOrderClientId` | `clientId` | `orderClientId` | | Time | — | `timestamp` (string, ms) | `timestamp` (number, ms) | In 451 and 452, `numLeft` is the unfilled amount in the base asset and `denomLeft` the order value in the quote asset. --- ## Subscribing Market-data messages are delivered by subscription. Private account messages are **not** - they arrive automatically once the connection is [authenticated](https://global.btcturk.com/apidoc/websocket-feed/authentication.md). ### Subscribe Send message type `151` with `join: true`: ```json [151, { "type": 151, "channel": "orderbook", "event": "BTCUSDT", "join": true }] ``` | Field | Type | Description | | ------- | ------- | --------------------------------------------------------- | | channel | string | Channel name - see the table below. | | event | string | Channel-specific key, usually the pair symbol (`BTCUSDT`). | | join | boolean | `true` to subscribe, `false` to unsubscribe. | ### Channels | Channel | `event` | Pushes | Type | | ----------- | ---------------------- | ----------------------------------------------------------------------------- | ----- | | `ticker` | `all` | [All tickers](https://global.btcturk.com/apidoc/websocket-feed/public-messages/all-tickers.md) | `401` | | `ticker` | pair symbol, `BTCUSDT` | [Pair ticker](https://global.btcturk.com/apidoc/websocket-feed/public-messages/pair-ticker.md) | `402` | | `trade` | pair symbol, `BTCUSDT` | [Trade](https://global.btcturk.com/apidoc/websocket-feed/public-messages/trade.md) | `422` | | `orderbook` | pair symbol, `BTCUSDT` | [Full order book](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book.md) | `431` | | `obdiff` | pair symbol, `BTCUSDT` | [Order book difference](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book-difference.md) | `432` | ### Subscription result The server answers with a result message (type `100`): ```json [100, { "type": 100, "ok": true, "message": "join|orderbook:BTCUSDT" }] ``` `message` is always `"|:"`. Immediately after a successful join, if the server already holds a cached snapshot for that channel/event, it pushes that snapshot as a separate message - so you normally receive a full picture before the first incremental update. ### Unsubscribe Send the same message with `join: false`. Two behaviours to be aware of: * **Unsubscribe is answered only when it actually removed something.** Leaving a channel you were not subscribed to produces **no reply at all** - not an `ok: false`. * **Re-subscribing to a channel/event you are already on replies `ok: false`.** That is an "already subscribed" signal, not a failure to deliver data; your existing subscription is untouched. --- ## Authentication Authentication is only needed for your own order, trade and balance events. Every [public message](https://global.btcturk.com/apidoc/websocket-feed/public-messages/all-tickers.md) works on an anonymous connection. This endpoint requires the **WebSocket** API key permission - see [API Access Permissions](https://global.btcturk.com/apidoc/api-access-permissions.md). ### HMAC login Send message type `114` after the socket opens: ```json [114, { "type": 114, "publicKey": "YOUR_API_PUBLIC_KEY", "timestamp": 1735866257711, "nonce": 5000, "signature": "COMPUTED_SIGNATURE" }] ``` | Field | Type | Description | | --------- | ------- | ------------------------------------------------------------------------ | | publicKey | string | API public key - the same value you send as `X-PCK` over REST. | | timestamp | integer | Current time in milliseconds (UTC), as `X-Stamp` over REST. | | nonce | integer | Optional. Backward tolerance for `timestamp` in milliseconds, as `X-Nonce` over REST. Omitted, `0` or negative means `5000`; values above `60000` are capped at `60000`. | | signature | string | HMAC-SHA256 signature. | The signature is computed **exactly as for the REST API** - the WebSocket service and the REST API hand the same four values to the same validator. See [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) for the algorithm and worked examples. ### Login result ```json [114, { "type": 114, "ok": true, "id": 12345, "message": null }] ``` | Field | Description | | --------- | ---------------------------------------- | | `ok` | `true` when the key validated. | | `id` | Your user id; `0` when `ok` is `false`. | | `message` | Failure reason; `null` on success. | :::warning The reply carries type **`114`**, the same type as the request - not `115`. A client waiting for `[115, ...]` will wait forever. ::: A second login attempt on an already-authenticated connection is **ignored silently**. To switch API keys, open a new connection. After a successful login, your order, trade and balance events are sent on the same connection automatically; you do not subscribe to them. See [private messages](https://global.btcturk.com/apidoc/websocket-feed/private-messages/balance-updated.md). --- ## All Tickers (401) Channel `ticker`, event `all`. Pushed about every 750 ms, even when nothing has changed, carrying every pair in one message. Subscribe with [message type 151](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md). ```json [401, { "type": 401, "channel": "ticker", "event": "all", "items": [ { "PS": "BTCUSDT", "NS": "BTC", "DS": "USDT", "PId": 19, "B": "85391", "A": "85420", "BA": "0.00292756", "AA": "0.0983193", "LA": "85417", "H": "87232", "L": "85274", "O": "86140", "V": "12.97543029", "AV": "86325.652885850000", "D": "-720", "DP": "-0.84", "Ord": 0 } ] }] ``` Each entry of `items` carries these codes: | Code | Meaning | | ----- | -------------------------- | | `PS` | Pair symbol | | `NS` | Numerator (base) symbol | | `DS` | Denominator (quote) symbol | | `PId` | Pair id | | `B` | Best bid | | `A` | Best ask | | `BA` | Best bid amount | | `AA` | Best ask amount | | `LA` | Last price | | `H` | 24h high | | `L` | 24h low | | `O` | Open | | `V` | Volume | | `AV` | Average price | | `D` | Daily change | | `DP` | Daily change percent | | `Ord` | Display order | A pair appears only once the server has a ticker for it. Prices and amounts are sent as **strings**: `V` always has 8 decimals, `AV` 12 and `DP` 2, and the other values have no trailing zeros. Zero values are sent as `"0"`, or with the field's fixed decimals (for example `"0.00"` for `DP`). For a single pair, subscribe to [Pair Ticker](https://global.btcturk.com/apidoc/websocket-feed/public-messages/pair-ticker.md) instead - it carries the same fields without the surrounding list. --- ## Pair Ticker (402) Channel `ticker`, event `` (for example `BTCUSDT`). Same fields as one entry of [All Tickers](https://global.btcturk.com/apidoc/websocket-feed/public-messages/all-tickers.md), but flattened into the payload itself rather than nested in a list. `Ord` is not included. Pushed about every 750 ms, even when nothing has changed. Subscribe with [message type 151](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md). ```json [402, { "type": 402, "channel": "ticker", "event": "BTCUSDT", "PS": "BTCUSDT", "NS": "BTC", "DS": "USDT", "PId": 19, "B": "85391", "A": "85420", "BA": "0.00292756", "AA": "0.0983193", "LA": "85417", "H": "87232", "L": "85274", "O": "86140", "V": "12.97543029", "AV": "86325.652885850000", "D": "-720", "DP": "-0.84" }] ``` | Code | Meaning | | ----- | -------------------------- | | `PS` | Pair symbol | | `NS` | Numerator (base) symbol | | `DS` | Denominator (quote) symbol | | `PId` | Pair id | | `B` | Best bid | | `A` | Best ask | | `BA` | Best bid amount | | `AA` | Best ask amount | | `LA` | Last price | | `H` | 24h high | | `L` | 24h low | | `O` | Open | | `V` | Volume | | `AV` | Average price | | `D` | Daily change | | `DP` | Daily change percent | A pair appears only once the server has a ticker for it. Prices and amounts are sent as **strings**: `V` always has 8 decimals, `AV` 12 and `DP` 2, and the other values have no trailing zeros. Zero values are sent as `"0"`, or with the field's fixed decimals (for example `"0.00"` for `DP`). --- ## Trade (422) Channel `trade`, event `` (for example `BTCUSDT`). One message per execution. Subscribe with [message type 151](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md). ```json [422, { "type": 422, "channel": "trade", "event": "BTCUSDT", "D": "1790168707937", "I": "101963842125958698", "A": "0.01170258", "P": "85400", "PS": "BTCUSDT", "S": 0 }] ``` | Code | Meaning | | ---- | -------------------------------------------- | | `D` | Timestamp, milliseconds since epoch (string) | | `I` | Trade id (string) | | `A` | Amount | | `P` | Price | | `PS` | Pair symbol | | `S` | Side - `0` buy, `1` sell | `A` and `P` carry up to 10 decimal places, and `A` is always positive regardless of side. `S` is the taker's side: `buy` means the buyer took liquidity. [Get Trades](https://global.btcturk.com/apidoc/api/public-endpoints/trades.md) uses the same convention. --- ## Full Order Book (431) Channel `orderbook`, event `` (for example `BTCUSDT`). A complete snapshot of the book. Subscribe with [message type 151](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md). One snapshot is pushed immediately on a successful join. ```json [431, { "type": 431, "channel": "orderbook", "event": "BTCUSDT", "CS": 1841, "PS": "BTCUSDT", "BO": [ { "P": "85391", "A": "0.00292756" } ], "AO": [ { "P": "85412", "A": "0.0983193" } ] }] ``` | Code | Meaning | | ---- | ---------------------------------------------- | | `CS` | Change set - increments as the book changes | | `PS` | Pair symbol | | `BO` | Bid orders, each `{ "P": price, "A": amount }` | | `AO` | Ask orders, same shape | Prices and amounts are strings without trailing zeros. To keep a local book up to date without re-receiving the whole snapshot, subscribe to [Order Book Difference](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book-difference.md) as well and apply its updates in `CS` order. --- ## Order Book Difference (432) Channel `obdiff`, event `` (for example `BTCUSDT`). Only the price levels that changed since the previous change set. Subscribe with [message type 151](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md). ```json [432, { "type": 432, "channel": "obdiff", "event": "BTCUSDT", "CS": 1842, "PS": "BTCUSDT", "BO": [ { "CP": 0, "P": "85391", "A": "0.005" } ], "AO": [ { "CP": 3, "P": "85412", "A": "0.0983193" } ] }] ``` | Code | Meaning | | ---- | -------------------------------------------- | | `CS` | Change set - follows the previous one | | `PS` | Pair symbol | | `BO` | Changed bid levels | | `AO` | Changed ask levels | Each changed level adds a `CP` (change process) code to the price/amount pair: | `CP` | Meaning | | ---- | --------------------------------------------------------- | | `0` | Amount at this price changed; `A` is the new amount | | `1` | New price level; `A` is its amount | | `3` | Price level removed; `A` is the amount it had before | Prices and amounts are strings without trailing zeros. :::warning `2` is not used. If you receive any other value, discard your book and subscribe to `orderbook` again. ::: Use `CS` to detect gaps: apply a difference only when its `CS` follows the one you last applied. If it does not, drop your local book and resubscribe to [Full Order Book](https://global.btcturk.com/apidoc/websocket-feed/public-messages/order-book.md) for a fresh snapshot. --- ## Balance Updated (201) Sent when any of your balances changes. The payload is for internal use; call [Get Account Balance](https://global.btcturk.com/apidoc/api/private-endpoints/account-balance.md) to read the new values. Requires an [authenticated](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) connection; there is no subscription for it. ```json [201, { "type": 201, "userId": 12345, "payload": "..." }] ``` | Field | Description | | --------- | ------------------------------------ | | `userId` | Your user id. | | `payload` | Opaque string - see the warning below. | :::warning `payload` is an **opaque string**. Its contents are not part of this API's contract and may change without notice. ::: Treat a `201` as "your balances changed - re-read them" and call [Get Account Balance](https://global.btcturk.com/apidoc/api/private-endpoints/account-balance.md) rather than parsing `payload`. --- ## User Trade (423) Sent when one of your orders executes. Requires an [authenticated](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) connection; there is no subscription for it. ```json [423, { "id": 987654, "orderId": 123456789, "timestamp": 1790168707937, "numeratorSymbol": "BTC", "denominatorSymbol": "USDT", "amount": "0.01170258", "price": "85400", "fee": "0.00000000", "tax": "0.00000000", "orderType": "buy", "role": "taker", "orderClientId": "my-client-id", "preciseAmount": 0.01170258 }] ``` | Field | Description | | ------------------- | ------------------------------------------------------------- | | `id` | Trade id. | | `orderId` | Id of the order that executed. | | `timestamp` | Milliseconds since epoch (number). | | `numeratorSymbol` | Base asset, e.g. `BTC`. | | `denominatorSymbol` | Quote asset, e.g. `TRY`. | | `amount` | Executed amount, at the pair's numerator precision. | | `price` | Execution price, at the pair's denominator precision. | | `fee` | Fee charged, 8 decimals. | | `tax` | Tax charged, 8 decimals. | | `orderType` | Literal string `"buy"` or `"sell"`. | | `role` | `maker` or `taker`. | | `orderClientId` | Your client id, when one was supplied. | | `preciseAmount` | The amount again, unrounded and as a JSON number. | :::info This is the one message whose payload has **no `type` field** - identify it from the first array element. Use `preciseAmount` rather than `amount` when rounding matters. ::: Numbers in private messages can carry trailing zeros (for example `156.6400000000000000`). Always parse them as decimals. `fee` can differ from [Get User Trade Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/user-transactions.md) in the last decimal place. Trade history over REST is authoritative. --- ## Order Matched (441) Sent when one of your orders is matched. Requires an [authenticated](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) connection; there is no subscription for it. :::info The REST response is the authoritative confirmation of your request. WebSocket events confirm the same change shortly afterwards; do not wait for them before considering an order placed or cancelled. ::: ```json [441, { "type": 441, "id": 123456789, "user": 12345, "isBid": true, "method": 0, "pair": 19, "symbol": "BTCUSDT", "amount": "0.01170258", "price": "85400", "clientId": "my-client-id", "timestamp": "1790070989160" }] ``` | Field | Description | | ----------- | -------------------------------------------------------- | | `id` | Order id. | | `user` | Your user id. | | `isBid` | `true` for a buy, `false` for a sell. | | `method` | `0` limit, `1` market, `2` stopLimit, `3` stopMarket. | | `pair` | Pair id. | | `symbol` | Pair symbol. | | `amount` | Matched amount, up to 10 decimals. | | `price` | Match price, up to 10 decimals. | | `clientId` | Your client id, when one was supplied. | | `timestamp` | Milliseconds since epoch, as a **string**. | For the resulting execution detail - fee, tax and the exact amount - see [User Trade](https://global.btcturk.com/apidoc/websocket-feed/private-messages/user-trade.md). Numbers in private messages can carry trailing zeros (for example `156.6400000000000000`). Always parse them as decimals. --- ## Order Inserted (451) Sent when one of your orders enters the book. Requires an [authenticated](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) connection; there is no subscription for it. :::info The REST response is the authoritative confirmation of your request. WebSocket events confirm the same change shortly afterwards; do not wait for them before considering an order placed or cancelled. ::: ```json [451, { "type": 451, "id": 123456789, "userId": 12345, "pairId": 19, "symbol": "BTCUSDT", "method": 0, "orderType": 0, "price": "85400", "amount": "0.1", "numLeft": "0.1", "denomLeft": "8540", "newOrderClientId": "my-client-id" }] ``` | Field | Description | | ------------------ | ----------------------------------------------------- | | `id` | Order id. | | `userId` | Your user id. | | `pairId` | Pair id. | | `symbol` | Pair symbol. | | `method` | `0` limit, `1` market, `2` stopLimit, `3` stopMarket. | | `orderType` | `0` buy, `1` sell. | | `price` | Order price. | | `amount` | Order amount, in the numerator (base) asset. | | `numLeft` | **Unfilled** amount still on the order. | | `denomLeft` | Order **total** in the denominator (quote) asset. | | `newOrderClientId` | Your client id, when one was supplied. | :::warning Despite the symmetry of their names, `numLeft` and `denomLeft` are not the same kind of value: `numLeft` is what remains unfilled, while `denomLeft` is the order's total quote value - not a remainder. Do not compute a fill ratio from the two. ::: Unlike the market-data channels, these values are plain decimal strings with no fixed number of decimals - do not assume a fixed scale when parsing. [Order Cancelled](https://global.btcturk.com/apidoc/websocket-feed/private-messages/order-cancelled.md) carries an identical payload under type `452`. Numbers in private messages can carry trailing zeros (for example `156.6400000000000000`). Always parse them as decimals. --- ## Order Cancelled (452) Sent when one of your orders is cancelled. Requires an [authenticated](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) connection; there is no subscription for it. :::info The REST response is the authoritative confirmation of your request. WebSocket events confirm the same change shortly afterwards; do not wait for them before considering an order placed or cancelled. ::: ```json [452, { "type": 452, "id": 123456789, "userId": 12345, "pairId": 19, "symbol": "BTCUSDT", "method": 0, "orderType": 0, "price": "85400", "amount": "0.1", "numLeft": "0.1", "denomLeft": "8540", "newOrderClientId": "my-client-id" }] ``` | Field | Description | | ------------------ | ----------------------------------------------------- | | `id` | Order id. | | `userId` | Your user id. | | `pairId` | Pair id. | | `symbol` | Pair symbol. | | `method` | `0` limit, `1` market, `2` stopLimit, `3` stopMarket. | | `orderType` | `0` buy, `1` sell. | | `price` | Order price. | | `amount` | Order amount, in the numerator (base) asset. | | `numLeft` | **Unfilled** amount still on the order. | | `denomLeft` | Order **total** in the denominator (quote) asset. | | `newOrderClientId` | Your client id, when one was supplied. | :::warning Despite the symmetry of their names, `numLeft` and `denomLeft` are not the same kind of value: `numLeft` is what remains unfilled, while `denomLeft` is the order's total quote value - not a remainder. Do not compute a fill ratio from the two. ::: Unlike the market-data channels, these values are plain decimal strings with no fixed number of decimals - do not assume a fixed scale when parsing. :::info An order cancelled through [Cancel Orders](https://global.btcturk.com/apidoc/api/private-endpoints/cancel-order.md) produces a `452`. That push is the confirmation that the cancellation was applied - you do not need to poll for it, though polling remains a safe fallback if your connection dropped. ::: [Order Inserted](https://global.btcturk.com/apidoc/websocket-feed/private-messages/order-inserted.md) carries an identical payload under type `451`. Numbers in private messages can carry trailing zeros (for example `156.6400000000000000`). Always parse them as decimals. --- ## Reconnecting The server sends a WebSocket ping frame every 15 seconds and closes the connection when it has received no pong for more than 31 seconds. Most WebSocket libraries answer pings automatically. The feed has no heartbeat message of its own. Tickers are pushed about every 750 ms, even when nothing has changed, so if a subscribed ticker channel is silent for more than 5 seconds, reconnect. After any reconnect you must: 1. Re-send [`114`](https://global.btcturk.com/apidoc/websocket-feed/authentication.md) if you need private messages - authentication does not survive a reconnect. 2. Re-send every [`151`](https://global.btcturk.com/apidoc/websocket-feed/subscribing.md) subscription - subscriptions are per-connection and are dropped when the socket closes. 3. Discard any locally-maintained order book and rebuild it from the snapshot that follows your `orderbook` join. Events that occurred while you were disconnected are **not replayed**. After reconnecting, read [Open Orders](https://global.btcturk.com/apidoc/api/private-endpoints/open-orders.md) and balances over REST, and reconcile against [All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md), [Get User Trade Transactions](https://global.btcturk.com/apidoc/api/private-endpoints/user-transactions.md) and [Get Account Balance](https://global.btcturk.com/apidoc/api/private-endpoints/account-balance.md) - before trusting your local state. --- ## Error Codes Market-data, order and account endpoints return errors in this format: ```json { "success": false, "message": "PAIR_NOT_FOUND_ERROR", "code": 1027 } ``` When a field is missing or malformed, `data` names the field: ```json { "success": false, "message": "INVALID_MODEL", "code": 1000, "data": { "quantity": ["INVALID_VALUE"] } } ``` Handle errors by `code`, not by `message`. | Message | Code | Meaning | | --- | --- | --- | | INVALID_MODEL | 1000 | A field is missing or malformed; `data` names the field | | PAIR_NOT_FOUND_ERROR | 1027 | The pair does not exist | | TICKER_NOT_FOUND_ERROR | 1028 | The pair exists but has no ticker yet | | INVALID_REQUEST_ERROR | 1038 | A parameter is missing or invalid, or the request body is missing (`data.body` is `REQUEST_BODY_REQUIRED`) | | INVALID_WITHDRAWAL_AMOUNT | 1038 | The withdrawal amount is zero, negative or malformed | | WITHDRAWAL_AMOUNT_EXCEEDED | 1038 | The withdrawal amount is above the maximum for the asset | | INVALID_ADDRESS_TAG | 1038 | The address tag (memo) is missing or invalid for the network | | ORDER_COULD_NOT_BE_CANCELED | 1051 | The order cannot be cancelled: it is a market order, it is already filled, or a temporary failure occurred (retry). An order that is already cancelled returns `200 SUCCESS` instead | | NO_ORDER_MATCHES_YOUR_REQUEST | 1052 | The order to cancel does not exist or is not yours | | BALANCE_NOT_ENOUGH | 1055 | Not enough free balance | | EXIST_PENDING_REQUEST | 1059 | You already have a pending withdrawal for this currency and network (HTTP `409`) | | CURRENCY_NOT_FOUND | 1064 | The currency does not exist | | AMOUNT_BELOW_MINIMUM_WITHDRAWAL_AMOUNT | 1068 | The amount is below the minimum withdrawal | | PAIR_SYMBOL_IS_NECESSARY | 1079 | `pairSymbol` is required | | CURRENCY_CHANNEL_NOT_FOUND | 1081 | The network (`asset`) does not exist | | WITHDRAWAL_ADDRESS_NOT_WHITELISTED | 1091 | The address is not one of your saved withdrawal addresses for this currency and network | | FAILED_SET_ORDER_UNEXPECTED | 1117 | An unexpected error occurred while placing the order; check [All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md) by `orderClientId` before retrying | | FAILED_MARKET_ORDER | 1118 | The market order was rejected; check `quantity` and `pairSymbol` | | FAILED_LIMIT_ORDER | 1120 | The limit order was rejected; check `price`, `quantity` and `pairSymbol` | | FAILED_ORDER_WITH_OPEN_ORDERS | 1122 | An identical order (same pair, side, price and quantity) is already open | | FAILED_MIN_TOTAL_AMOUNT | 1123 | Price × quantity is below the pair's `minExchangeValue` | | FAILED_INVALID_PRICE_SCALE | 1126 | The price has too many decimals | | FAILED_INVALID_QUANTITY_SCALE | 1127 | The quantity has too many decimals | | ORDER_METHOD_NOT_SUPPORTED | 1134 | The order method is unknown, not allowed on this pair, or a stop order (`stoplimit`, `stopmarket`), which the API does not accept | | ORDER_NOT_FOUND | 1152 | The order does not exist or is not yours | | ORDER_TYPE_NOT_SUPPORTED | 1193 | `orderType` must be `buy` or `sell` | | PRICE_MUST_BE_LESS_THAN_MAXPRICE | 1226 | A buy price is above the pair's `maxPrice` | | PRICE_MUST_BE_GREATER_THAN_MINPRICE | 1227 | A sell price is below the pair's `minPrice` | | DUPLICATE_CLIENT_ORDER_ID | 1246 | `newOrderClientId` was already used in the last 24 hours; `data.id` holds the existing order's id, or `null` when the first request's result is not known yet (look the order up by `orderClientId` in [Open Orders](https://global.btcturk.com/apidoc/api/private-endpoints/open-orders.md) or [All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md)) | | ORDER_MAX_PRICE_EXCEEDED | 8003 | The price is above `maximumLimitOrderPrice` | | ORDER_MIN_PRICE_EXCEEDED | 8004 | The price is below `minimumLimitOrderPrice` | | ORDER_INSERT_BLOCKED | 8005 | Orders on this pair are paused for maintenance; retry later | | ORDER_CANCEL_BLOCKED | 8006 | Cancels on this pair are paused for maintenance; retry later | | TOO_MANY_REQUESTS | 8018 | Rate limit exceeded; see [Rate Limits](https://global.btcturk.com/apidoc/api/private-endpoints/rate-limits.md) | [Create Crypto Withdrawal](https://global.btcturk.com/apidoc/api/private-endpoints/crypto-withdrawals.md) uses the format above; its page lists every withdrawal error. The other wallet endpoints (deposit addresses, withdrawal addresses, withdrawal lookups) return RFC 7807 problem documents: ```json { "title": "Not Found", "type": "crypto-withdrawal-not-found", "status": 404, "detail": "Not found" } ``` | type | Status | | --- | --- | | symbol-not-found | 400 | | currency-channel-not-found | 400 | | crypto-deposit-address-not-found | 404 | | crypto-withdrawal-address-not-found | 404 | | crypto-withdrawal-not-found | 404 | | withdrawal-address-blocked, suspicious-address, user-blocked | 403 | --- ## Retry Strategy Guideline #### Retry Strategies These strategies are appropriate to implement in cases like receiving **5xx status code** from server and system is under maintenance and end date of maintanance is not specified. When implementing retry logic in your application, it is important to have a clear retry strategy in place. A retry strategy defines how and when to retry a request after an error. Here are some common strategies for retrying requests: * **Fixed delay retry:** In this strategy, the same amount of time is waited between each retry attempt. For example, you could wait 1 second between each retry attempt. This is the simplest retry strategy, but it can be less effective if the error is not transient and the delay is not long enough to allow the issue to be resolved. * **Incremental delay retry:** In this strategy, the amount of time waited between retry attempts is increased with each retry. For example, you could start by waiting 1 second, then 2 seconds, then 3 seconds, and so on. This strategy can be more effective at allowing temporary errors to be resolved in case they are not transient. * **Exponential backoff retry:** In this strategy, the amount of time waited between retry attempts is increased exponentially with each retry. For example, you could start by waiting 1 second, then 2 seconds, then 4 seconds, then 8 seconds, and so on. This strategy is similar to incremental delay, but the increase in delay is exponential rather than linear. This strategy can be more effective at allowing temporary errors to be resolved in case they are not transient. :::info There are pros and cons to **Incremental Delay Retry** and **Exponential Back-off Retry** strategies. Incremental delay retry is simpler to implement and may be more predictable, but it may not be as effective at handling temporary failures. Exponential backoff retry is more complex to implement, but it may be more effective at handling temporary failures because the delays between retries increase over time, giving the system more time to recover. ::: Overall, the choice of which retry strategy to use depends on the specific needs of the system and the type of failures that are being encountered. In some cases, a combination of both strategies may be used to achieve the desired level of reliability. You can choose the retry strategy that best fits your needs, or you can implement a custom retry strategy that combines different strategies. #### Retrying safely * **Orders:** always send your own `newOrderClientId` (up to 50 characters). If a request times out, send it again with the same `newOrderClientId`. If the first one was placed, you receive `DUPLICATE_CLIENT_ORDER_ID` (1246) with the existing order's id in `data`, and no second order is created. If `data.id` is `null`, the result of the first request is not known yet: find the order by `orderClientId` in [Open Orders](https://global.btcturk.com/apidoc/api/private-endpoints/open-orders.md) or [All Orders](https://global.btcturk.com/apidoc/api/private-endpoints/all-orders.md) before sending a new order with a different `newOrderClientId`. * **Withdrawals:** always send your own `uniqueTransactionId` and reuse it when retrying. * **Cancels:** cancelling an order that is already cancelled returns `200 SUCCESS`, so cancels can be retried. :::info To prevent multiple insertions when inserting a new resource, we recommend checking that the resource does not already exist on the server before making a POST request. You can use GET endpoints to verify the existence of the resource before attempting to insert it. ::: #### Rate Limits If you receive a response with a status code of **429 (Too Many Requests)**, it means that you have exceeded the rate limit for the endpoint you are trying to access. In this case, you will need to wait for a certain amount of time before making a new request. This time is indicated in the Retry-After header of the response. For example, a Retry-After value of 52 means that you need to wait 52 seconds before making a new request. It is important to implement proper retry logic in your application to handle these rate-limit errors. Here are some best practices to follow when implementing retry logic: * Always check for a Retry-After header in the response if you receive a status code 429, before retrying a request. * **If the** Retry-After **header is present**, wait for the amount of time indicated in the header before retrying the request. Do not retry the request immediately, because you will keep getting 429 responses until a specified amount of time in the header passes. * **If the header is not present**, you can implement one of the retry strategies described above. You can get information about our rate limits by visiting; [Rate Limits](https://global.btcturk.com/apidoc/api/private-endpoints/rate-limits.md) --- ## Pairs Scale (Quantity/Price) Each pair limits how many decimal places quantities and prices can have. Read the limits from [Get Exchange Info](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md) (`/api/v2/server/exchangeinfo`): * `numeratorScale` is the maximum number of decimals for `quantity` in the base asset. * `denominatorScale` is the maximum number of decimals for `price` in the quote asset. It also applies to `quantity` on market buy orders, where `quantity` is the quote amount to spend. Example (BTCUSDT): `numeratorScale` is 8 and `denominatorScale` is 0, so quantity `0.00012345` and price `85400` are valid, while price `85400.5` returns FAILED_INVALID_PRICE_SCALE (1126). A market buy with quantity `12.5` (USDT) returns FAILED_INVALID_QUANTITY_SCALE (1127). ```json { "id": 19, "name": "BTCUSDT", "nameNormalized": "BTC_USDT", "status": "TRADING", "numerator": "BTC", "denominator": "USDT", "numeratorScale": 8, "denominatorScale": 0, "hasFraction": false, "filters": [ { "filterType": "PRICE_FILTER", "minPrice": "65518.968", "maxPrice": "98278.452", "tickSize": "1", "minExchangeValue": "9.91", "minAmount": null, "maxAmount": null } ], "orderMethods": ["MARKET", "LIMIT"], "displayFormat": "#,###", "commissionFromNumerator": false, "order": 2000, "priceRounding": false, "isNew": false, "marketPriceWarningThresholdPercentage": 0.25, "maximumOrderAmount": null, "maximumLimitOrderPrice": 818860.0, "minimumLimitOrderPrice": 8188.6 } ``` --- ## FAQ (Frequently Asked Questions)
BtcTurk Global API Frequently Asked Questions Answers to common questions about integrating with the BtcTurk Global API.
Why do I receive 401 - Unauthorized error ##### 401 Unauthorized A 401 response has no body. Check, in this order: the three headers (`X-PCK`, `X-Stamp`, `X-Signature`) are present; `X-Stamp` is within the accepted window (synchronise your clock with NTP); the signature follows [Authentication V1](https://global.btcturk.com/apidoc/api/authentication/authentication-v1.md) exactly; the request comes from the IP address registered for the key; and the key has the [permission group](https://global.btcturk.com/apidoc/api-access-permissions.md) the endpoint needs.
Why do I receive Invalid nonce error `X-Stamp` is a regular integer number — the current Unix timestamp in milliseconds. By default there is a 5 second backward tolerance (extendable via `X-Nonce`, up to 60 seconds) and a fixed 5 second forward tolerance, but your server's current time must be synced with the API server time, which uses UTC.
Why do I receive 400 - BALANCE_NOT_ENOUGH error The order was rejected because the free balance does not cover the order plus its commission. The response is `400 Bad Request` with `"message": "BALANCE_NOT_ENOUGH"` and `"code": 1055`. For TRY pairs, you need to calculate the commission and deduct from the total amount. For example, if you would like to order 1.00000000 BTC for 50,000TRY, your free balance must be at least 50,090TRY (Maker/Taker commissions are being calculated after your order executed. If your order matches immediately you'll be charged as Taker. Otherwise, you'll be charged as Maker and the commission difference will be added to your balance)
Why do I receive 429 - Too many requests This means you exceeded the rate limit. Refer to Rate Limits section. Also please check the Retry-After response HTTP header. [**https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After**](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) It indicates how long the user agent should wait before making a follow-up request.
What is the difference between API versions and which one is suitable for me There are two versions **V1** and **V2**. * **V1** hosts most authentication-required endpoints (balances, orders, crypto deposit/withdrawal addresses, crypto withdrawals, transactions, volumes) as well as some public reference data (currencies, pairs), all with HMAC authentication where required. * **V2** hosts public market data: ticker, orderbook, trades, exchangeinfo, currency channels and crypto channels. If you would like to request data related to your user account, you should use the relevant **V1** endpoint with HMAC authentication. Public market data is served from **V2** (with a couple of public endpoints on V1).
Does BtcTurk Global API have a WebSocket feed? Yes. Connect to `wss://ws.global.btcturk.com` for realtime ticker, trade and order book data, and — after authenticating with your API key — for your own order, trade and balance events. See [Connection & Message Format](https://global.btcturk.com/apidoc/websocket-feed/connection.md) for the message protocol.
How are rate limits set? All requests from the same client, public and private, count towards the same limits: 3 requests per 500 ms and 60 per 10 seconds. See [Rate Limits](https://global.btcturk.com/apidoc/api/private-endpoints/rate-limits.md).
What are commission rates? BtcTurk Global API proxies order execution to BtcTurk's trading engine, so commission rates follow BtcTurk's published fee schedule. Check with your BtcTurk Global API operator for up-to-date rates.
What is the minimum transaction limit? You can check the minimum transaction limits on our exchangeInfo endpoint. Minimum transaction limits can be displayed with the `minExchangeValue` parameter. See [ExchangeInfo](https://global.btcturk.com/apidoc/api/public-endpoints/exchange-info.md) for more information.
What is the meaning of hasFraction field in ExchangeInfo endpoint? Orders are not validated against `hasFraction`. A price can have at most `denominatorScale` decimal places; a price with more returns `FAILED_INVALID_PRICE_SCALE` (1126). See [Pairs Scale (Quantity/Price)](https://global.btcturk.com/apidoc/pairs-scale-quantity-price.md).
Have more questions If you have more questions, please reach out — see [Contact Us](https://global.btcturk.com/apidoc/contact-us.md).
--- ## Contact Us For questions about the BtcTurk Global API, e-mail [support@global.btcturk.com](mailto:support@global.btcturk.com). Please include your public API key (never your private key), the time of the request in UTC, the endpoint, and the full response body.