OTC Trading
RFQ workflow and OTC order execution with external dealers
OTC Trading
This guide covers the OTC (Over-the-Counter) trading workflow for executing trades with external dealers.
Overview
OTC trading allows clients to execute large trades with external dealers, with the platform acting as an intermediary. This avoids impacting the public order book on the Marketplace.
Prerequisites
- Authenticated session (JWT or API key)
CanTradepermission- Sub-account with
venue=VENUE_OTCor OTC-enabled - Pair must have
otcTradable= true
Step 1: Check OTC Listing
Before trading, verify that OTC trading is available for your desired pair.
Endpoint: GET /api/rest/v1/otc/listings/{pairId}
Request
curl -X GET "https://api.t-dx.com/api/rest/v1/otc/listings/79b1db24-7dc8-45d1-ab77-44318f872a8e" \
-H "Authorization: Bearer <access-token>"Response (200 OK)
{
"result": {
"id": "listing-uuid",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"minIncrement": "0.01",
"minRfqQuantity": "1.0",
"minOrderQuantity": "0.1",
"live": true,
"monitoringThreshold": 10000,
"createdAt": "2023-01-01T00:00:00Z"
}
}Listing Fields
| Field | Description |
|---|---|
minIncrement | Minimum price increment |
minRfqQuantity | Minimum quantity for RFQ |
minOrderQuantity | Minimum quantity for orders |
live | Whether OTC trading is active |
Step 2: Create OTC Order
Submit an OTC order for execution.
Endpoint: POST /api/rest/v1/otc/orders
Request
curl -X POST "https://api.t-dx.com/api/rest/v1/otc/orders" \
-H "Authorization: Bearer <access-token>" \
-H "Content-Type: application/json" \
-d '{
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"type": "TYPE_LIMIT",
"quantity": "10.00000000",
"price": "45000.00",
"timeInForce": "TIME_IN_FORCE_GOOD_TILL_CANCELED"
}'Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
subAccountId | UUID | Yes | Sub-account for the order |
pairId | UUID | Yes | Trading pair ID |
side | enum | Yes | SIDE_BUY or SIDE_SELL |
type | enum | Yes | Order type (see below) |
quantity | decimal | Yes | Order quantity |
price | decimal | No | Limit price (required for limit orders) |
timeInForce | enum | No | Time in force policy |
comment | string | No | Optional order comment |
clientOrderId | string | No | Client-provided identifier |
dry | boolean | No | If true, validates without creating |
startAt | timestamp | No | Scheduled start time |
endAt | timestamp | No | Expiration time (required for TWAP) |
parameters | object | No | Order-type specific parameters |
Order Types
| Type | Description |
|---|---|
TYPE_LIMIT | Limit order at specified price |
TYPE_MARKET | Market order |
TYPE_LIMIT_TWAP | Time-weighted average price |
Stop Orders Stop and stop-limit orders are created by addingstopParamsto theparametersfield. UseTYPE_MARKETwithstopParamsfor a stop order, orTYPE_LIMITwithstopParamsfor a stop-limit order. See Stop Order Example below.
Time in Force
| Value | Description |
|---|---|
TIME_IN_FORCE_GOOD_TILL_CANCELED | Remains active until filled or cancelled |
TIME_IN_FORCE_IMMEDIATE_OR_CANCEL | Fill immediately or cancel |
TIME_IN_FORCE_FILL_OR_KILL | Fill completely or cancel |
Response (200 OK)
{
"result": {
"id": "otc-order-uuid",
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"type": "TYPE_LIMIT",
"status": "STATUS_OPEN",
"quantity": "10.00000000",
"cumulativeQuantity": "0.00000000",
"price": "45000.00",
"timeInForce": "TIME_IN_FORCE_GOOD_TILL_CANCELED",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
}Step 3: List OTC Orders
View your OTC orders.
Endpoint: GET /api/rest/v1/otc/orders/by-sub-account/{subAccountId}
Request
curl -X GET "https://api.t-dx.com/api/rest/v1/otc/orders/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804" \
-H "Authorization: Bearer <access-token>"Query Parameters
This endpoint supports standard pagination, sorting, and filtering.
Supported filters: status, side, pair_id
Response (200 OK)
{
"result": [
{
"id": "otc-order-uuid",
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"type": "TYPE_LIMIT",
"status": "STATUS_FILLED",
"quantity": "10.00000000",
"cumulativeQuantity": "10.00000000",
"price": "45000.00",
"clientAmount": "449500.00",
"timeInForce": "TIME_IN_FORCE_GOOD_TILL_CANCELED",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:35:00Z"
}
],
"pagination": {
"cursors": {
"self": "eyJTb3J0cyI6W10sIkZpbHRlcnMiOltdLCJJc0ZpcnN0Ijp0cnVlfQ==",
"first": "eyJTb3J0cyI6W10sIkZpbHRlcnMiOltdLCJJc0ZpcnN0Ijp0cnVlfQ==",
"last": "",
"next": "",
"previous": ""
}
}
}OTC Order Status Values
| Status | Description |
|---|---|
STATUS_TENTATIVE | Order pending confirmation |
STATUS_PENDING | Order pending activation |
STATUS_OPEN | Order active in the market |
STATUS_FILLED | Fully executed |
STATUS_CANCELED | Cancelled |
STATUS_REJECTED | Rejected by system |
STATUS_PENDING_CANCEL | Cancel request pending |
Step 4: Get Specific OTC Order
Endpoint: GET /api/rest/v1/otc/orders/by-sub-account/{subAccountId}/{orderId}
Request
curl -X GET "https://api.t-dx.com/api/rest/v1/otc/orders/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804/otc-order-uuid" \
-H "Authorization: Bearer <access-token>"Response (200 OK)
{
"result": {
"id": "otc-order-uuid",
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"type": "TYPE_LIMIT",
"status": "STATUS_FILLED",
"quantity": "10.00000000",
"cumulativeQuantity": "10.00000000",
"price": "45000.00",
"clientAmount": "449500.00",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:35:00Z"
}
}Step 5: Cancel OTC Order
Cancel an open OTC order.
Endpoint: DELETE /api/rest/v1/otc/orders/by-sub-account/{subAccountId}/{orderId}
Request
curl -X DELETE "https://api.t-dx.com/api/rest/v1/otc/orders/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804/otc-order-uuid" \
-H "Authorization: Bearer <access-token>"Response (200 OK)
Empty response on success.
Step 6: View OTC Trades
View executed OTC trades.
Endpoint: GET /api/rest/v1/otc/trades/by-sub-account/{subAccountId}
Request
curl -X GET "https://api.t-dx.com/api/rest/v1/otc/trades/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804" \
-H "Authorization: Bearer <access-token>"Query Parameters
This endpoint supports standard pagination and filtering.
Supported filters: order_id, side, pair_id
Sort restriction: OTC trades can only be sorted by executed_at:
sort=executed_at-desc(default)sort=executed_at-asc
Note: Unlike other endpoints, sorting by
created_atis not supported and will return a 400 error.
Response (200 OK)
{
"result": [
{
"id": "otc-trade-uuid",
"orderId": "otc-order-uuid",
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"quantity": "10.00000000",
"amount": "450000.00",
"clientAmount": "449500.00",
"executedAt": "2024-01-15T10:35:00Z"
}
],
"pagination": {
"cursors": {
"self": "eyJTb3J0cyI6W10sIkZpbHRlcnMiOltdLCJJc0ZpcnN0Ijp0cnVlfQ==",
"first": "eyJTb3J0cyI6W10sIkZpbHRlcnMiOltdLCJJc0ZpcnN0Ijp0cnVlfQ==",
"last": "",
"next": "",
"previous": ""
}
}
}Step 7: Get Specific OTC Trade
Endpoint: GET /api/rest/v1/otc/trades/by-sub-account/{subAccountId}/{tradeId}
Request
curl -X GET "https://api.t-dx.com/api/rest/v1/otc/trades/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804/otc-trade-uuid" \
-H "Authorization: Bearer <access-token>"Step 8: View Quotes (Optional)
View quotes associated with your orders.
Endpoint: GET /api/rest/v1/quotes/by-sub-account/{subAccountId}
Request
curl -X GET "https://api.t-dx.com/api/rest/v1/quotes/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804" \
-H "Authorization: Bearer <access-token>"Query Parameters
This endpoint supports standard pagination, sorting, and filtering.
Supported filters: status, side, pair_id
Response (200 OK)
{
"result": [
{
"id": "quote-uuid",
"rfqId": "rfq-uuid",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"status": "QUOTE_STATUS_ACCEPTED",
"quantity": "10.00000000",
"amount": "450000.00",
"fees": "500.00",
"clientAmount": "449500.00",
"quoteSide": "ASK",
"operationSide": "SIDE_BUY",
"acceptedAt": "2024-01-15T10:31:00Z"
}
],
"pagination": {
"cursors": {
"self": "eyJTb3J0cyI6W10sIkZpbHRlcnMiOltdLCJJc0ZpcnN0Ijp0cnVlfQ==",
"first": "eyJTb3J0cyI6W10sIkZpbHRlcnMiOltdLCJJc0ZpcnN0Ijp0cnVlfQ==",
"last": "",
"next": "",
"previous": ""
}
}
}Quote Status Values
| Status | Description |
|---|---|
QUOTE_STATUS_ACCEPTED | Quote accepted |
QUOTE_STATUS_CONFIRMED_BY_COUNTERPARTY | Confirmed by counterparty |
QUOTE_STATUS_REJECTED_BY_COUNTERPARTY | Rejected by counterparty |
QUOTE_STATUS_SETTLED | Trade settled |
QUOTE_STATUS_MISSING | Quote not available |
Get Specific Quote
Endpoint: GET /api/rest/v1/quotes/by-sub-account/{subAccountId}/rfq/{rfqId}
curl -X GET "https://api.t-dx.com/api/rest/v1/quotes/by-sub-account/7376524e-6b6b-4137-9719-7e07a7709804/rfq/rfq-uuid" \
-H "Authorization: Bearer <access-token>"TWAP Order Example
Create a TWAP (Time-Weighted Average Price) order:
curl -X POST "https://api.t-dx.com/api/rest/v1/otc/orders" \
-H "Authorization: Bearer <access-token>" \
-H "Content-Type: application/json" \
-d '{
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"type": "TYPE_LIMIT_TWAP",
"quantity": "100.00000000",
"price": "45000.00",
"startAt": "2024-01-15T10:00:00Z",
"endAt": "2024-01-15T18:00:00Z",
"parameters": {
"twapParams": {
"clipSize": "0.5"
}
}
}'Stop Order Example
Create a stop-limit order that triggers when the price reaches 44000.00:
curl -X POST "https://api.t-dx.com/api/rest/v1/otc/orders" \
-H "Authorization: Bearer <access-token>" \
-H "Content-Type: application/json" \
-d '{
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_BUY",
"type": "TYPE_LIMIT",
"quantity": "10.00000000",
"price": "45000.00",
"timeInForce": "TIME_IN_FORCE_GOOD_TILL_CANCELED",
"parameters": {
"stopParams": {
"triggerPrice": "44000.00"
}
}
}'For a stop (market) order, use TYPE_MARKET instead of TYPE_LIMIT and omit the price field:
curl -X POST "https://api.t-dx.com/api/rest/v1/otc/orders" \
-H "Authorization: Bearer <access-token>" \
-H "Content-Type: application/json" \
-d '{
"subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
"pairId": "79b1db24-7dc8-45d1-ab77-44318f872a8e",
"side": "SIDE_SELL",
"type": "TYPE_MARKET",
"quantity": "10.00000000",
"parameters": {
"stopParams": {
"triggerPrice": "40000.00"
}
}
}'Stop Parameters
| Field | Type | Required | Description |
|---|---|---|---|
triggerPrice | decimal | Yes | The price that, once reached, will trigger the order |
Error Scenarios
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_ARGUMENT | Invalid quantity, price, or parameters |
| 403 | NOT_ENOUGH_FUNDS | Insufficient balance for trade |
| 403 | PERMISSION_DENIED | No trade permission |
| 404 | NOT_FOUND | Order or trade not found |
| 422 | FAILED_PRECONDITION | OTC trading not enabled for pair |
Related
- Trading Data - Market data and pricing
- Wallet Information - Balance verification
- Domains: Trading - Full trading API reference
Updated 5 days ago
