REST API · Trading automation
Build trading tools, automate workflows, and connect your systems with the ionloop.trade REST API.
https://api.ionloop.trade/v1/markets
GET https://api.ionloop.trade/v1/markets Authorization: Bearer YOUR_API_KEY
The ionloop.trade REST API exposes versioned resources for market data, trading, portfolio, wallets, transactions, webhooks, and system status. Every response uses the same JSON envelope so bots, dashboards, and back-office tools share one integration pattern.
{
"success": true,
"data": {},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
Go from signup to your first automated trade flow in six steps.
Register at ionloop.trade and complete identity checks required for trading APIs.
Open Developer Settings, create a key, and assign scopes (markets, orders, portfolio, webhooks).
Send Authorization: Bearer YOUR_API_KEY on every HTTPS call.
Call GET /v1/markets and /v1/markets/:symbol/ticker to validate connectivity.
Submit a small limit order on a sandbox or low-risk pair; verify status via GET /v1/orders/:id.
Register POST /v1/webhooks and verify HMAC signatures on delivery.
Authenticate with a bearer token issued from the ionloop.trade developer console.
Keys are scoped; trading endpoints require explicit orders:write (and related) grants.
curl https://api.ionloop.trade/v1/markets \ -H 'Authorization: Bearer YOUR_API_KEY'
const res = await fetch('https://api.ionloop.trade/v1/markets', {
headers: {
Authorization: 'Bearer YOUR_API_KEY',
Accept: 'application/json'
}
});
const axios = require('axios');
const client = axios.create({
baseURL: 'https://api.ionloop.trade',
headers: { Authorization: 'Bearer YOUR_API_KEY' }
});
const { data } = await client.get('/v1/markets');
import requests
r = requests.get(
'https://api.ionloop.trade/v1/markets',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
timeout=10,
)
print(r.json())
Surface areas map to REST resources on https://api.ionloop.trade.
Use “Open reference” to jump to concrete endpoint contracts.
API keys, scopes, rotation, and session-backed issuance from the console.
Ledger history including trades, deposits, withdrawals, and fees.
Profile, preferences, and session helpers tied to your ionloop.trade account.
Contracts below reflect API version v1. Paths are relative to https://api.ionloop.trade.
List markets — List available trading markets.
Required permissions: None (public). Optional API key for elevated rate limits.
| Name | Type | Required | Description |
|---|---|---|---|
quote |
string | Optional | Filter by quote asset (e.g. USDT). |
{
"success": true,
"data": {
"items": [
{
"symbol": "BTC-USDT",
"status": "online",
"baseAsset": "BTC",
"quoteAsset": "USDT"
}
]
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
429 RATE_LIMITED — Soft throttle without key
Responses are cache-friendly; use single-market endpoints for low-latency trading.
Market details — Get details for a single market.
Required permissions: markets:read
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string | Required | Market pair, e.g. BTC-USDT. |
{
"success": true,
"data": {
"symbol": "BTC-USDT",
"status": "online",
"tickSize": "0.01",
"stepSize": "0.000001",
"minNotional": "10"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
404 NOT_FOUND — Unknown symbol · 403 FORBIDDEN
Symbol must match active listing; retired markets return NOT_FOUND.
Ticker — Get latest price and 24h market statistics.
Required permissions: markets:read
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string | Required | Market pair. |
{
"success": true,
"data": {
"symbol": "BTC-USDT",
"lastPrice": "65102.45",
"bid": "65100.10",
"ask": "65103.80",
"volume24h": "18293.441",
"high24h": "65880.00",
"low24h": "64110.00"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
404 NOT_FOUND · 503 MARKET_CLOSED
Polling faster than 1s may hit throttle; prefer websocket feeds for HFT-style workloads.
Order book — Get current order book depth.
Required permissions: markets:read
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string | Required | Market pair. |
depth |
integer | Optional | Levels per side (default 50, max 500). |
{
"success": true,
"data": {
"symbol": "BTC-USDT",
"bids": [["65100.10", "0.542"]],
"asks": [["65103.80", "0.318"]],
"sequence": 92881102
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
404 NOT_FOUND · 429 RATE_LIMITED
Sequence numbers increase monotonically; drop clients if gap detected.
Create order — Create a new order.
Required permissions: orders:write
| Name | Type | Required | Description |
|---|---|---|---|
| No query parameters. | |||
{
"symbol": "BTC-USDT",
"side": "buy",
"type": "limit",
"quantity": "0.01",
"price": "65000.00",
"timeInForce": "GTC"
}
{
"success": true,
"data": {
"id": "ord_9x82k1",
"symbol": "BTC-USDT",
"side": "buy",
"type": "limit",
"status": "open",
"quantity": "0.01",
"filledQuantity": "0",
"price": "65000.00",
"createdAt": "2026-05-14T12:00:00Z"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
422 VALIDATION_ERROR · 402 INSUFFICIENT_BALANCE · 409 ORDER_REJECTED · 503 MARKET_CLOSED
Send Idempotency-Key to prevent duplicate submissions on retries.
List orders — List user orders.
Required permissions: orders:read
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string | Optional | Filter by market. |
status |
string | Optional | open | filled | cancelled · comma-separated. |
page |
integer | Optional | Page index. |
{
"success": true,
"data": {
"items": [
{
"id": "ord_9x82k1",
"symbol": "BTC-USDT",
"side": "buy",
"status": "open",
"quantity": "0.01",
"filledQuantity": "0"
}
],
"page": 1,
"pageSize": 50
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
401 UNAUTHORIZED · 403 FORBIDDEN
Only returns orders for the authenticated account.
Get order — Get one order by ID.
Required permissions: orders:read
| Name | Type | Required | Description |
|---|---|---|---|
id |
string | Required | Order identifier. |
{
"success": true,
"data": {
"id": "ord_9x82k1",
"symbol": "BTC-USDT",
"side": "buy",
"type": "limit",
"status": "open",
"quantity": "0.01",
"filledQuantity": "0",
"price": "65000.00",
"createdAt": "2026-05-14T12:00:00Z"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
404 NOT_FOUND
Historical fills appear under transactions once completed.
Cancel order — Cancel an open order.
Required permissions: orders:write
| Name | Type | Required | Description |
|---|---|---|---|
id |
string | Required | Order identifier. |
{
"success": true,
"data": {
"id": "ord_9x82k1",
"status": "cancelled",
"cancelledAt": "2026-05-14T12:01:05Z"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
404 NOT_FOUND · 409 ORDER_REJECTED — Already terminal state
Webhook order.cancelled emits after matching engine acknowledges.
Portfolio — Get account portfolio balances.
Required permissions: portfolio:read
| Name | Type | Required | Description |
|---|---|---|---|
| No query parameters. | |||
{
"success": true,
"data": {
"balances": [
{ "asset": "USDT", "available": "12540.22", "locked": "250.00" },
{ "asset": "BTC", "available": "0.845", "locked": "0.010" }
]
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
401 UNAUTHORIZED
Locked amounts include working orders and pending withdrawals.
Wallets — List wallet balances.
Required permissions: wallet:read
| Name | Type | Required | Description |
|---|---|---|---|
type |
string | Optional | spot | funding |
{
"success": true,
"data": {
"wallets": [
{
"id": "wal_main",
"type": "spot",
"balances": [
{ "asset": "USDT", "available": "12540.22", "locked": "250.00" }
]
}
]
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
403 FORBIDDEN
Use with transactions for reconciliation across chains and internal rails.
Transactions — List account transactions.
Required permissions: transactions:read
| Name | Type | Required | Description |
|---|---|---|---|
type |
string | Optional | trade | deposit | withdrawal | fee |
from |
datetime | Optional | ISO8601 start. |
to |
datetime | Optional | ISO8601 end. |
{
"success": true,
"data": {
"items": [
{
"id": "txn_77aa",
"type": "trade",
"symbol": "BTC-USDT",
"quantity": "0.01",
"fee": "0.65",
"createdAt": "2026-05-14T11:58:00Z"
}
],
"page": 1,
"pageSize": 100
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
400 VALIDATION_ERROR — Invalid window
Exports for tax reporting available via dashboard CSV.
Create webhook — Create a webhook endpoint.
Required permissions: webhooks:write
| Name | Type | Required | Description |
|---|---|---|---|
| No query parameters. | |||
{
"url": "https://hooks.yourapp.com/ionloop",
"events": ["order.filled", "trade.executed"],
"secret": "whsec_generate_in_console"
}
{
"success": true,
"data": {
"id": "wh_44291",
"url": "https://hooks.yourapp.com/ionloop",
"status": "active"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
422 VALIDATION_ERROR — Invalid URL or event list
HTTPS required; secret used for HMAC signature verification.
System status — Get API and trading system status.
Required permissions: None (public).
| Name | Type | Required | Description |
|---|---|---|---|
| No query parameters. | |||
{
"success": true,
"data": {
"api": "operational",
"matchingEngine": "operational",
"withdrawals": "degraded",
"incidents": []
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
503 INTERNAL_ERROR — Rare aggregation failure
Poll at most once every 15s; subscribe to status page for human updates.
Integration snippets you can paste into scripts or services.
const r = await fetch('https://api.ionloop.trade/v1/markets', {
headers: { Authorization: 'Bearer YOUR_API_KEY', Accept: 'application/json' }
});
const body = await r.json();
console.log(body.data.items.map((m) => m.symbol));
const axios = require('axios');
const { data } = await axios.get(
'https://api.ionloop.trade/v1/markets/BTC-USDT/ticker',
{ headers: { Authorization: 'Bearer YOUR_API_KEY' } }
);
console.log(data.data.lastPrice);
import requests
payload = {
"symbol": "BTC-USDT",
"side": "buy",
"type": "limit",
"quantity": "0.01",
"price": "65000.00",
"timeInForce": "GTC",
}
r = requests.post(
"https://api.ionloop.trade/v1/orders",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json=payload,
timeout=15,
)
print(r.json())
curl -s -X DELETE "https://api.ionloop.trade/v1/orders/ord_9x82k1" \ -H "Authorization: Bearer YOUR_API_KEY"
import requests
r = requests.get(
"https://api.ionloop.trade/v1/portfolio",
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=10,
)
for row in r.json()["data"]["balances"]:
print(row["asset"], row["available"], row["locked"])
ionloop.trade delivers trading lifecycle events to your HTTPS endpoints.
Each request includes X-Ionloop-Signature (HMAC-SHA256 of the raw body with your webhook secret)
and X-Ionloop-Event-Id for idempotent processing.
order.created · order.updated · order.filled · order.cancelledtrade.executedwallet.deposit.created · wallet.withdrawal.createdtransaction.completedprice.alert.triggeredaccount.updatedTransient failures retry with exponential backoff for up to 24 hours. Respond with 2xx within 10 seconds to acknowledge.
The developer console stores delivery logs: timestamps, HTTP status, latency, and truncated response bodies for debugging.
{
"id": "evt_k92qa",
"type": "order.filled",
"version": "2026-05-01",
"createdAt": "2026-05-14T12:00:02Z",
"data": {
"orderId": "ord_9x82k1",
"symbol": "BTC-USDT",
"filledQuantity": "0.01",
"averagePrice": "65012.40"
}
}
Verify HMAC before trusting payloads; rotate secrets per environment. Allow-list ionloop egress IPs where your infrastructure supports it.
Failures use the same envelope as successes so observability stacks can join on requestId.
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid API token"
},
"meta": {
"requestId": "req_123456",
"timestamp": "2026-05-14T12:00:00Z"
}
}
| Code | HTTP | When |
|---|---|---|
UNAUTHORIZED | 401 | Missing, malformed, or expired API key. |
FORBIDDEN | 403 | Authenticated but lacking scopes or account state blocks trading. |
VALIDATION_ERROR | 422 | Schema or field validation failed. |
RATE_LIMITED | 429 | Quota exceeded — honour Retry-After. |
NOT_FOUND | 404 | Unknown order, market, or resource id. |
ORDER_REJECTED | 409 | Matching engine rejected the instruction (size, price band, self-trade). |
INSUFFICIENT_BALANCE | 402 | Not enough available balance for order or withdrawal. |
MARKET_CLOSED | 503 | Market halted or in post-only maintenance. |
INTERNAL_ERROR | 500 | Unexpected server fault — retry with backoff. |
Production targets high availability; subscribe to the public status channel for incident timelines.
Authenticated traffic defaults to 1200 requests / minute per API key with burst control on order routes.
429 responses include RATE_LIMITED and Retry-After.
List endpoints accept page and pageSize (max 100).
Results are stable within a page token window; use time filters for audit pulls.
All routes documented here live under /v1/.
Breaking changes ship only in new major versions with a published migration window.
Use https://api-sandbox.ionloop.trade with sandbox keys for integration tests —
ledger balances are isolated from production.
Developer support covers REST onboarding, webhook debugging, and quota adjustments.
2026-05 · base URL https://api.ionloop.trade