Introduction
The Open Trade REST API is a request/response counterpart to the WebSocket API. Every endpoint here is a direct REST equivalent of a WebSocket channel or command — if you'd rather poll or fire one-off requests instead of holding a persistent socket open, this is the interface to use.
REST Base URL
/hermes-ws-gateway/api/rest/balance — concatenate host + that full path.
Endpoint Groups
/public/. Send the Authorization header on all requests below.
/public/ path (market data, no account-specific data)
GET /public/asset-listGET /public/instrument-listGET /public/order-book-public
/trade-private/ path and account endpoints (account/order data)
POST / PUT / DELETE /trade-private/ordersGET /trade-private/trades-historyGET /trade-private/orders-historyGET /trade-private/active-ordersGET /client-portfolioGET /client-portfolio-historyGET /balance
Versioning & Headers
Every REST call — public or private — must include the X-API-Version header. This lets Open Trade evolve the REST contract without breaking existing integrations.
| Header | Required | Description |
|---|---|---|
| X-API-Version | Yes | API version to target. Current value: 1.0.0 |
| Authorization | Private only | Bearer JWT token, obtained via the authentication flow below. Required on every private endpoint. |
Authentication
Private REST endpoints use the exact same credential exchange as the Private Data API (WebSocket) — obtain your JWT once, then reuse it across both interfaces.
- Login with username and password to obtain a session cookie
- Use the session cookie to obtain a JWT token
- Send the JWT token as a Bearer token in the
Authorizationheader of every private REST request
Authentication Flow
Step 1: Login with Username and Password
Using POST method, send your credentials to the login endpoint. Note that the credentials must be sent as form-data with keys in lowercase. This returns a SESSION cookie (not JSESSIONID).
// UAT Environment
POST https://auth-uat.opentrade.exchange/login
// PROD Environment
POST https://auth.opentrade.exchange/login
// Form Data (lowercase keys!)
username: your_username
password: your_password
SESSION cookie that you need for the next step.
Step 2: Obtain JWT Token
Use the SESSION cookie from Step 1 to obtain your JWT token. This is a POST with the client secret sent as a header, not a query parameter, and an empty body.
// UAT Environment
POST https://auth-uat.opentrade.exchange/auth/jwt/clients/{client-api-username}/token
// PROD Environment
POST https://auth.opentrade.exchange/auth/jwt/clients/{client-api-username}/token
// Headers
Cookie: SESSION={session_cookie_from_step_1}
clientSecret: {secret}
// Body: empty
/auth/jwt/clients/ (plural) — not /client/. And note this is a single /auth/, not the doubled /auth/auth/ some older references show.
Complete Authentication Flow with cURL
curl -s --cookie-jar cookies.txt -X POST \
"https://auth-uat.opentrade.exchange/login" \
-d "username=[USER_NAME]&password=[USER_PASSWORD]" \
--next -s -b cookies.txt -X POST \
"https://auth-uat.opentrade.exchange/auth/jwt/clients/[API_USER_NAME]/token" \
-H "accept: */*" \
-H "clientSecret: [API_SECRET]" \
-d ""
Bearer eyJ.... Use it as-is in the Authorization header — don't add a second "Bearer " prefix. The response also includes a jwt-expire-at header (token lifetime) and jwt-scope header.
Using Your Token
The token returned from the authentication flow already includes the Bearer prefix (the response body reads Bearer eyJ...). Use it exactly as returned in the Authorization header — do not prepend a second Bearer , or the header will read Bearer Bearer eyJ... and be rejected.
Include it on every private REST call, alongside the required X-API-Version header.
GET /hermes-ws-gateway/api/rest/trade-private/active-orders HTTP/1.1
Host: gateway-public-uat.opentrade.exchange
X-API-Version: 1.0.0
Authorization: Bearer eyJraWQiOiIwYWJmMGYwZS00YzliLTQ3NjItYjkxYS04NjE2YzkxMzJkMjkiLCJhbGciOiJSUzI1NiJ9...
Token Lifetime
The token response includes two headers you should read and store alongside the token itself:
| Header | Description |
|---|---|
| jwt-expire-at | ISO-8601 timestamp of when the token expires. Re-run the login + token exchange before this time to get a fresh token. |
| jwt-scope | Scope granted to this token, e.g. api.access. |
- Store your token securely and never expose it in client-side code
- Read
jwt-expire-atfrom the token response and refresh proactively before that time, rather than waiting for a 401 - Re-running the full login + token exchange is how you refresh — there is no separate refresh-token endpoint
- Use environment variables or a secrets manager to store credentials, never hardcode them in source control
REST equivalent of the WS ASSET_LIST channel. Returns the full list of assets supported across all connected exchanges.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
[
{
"class": "Currency",
"code": "BTC",
"name": "BTC"
}
]
REST equivalent of the WS INSTRUMENT_LIST channel. Returns all tradable instruments (pairs) and their quote currency.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
[
{
"class": "Instrument",
"quoteCurrencyCode": "BTC",
"code": "BTC/USD",
"name": "BTC/USD"
}
]
REST equivalent of a WS ORDER_BOOK_PUBLIC channel GET snapshot. Returns an L2 order book snapshot (bids/asks) for the requested instrument(s).
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| instruments | query | array<string> | Yes | Instrument codes to fetch, e.g. BTC/USD |
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
GET /hermes-ws-gateway/api/rest/public/order-book-public?instruments=BTC/USD HTTP/1.1
X-API-Version: 1.0.0
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
[
{
"class": "OrderBook",
"exchange": "OKEX",
"symbol": "BTC/USDT",
"bids": [
[63985.5, 0.50735545]
],
"asks": [
[63985.6, 1.08926571]
],
"eventTime": 1783442361532
}
]
[price, amount] pair, ordered best-price-first. eventTime is a Unix epoch timestamp in milliseconds. The response returns one entry per exchange with liquidity for the requested instrument — expect multiple entries per instrument (e.g. one each for OKEX, BITGET, HUOBI), not a single merged book.
REST equivalent of the WS TRADE_PRIVATE channel CREATE command. Accepts an array so multiple orders can be submitted in a single call.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| exchange | string | Optional | Name of exchange to send order to, such as BITFINEX, LMAX, OKX. If not provided, order will be set as SMART |
| globalInstrumentCd | string | Yes | Instrument code, e.g. BTC/USD |
| clientOrderId | string | Optional | Recommend unique Unix timestamp; server will assign one if omitted |
| direction | string | Yes | BUY or SELL |
| orderType | string | Yes | MARKET, LIMIT, POST_ONLY, BUY_STOP, SELL_STOP, STOP_LOSS, TAKE_PROFIT |
| timeInForce | string | Optional | GTC, GTD, GTT, FOK, IOC |
| price | number | Yes | Price required always |
| amount | number | Yes | Order quantity |
[
{
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USD",
"clientOrderId": "0989876565",
"direction": "SELL",
"orderType": "LIMIT",
"timeInForce": "GTC",
"price": 0.215,
"amount": 1.0
}
]
[
{
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USD",
"clientOrderId": "0989876565",
"direction": "SELL",
"orderType": "LIMIT",
"timeInForce": "GTC",
"price": 0.215,
"amount": 1.0,
"orderStatus": "NEW",
"exchangeOrderId": "1928374650",
"filledPrice": 0.0,
"filledAmount": 0.0,
"orderDateTime": "2026-07-07T13:04:43.792Z",
"message": "",
"processInstanceId": "string"
}
]
clientOrderId must be unique per order. Reusing an ID will be rejected.
REST equivalent of the WS TRADE_PRIVATE channel UPDATE command (order modification — e.g. price/amount changes on a resting order).
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
Uses the same request/response body shape as Create Orders, but requires an existing clientOrderId or exchangeOrderId to identify the order being modified.
[
{
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USD",
"clientOrderId": "0989876565",
"direction": "SELL",
"orderType": "LIMIT",
"timeInForce": "GTC",
"price": 0.22,
"amount": 1.0
}
]
REST equivalent of the WS TRADE_PRIVATE channel CANCEL command.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
Note that DELETE requests here carry a request body — identify the order(s) to cancel via clientOrderId, exchangeOrderId, and globalInstrumentCd.
- You must provide either
clientOrderIdorexchangeOrderId— at least one is required to identify the order. - If
clientOrderIdis provided, it is used (takes precedence overexchangeOrderId). - If only
exchangeOrderIdis provided, that order is cancelled. - If neither is provided, all orders for the selected pair(s) will be cancelled.
[
{
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USD",
"clientOrderId": "0989876565",
"exchangeOrderId": "1928374650"
}
]
[
{
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USD",
"clientOrderId": "0989876565",
"orderStatus": "CANCELLED",
"exchangeOrderId": "1928374650",
"orderDateTime": "2026-07-07T13:04:52.249Z",
"message": ""
}
]
REST equivalent of the WS TRADE_PRIVATE channel active orders GET. Returns all currently open (not filled/cancelled/rejected) orders.
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| instruments | query | array<string> | Optional | Filter to specific instruments; omit for all |
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
[
{
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USD",
"clientOrderId": "0989876565",
"direction": "SELL",
"orderType": "LIMIT",
"timeInForce": "GTC",
"price": 0.215,
"amount": 1.0,
"orderStatus": "ACTIVE",
"exchangeOrderId": "1928374650",
"filledPrice": 0.0,
"filledAmount": 0.0,
"orderDateTime": "2026-07-07T13:06:29.441Z",
"message": "",
"processInstanceId": "string"
}
]
REST equivalent of the WS TRADE_PRIVATE channel trades history GET. Returns executed trades (fills) within a date range.
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| instruments | query | array<string> | Optional | Filter to specific instruments |
| fromDtm | query | string ($date-time) | Optional | Range start (ISO-8601) |
| toDtm | query | string ($date-time) | Optional | Range end (ISO-8601) |
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
GET /hermes-ws-gateway/api/rest/trade-private/trades-history?instruments=BTC/USDT&fromDtm=2026-06-01T00:00:00&toDtm=2026-07-01T00:00:00 HTTP/1.1
X-API-Version: 1.0.0
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
[
{
"class": "Order",
"exchange": "OKEX",
"globalInstrumentCd": "BTC/USDT",
"clientOrderId": "11781606906612",
"direction": "BUY",
"orderType": "MARKET",
"timeInForce": "GTC",
"price": 66591.4,
"amount": 0.0002,
"orderStatus": "FILLED",
"exchangeOrderId": "3660939752535318528",
"filledPrice": 66558.0,
"filledAmount": 0.0002,
"orderDateTime": "2026-06-16T10:48:26.747Z",
"message": null,
"processInstanceId": null
}
]
clientOrderId, one per fill (e.g. PARTIALLY_FILLED followed by FILLED). Aggregate by clientOrderId if you need one row per order rather than per fill.
REST equivalent of the WS TRADE_PRIVATE channel orders history GET. Returns historical orders filtered by status and date range.
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| instruments | query | array<string> | Yes | Instrument codes to filter by |
| statuses | query | array<string> | Yes | See status values below |
| fromDtm | query | string ($date-time) | Optional | Range start (ISO-8601) |
| toDtm | query | string ($date-time) | Optional | Range end (ISO-8601) |
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
Available Status Values
NEW, SUBMITTED, PENDING, ACTIVE, IN_RECONCILIATION, PARTIALLY_FILLED, FILLED, CANCELLED, REJECTED, EXPIRED, FAILED, REJECTED_WRONG_ENV, DUPLICATE, UNKNOWN
REST equivalent of the WS CLIENT_PORTFOLIO channel GET snapshot. Returns current holdings by asset type, including exposure, PnL, and available balances.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
[
{
"class": "ClientPortfolio",
"assetType": "BTC",
"quantity": 0.0019553,
"wap": 90550.7416782,
"index": 88010.42919245128,
"onOrders": 0.0,
"available": 0.0019553,
"marketValue": 172.0867922,
"unrealizedPnl": -51.7776368,
"notional": 177.05386520338445
}
]
wap is the weighted average price (your cost basis) for the position; index is the current mark price used for valuation. unrealizedPnl reflects the difference between the two and can be negative. quantity and available can be negative for a short position.
Historical counterpart to Client Portfolio — returns portfolio snapshots over a date range instead of the live snapshot.
REST equivalent of the WS BALANCE channel. Returns account balances by currency.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
[
{
"class": "Balance",
"currencyCode": "BTC",
"balance": 0.0019553,
"available": 0.0019553,
"locked": 0.0
}
]
balance is total holdings for that currency; available is free/withdrawable; locked is held against open orders (balance = available + locked).
REST equivalent of the WS CLIENT_BALANCE_DISTRIBUTION channel GET. Returns where your tokens actually sit: one row per asset per venue, with cost basis, valuation and PnL for that venue.
/balance and /client-portfolio both report the aggregate across every venue, but an order is routed to exactly one exchange and is checked against that venue's balance alone. Read this endpoint to decide where an order can actually be filled, and how much can be withdrawn or transferred off a given venue.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
There are no query parameters. The client is taken from the token, so there is no way to request another account's distribution.
[
{
"class": "ClientBalanceDistribution",
"clientId": 1000123,
"asset": "BTC",
"exchange": "OKEX",
"finalBalance": 0.35,
"costBasisUsd": 30642.7595,
"totalValueUsd": 30803.6502,
"inventoryValueUsd": 30642.7595,
"wap": 87550.7414,
"lockedAmount": 0.05,
"availableAmount": 0.3,
"unrealizedPnl": 160.8907,
"returnPercent": 0.525
},
{
"class": "ClientBalanceDistribution",
"clientId": 1000123,
"asset": "BTC",
"exchange": "BITGET",
"finalBalance": 0.12,
"costBasisUsd": 10866.089,
"totalValueUsd": 10561.2515,
"inventoryValueUsd": 10866.089,
"wap": 90550.7417,
"lockedAmount": 0.0,
"availableAmount": 0.12,
"unrealizedPnl": -304.8375,
"returnPercent": -2.8054
}
]
Response Fields
| Field | Type | Description |
|---|---|---|
| clientId | number | Your Open Trade client identifier, taken from the token. |
| asset | string | Asset code, e.g. BTC, USDT, GALA. |
| exchange | string | Venue holding the asset: OKEX, HUOBI, BITGET, BITMART, BINANCE, DERIBIT, LMAX, GEMINI, BLOCKCHAIN, OPENTRADE. |
| finalBalance | number | Total amount of the asset held on that venue. |
| availableAmount | number | Amount free to trade, withdraw or transfer from that venue. |
| lockedAmount | number | Amount reserved on that venue, typically against open orders or a pending transfer. |
| wap | number | Weighted average price paid for the holding on that venue, in USD. |
| costBasisUsd | number | USD cost basis of the holding on that venue. |
| inventoryValueUsd | number | USD value of the inventory carried for the position on that venue. |
| totalValueUsd | number | Current USD market value of the holding on that venue. |
| unrealizedPnl | number | Unrealized PnL on the holding, in USD. Negative when the position is under water. |
| returnPercent | number | Return on the holding, in percent. |
An asset held on three exchanges comes back as three rows. Sum finalBalance over the rows sharing an asset to reconcile against /balance, and never assume a single row carries the whole position.
CLIENT_BALANCE_DISTRIBUTION channel returns, carrying the same "class" discriminator. Only the envelope differs: the WS message wraps them in a data array, while REST returns the array on its own.
REST equivalent of the WS DEPOSIT_WALLET channel. Returns the client's deposit wallet addresses, one per supported asset.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
[
{
"class": "DepositWallet",
"id": 1000003606,
"clientId": 100882,
"symbol": "XRP",
"walletAddress": "rnSffMjADGXG9apHR6gjKz8THc1FtZGCov",
"status": "ACTIVE",
"comment": "tag: 1000003606",
"exchange": "OPENTRADE"
},
{
"class": "DepositWallet",
"id": 1000003615,
"clientId": 100882,
"symbol": "AAVE",
"walletAddress": "0x649590c78f702ed0cdeab07daf722673d2510afe",
"status": "ACTIVE",
"comment": null,
"exchange": "OPENTRADE"
}
]
comment carries the destination tag/memo when the asset requires one (e.g. XRP); otherwise null.
REST equivalent of the WS DEPOSIT_WORKFLOW channel GET. Tracks the lifecycle of incoming on-chain deposits as they are detected, confirmed, and credited to your account.
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| category | query | string | Yes | ACTIVE_PROCESSES or COMPLETED_PROCESSES |
| removeFailed | query | boolean | Optional | Excludes failed/errored processes when true. Applies to COMPLETED_PROCESSES only |
| date-from | query | string ($date) | Optional | Range start (YYYY-MM-DD). Applies to COMPLETED_PROCESSES only |
| date-to | query | string ($date) | Optional | Range end (YYYY-MM-DD). Applies to COMPLETED_PROCESSES only |
| page | query | integer | Optional | Zero-indexed page number. Applies to COMPLETED_PROCESSES only |
| pageSize | query | integer | Optional | Results per page. Applies to COMPLETED_PROCESSES only |
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
GET /hermes-ws-gateway/api/rest/deposit-workflow?category=COMPLETED_PROCESSES&removeFailed=true&date-from=2026-01-01&date-to=2026-07-14&page=0&pageSize=50 HTTP/1.1
X-API-Version: 1.0.0
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
[
{
"class": "DepositWorkflow",
"walletAddress": "0x649590c78f702ed0cdeab07daf722673d2510afe",
"cryptoAssetCode": "USDT",
"transferAmount": 20.0002,
"feeAmount": 0.00001613542206867,
"feeAssetCode": "ETH",
"walletTransferId": "a31a5f77-1826-4e20-a416-ba282c4fd864",
"tag": null,
"processInstanceId": "96ece4ff-463e-11f1-af10-22add62dcf14",
"state": "Update Transfer Status - Complete",
"message": null,
"startTime": "2026-05-02T15:50:05.922Z",
"endTime": "2026-05-02T15:53:27.104Z",
"suspended": false,
"tokenPriceUsd": 0.9997792134,
"errorMessage": null
},
{
"class": "DepositWorkflow",
"walletAddress": "0x649590c78f702ed0cdeab07daf722673d2510afe",
"cryptoAssetCode": "ETH",
"transferAmount": 0.000811907277365572,
"feeAmount": null,
"feeAssetCode": null,
"walletTransferId": null,
"tag": null,
"processInstanceId": "b6a8edc5-44f0-11f1-bce8-7a2b3ca44423",
"state": "Check Deposit Amount",
"message": null,
"startTime": "2026-05-01T00:00:07.255Z",
"endTime": "2026-05-01T00:00:08.580Z",
"suspended": false,
"tokenPriceUsd": 2255.9838392777,
"errorMessage": null
}
]
state reflects the current step in the deposit pipeline; a state ending in Complete indicates the deposit has been credited. feeAmount, feeAssetCode, and walletTransferId populate once the deposit has been processed on-chain.
REST equivalent of the WS TRANSFER_WORKFLOW channel CREATE command. Initiates a transfer either between two connected exchanges/venues, or from an exchange out to an external blockchain wallet address.
Headers
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| fromExchange | string | Yes | Source venue code, e.g. OPENTRADE, OKEX |
| toExchange | string | Yes | Destination venue code, or BLOCKCHAIN to send to an external wallet |
| walletToAddress | string | Optional | Required only when toExchange is BLOCKCHAIN |
| cryptoAssetCode | string | Yes | Asset to transfer, e.g. USDT |
| transferAmount | number | Yes | Amount to transfer |
Exchange to Exchange
{
"fromExchange": "OPENTRADE",
"toExchange": "BITMART",
"cryptoAssetCode": "USDT",
"transferAmount": 4
}
Exchange to Blockchain Wallet (Withdrawal)
This is the same POST /hermes-ws-gateway/api/rest/transfer-workflow endpoint used above — a withdrawal is simply a transfer where toExchange is set to BLOCKCHAIN and walletToAddress is the external destination address.
{
"fromExchange": "OKEX",
"toExchange": "BLOCKCHAIN",
"walletToAddress": "0x1c93969dce56d7eeeb00679dcfe89d7e0f719979",
"cryptoAssetCode": "USDT",
"transferAmount": 15
}
walletToAddress and cryptoAssetCode before submitting.
category=ACTIVE_PROCESSES (in flight) or category=COMPLETED_PROCESSES (finished) to follow the withdrawal's progress. The response's txId is populated once the withdrawal is broadcast on-chain.
REST equivalent of the WS TRANSFER_WORKFLOW channel GET. Tracks the lifecycle of transfers created via Create Transfer, whether between exchanges or out to a blockchain wallet.
Query Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| category | query | string | Yes | ACTIVE_PROCESSES or COMPLETED_PROCESSES |
| removeFailed | query | boolean | Optional | Excludes failed/errored processes when true. Applies to COMPLETED_PROCESSES only |
| date-from | query | string ($date) | Optional | Range start (YYYY-MM-DD). Applies to COMPLETED_PROCESSES only |
| date-to | query | string ($date) | Optional | Range end (YYYY-MM-DD). Applies to COMPLETED_PROCESSES only |
| page | query | integer | Optional | Zero-indexed page number. Applies to COMPLETED_PROCESSES only |
| pageSize | query | integer | Optional | Results per page. Applies to COMPLETED_PROCESSES only |
| transferSubType | query | string | Optional | ALL, or a more specific subtype to narrow results. Applies to COMPLETED_PROCESSES only |
| Authorization | header | string | Yes | Bearer JWT token |
| X-API-Version | header | string | Optional | Default: 1.0.0 |
GET /hermes-ws-gateway/api/rest/transfer-workflow?category=COMPLETED_PROCESSES&removeFailed=true&date-from=2026-07-01&date-to=2026-07-14&page=0&pageSize=500&transferSubType=ALL HTTP/1.1
X-API-Version: 1.0.0
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
[
{
"class": "TransferWorkflow",
"fromExchange": "OPENTRADE",
"toExchange": "OKEX",
"cryptoAssetCode": "USDT",
"transferAmount": 5,
"walletTransferId": "ffa280b4-3c95-4741-bb25-d154193b6510",
"tag": null,
"processInstanceId": "b0d4b1a1-78ec-11f1-86a3-b6505867aca1",
"state": "Completed",
"message": null,
"startTime": "2026-07-06T03:42:19.954Z",
"endTime": "2026-07-15T18:36:19.707Z",
"suspended": false,
"walletFromAddress": "0x375b9d792d38105bee4b87f72941a6af071d9218",
"feeAmount": 0.00001031880686044,
"feeAssetCode": "ETH",
"txId": "0x205cce2e2077c709a2c9f2b8fffe8861b30c2421bce308bdc87e662d8f90edfb",
"exchangeTxId": null,
"exchangeTransferId": null,
"errorMessage": null,
"tasks": null
},
{
"class": "TransferWorkflow",
"fromExchange": "OKEX",
"toExchange": "OPENTRADE",
"cryptoAssetCode": "USDT",
"transferAmount": 5,
"walletTransferId": "916e31ee-700b-4e60-b6c2-9d14ad651fe9",
"tag": null,
"processInstanceId": "fe8858c3-78dd-11f1-86a3-b6505867aca1",
"state": "Completed",
"message": null,
"startTime": "2026-07-06T01:57:07.865Z",
"endTime": "2026-07-06T01:59:28.529Z",
"suspended": false,
"walletFromAddress": "OKEX",
"feeAmount": 0.097,
"feeAssetCode": "USDT",
"txId": null,
"exchangeTxId": "413425468",
"exchangeTransferId": "413425468",
"errorMessage": null,
"tasks": null
}
]
walletFromAddress holds the source wallet address for on-chain transfers, or the source exchange name for exchange-internal transfers. txId is populated only for blockchain transfers; exchangeTxId/exchangeTransferId only for exchange-to-exchange transfers.