Skip to content

Get Trades List

POST https://trade-uk.sandbox.zodiamarkets.com/api/3/trades

Retrieve a list of executed trades with optional filtering. Returns a single record for each trade, whilst the transaction endpoint returns a separate record for each leg of the trade.


Trades progress through various states from execution to settlement:

State Description
PENDING_SETTLEMENT Trade executed, awaiting settlement
PROCESSED Trade fully settled
CANCELLED Trade cancelled or rejected before settlement

Class Description
OTC Over-the-counter trades executed via Zodia Markets trading desk
RFS Request for Stream trades executed via e-Trader or WebSocket API

Key Difference:

  • RFS trades include a quoteId field (from the WebSocket price stream)
  • OTC trades have no quoteId

Use max (1-200) and offset parameters to paginate through large result sets.

def get_all_trades(filters=None):
"""Retrieve all trades matching filters"""
all_trades = []
offset = 0
max_per_page = 200
if filters is None:
filters = {}
while True:
body = {
**filters,
'max': max_per_page,
'offset': offset
}
response = make_api_request('POST', 'api/3/trades', body)
trades = response['data']
all_trades.extend(trades)
# Stop if we got fewer results than requested
if len(trades) < max_per_page:
break
offset += max_per_page
return all_trades

import json
import hmac
import hashlib
import time
import requests
from datetime import datetime, timedelta
# Configuration
api_key = "your_api_key"
api_secret = "your_api_secret"
base_url = "https://trade-uk.sandbox.zodiamarkets.com"
# Request body - Get trades from last 7 days
today = datetime.utcnow()
week_ago = today - timedelta(days=7)
# Every signed request must carry a nonce or tonce
tonce = str(int(time.time() * 1000000))
body = {
"tonce": tonce,
"from": week_ago.strftime("%Y-%m-%dT%H:%M:%SZ"),
"to": today.strftime("%Y-%m-%dT%H:%M:%SZ"),
"tradeState": "PENDING_SETTLEMENT",
"max": 50,
"offset": 0
}
body_json = json.dumps(body)
# Generate signature
path = "api/3/trades"
message = f"{path}\0{body_json}"
signature = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha512
).hexdigest()
# Make request
headers = {
"Rest-Key": api_key,
"Rest-Sign": signature,
"Content-Type": "application/json"
}
response = requests.post(
f"{base_url}/{path}",
headers=headers,
data=body_json
)
# Process response
if response.status_code == 200:
data = response.json()
print(f"Found {data['total']} trades")
for trade in data['data']:
print(f"\nTrade: {trade['tradeRef']}")
print(f" Client Ref: {trade['clientRef']}")
print(f" Class: {trade['tradeClass']}")
print(f" Side: {trade['tradeSide']}")
print(f" State: {trade['tradeState']}")
print(f" Traded: {trade['tradedAmount']['amount']} {trade['tradedAmount']['currency']}")
print(f" Settlement: {trade['settlementAmount']['amount']} {trade['settlementAmount']['currency']}")
print(f" Price: {trade['executedPrice']}")
print(f" Settlement Date: {trade['settlementDate']}")
if trade.get('quoteId'):
print(f" Quote ID: {trade['quoteId'][:50]}...")
if trade['beneficiary']:
print(f" Third-party: {trade['beneficiary']['name']}")
else:
print(f"Error: {response.status_code}")
print(response.text)
const crypto = require('crypto');
const axios = require('axios');
// Configuration
const apiKey = 'your_api_key';
const apiSecret = 'your_api_secret';
const baseUrl = 'https://trade-uk.sandbox.zodiamarkets.com';
// Request body - Get trades from last 7 days
const today = new Date();
const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
// Every signed request must carry a nonce or tonce
const tonce = Date.now() * 1000;
const body = {
tonce,
from: weekAgo.toISOString(),
to: today.toISOString(),
tradeState: 'PENDING_SETTLEMENT',
max: 50,
offset: 0
};
const bodyJson = JSON.stringify(body);
// Generate signature
const path = 'api/3/trades';
const message = `${path}\0${bodyJson}`;
const signature = crypto
.createHmac('sha512', apiSecret)
.update(message)
.digest('hex');
// Make request
const headers = {
'Rest-Key': apiKey,
'Rest-Sign': signature,
'Content-Type': 'application/json'
};
axios.post(`${baseUrl}/${path}`, body, { headers })
.then(response => {
console.log(`Found ${response.data.total} trades`);
response.data.data.forEach(trade => {
console.log(`\nTrade: ${trade.tradeRef}`);
console.log(` Client Ref: ${trade.clientRef}`);
console.log(` Class: ${trade.tradeClass}`);
console.log(` Side: ${trade.tradeSide}`);
console.log(` State: ${trade.tradeState}`);
console.log(` Traded: ${trade.tradedAmount.amount} ${trade.tradedAmount.currency}`);
console.log(` Settlement: ${trade.settlementAmount.amount} ${trade.settlementAmount.currency}`);
console.log(` Price: ${trade.executedPrice}`);
console.log(` Settlement Date: ${trade.settlementDate}`);
if (trade.quoteId) {
console.log(` Quote ID: ${trade.quoteId.substring(0, 50)}...`);
}
if (trade.beneficiary) {
console.log(` Third-party: ${trade.beneficiary.name}`);
}
});
})
.catch(error => {
console.error('Error:', error.response?.status);
console.error(error.response?.data);
});
Terminal window
curl -X POST https://trade-uk.sandbox.zodiamarkets.com/api/3/trades \
-H "Rest-Key: your_api_key" \
-H "Rest-Sign: your_hmac_signature" \
-H "Content-Type: application/json" \
-d '{
"tonce": 1770888183656000,
"from": "2026-04-01T00:00:00Z",
"to": "2026-04-30T23:59:59Z",
"tradeState": "PENDING_SETTLEMENT",
"max": 50,
"offset": 0
}'

from datetime import datetime, timedelta
def get_recent_trades(days=7):
"""Get trades from the last N days"""
today = datetime.utcnow()
start_date = today - timedelta(days=days)
body = {
'from': start_date.strftime('%Y-%m-%dT%H:%M:%SZ'),
'to': today.strftime('%Y-%m-%dT%H:%M:%SZ')
}
response = make_api_request('POST', 'api/3/trades', body)
return response['data']
trades = get_recent_trades(7)
print(f"Found {len(trades)} trades in the last 7 days")
def get_pending_settlements():
"""Get all trades pending settlement"""
body = {
'tradeState': 'PENDING_SETTLEMENT'
}
response = make_api_request('POST', 'api/3/trades', body)
return response['data']
pending = get_pending_settlements()
for trade in pending:
print(f"{trade['tradeRef']}: {trade['settlementDate']}")
def get_trades_by_account_group(account_group_uuid):
"""Get trades for specific account group"""
body = {
'accountGroupUuid': account_group_uuid
}
response = make_api_request('POST', 'api/3/trades', body)
return response['data']
trades = get_trades_by_account_group('2073252c-81ed-41be-bf4d-d51b8f2246b8')
def find_trade_by_ref(trade_ref):
"""Find specific trade by trade reference"""
body = {
'tradeRef': trade_ref
}
response = make_api_request('POST', 'api/3/trades', body)
if response['data']:
return response['data'][0]
return None
trade = find_trade_by_ref('f4a964ad27074a9780b5010b3514d2e0')
if trade:
print(f"Found trade: {trade['tradeState']}")
def find_trade_by_client_ref(client_ref):
"""Find trade by your custom client reference"""
body = {
'clientRef': client_ref
}
response = make_api_request('POST', 'api/3/trades', body)
if response['data']:
return response['data'][0]
return None
trade = find_trade_by_client_ref('8305ec3c-83a3-490c-aab5-4748d7436ad8')
if trade:
print(f"Found trade: {trade['tradeRef']}")
def get_rfs_trades():
"""Get all RFS trades (includes quote IDs)"""
body = {
'tradeClass': 'RFS'
}
response = make_api_request('POST', 'api/3/trades', body)
return response['data']
rfs_trades = get_rfs_trades()
for trade in rfs_trades:
print(f"Trade: {trade['tradeRef']}")
if trade.get('quoteId'):
print(f" Quote ID: {trade['quoteId'][:50]}...")
def get_third_party_trades():
"""Get all trades with third-party settlement"""
response = make_api_request('POST', 'api/3/trades', {})
third_party = [
t for t in response['data']
if t['beneficiary'] is not None
]
return third_party
trades = get_third_party_trades()
for trade in trades:
print(f"{trade['tradeRef']}: {trade['beneficiary']['name']}")
from collections import defaultdict
def calculate_volume_by_currency():
"""Calculate total traded volume by currency"""
response = make_api_request('POST', 'api/3/trades', {})
volume = defaultdict(float)
for trade in response['data']:
currency = trade['tradedAmount']['currency']
amount = trade['tradedAmount']['amount']
volume[currency] += amount
return dict(volume)
volumes = calculate_volume_by_currency()
for currency, total in volumes.items():
print(f"{currency}: {total:,.2f}")
def get_trades_for_date(date_str):
"""Get all trades for a specific date (YYYY-MM-DD)"""
from_time = f"{date_str}T00:00:00Z"
to_time = f"{date_str}T23:59:59Z"
body = {
'from': from_time,
'to': to_time
}
response = make_api_request('POST', 'api/3/trades', body)
return response['data']
trades = get_trades_for_date('2026-04-20')
print(f"Trades on 2026-04-20: {len(trades)}")
def reconcile_trades(client_refs):
"""Check which client references have completed trades"""
completed = []
missing = []
for client_ref in client_refs:
body = {'clientRef': client_ref}
response = make_api_request('POST', 'api/3/trades', body)
if response['data']:
trade = response['data'][0]
completed.append({
'clientRef': client_ref,
'tradeRef': trade['tradeRef'],
'tradeState': trade['tradeState']
})
else:
missing.append(client_ref)
return completed, missing
# Usage
my_refs = [
'8305ec3c-83a3-490c-aab5-4748d7436ad8',
'other-client-ref-123'
]
completed, missing = reconcile_trades(my_refs)
print(f"Completed: {len(completed)}")
print(f"Missing: {len(missing)}")

Use ISO 8601 format for from and to parameters:

Format: YYYY-MM-DDTHH:MM:SSZ

Examples:

  • 2026-04-20T00:00:00Z - Start of day (UTC)
  • 2026-04-20T23:59:59Z - End of day (UTC)
  • 2026-04-20T10:25:35Z - Specific time (UTC)

Today’s trades:

{
"from": "2026-04-20T00:00:00Z",
"to": "2026-04-20T23:59:59Z"
}

Last 30 days:

{
"from": "2026-03-21T00:00:00Z",
"to": "2026-04-20T23:59:59Z"
}

Specific month:

{
"from": "2026-04-01T00:00:00Z",
"to": "2026-04-30T23:59:59Z"
}

# Good - Paginated request
def get_all_trades_paginated():
all_trades = []
offset = 0
while True:
response = make_api_request('POST', 'api/3/trades', {
'max': 200,
'offset': offset
})
trades = response['data']
all_trades.extend(trades)
if len(trades) < 200:
break
offset += 200
return all_trades
# Bad - Requesting without pagination
response = make_api_request('POST', 'api/3/trades', {})
# May timeout or return incomplete data
# Good - Filter with API parameters
response = make_api_request('POST', 'api/3/trades', {
'tradeState': 'PENDING_SETTLEMENT',
'tradeClass': 'RFS'
})
# Bad - Fetch all and filter locally
all_trades = make_api_request('POST', 'api/3/trades', {})
filtered = [t for t in all_trades['data'] if t['tradeState'] == 'PENDING_SETTLEMENT']
# Wastes bandwidth and time
# Good - Specific date range
body = {
'from': '2026-04-01T00:00:00Z',
'to': '2026-04-30T23:59:59Z'
}
# Bad - Fetching all trades without date filter
body = {} # Returns all trades ever - slow!
# Good - Provide client reference when executing orders
order = {
'messageType': 'order',
'quoteId': quote_id,
'tradeSide': 'BUY',
'clientRequestId': 'ORDER-123', # This becomes clientRef
...
}
# Later, easily retrieve your trade
trade = find_trade_by_client_ref('ORDER-123')

Domain: Trading

POST https://trade-uk.sandbox.zodiamarkets.com/api/3/trades
Header Required Description
Rest-Key API key for authentication
Rest-Sign Calculated API Signature
Field Type Required Description
tonce integer (int64) yes The current Unix time in microseconds.
nonce integer (int64) Alternative to tonce. Every request must carry either nonce or tonce, and the value must parse as a whole number; a request with neither is rejected with INVALID_NONCE_OR_TONCE.
tradeRef string Filter by Zodia Markets trade reference
clientRef string Filter by your custom client reference
tradeState string (enum) Filter by trade state — One of: CANCELLED, PROCESSED, PENDING_SETTLEMENT
tradeSide string (enum) Filter by trade side — One of: BUY, SELL
tradeClass string (enum) Filter by trade class — One of: OTC, RFS
from string (date-time) Start date/time filter (ISO 8601 format) for createdAt
to string (date-time) End date/time filter (ISO 8601 format) for createdAt
accountGroupUuid string (uuid) Filter by specific account group UUID
sortDirection string (enum) Sort direction applied to the trade ordering — One of: ASC, DESC — Default: “DESC”
max integer (int32) Maximum results to return (1-200) — Default: 50
offset integer (int32) Offset for pagination — Default: 0
userUuid string Master API keys only: UUID of the user to act on behalf of. Ignored unless the calling key belongs to the owner of a master-API-enabled site.
Field Type Required Description
data array of object Array of trade objects
data[].uuid string (uuid) Unique trade identifier
data[].createdAt string (date-time) Trade creation timestamp (ISO 8601)
data[].updatedAt string (date-time) Last update timestamp (ISO 8601)
data[].tradeRef string Zodia Markets trade reference
data[].clientRef string Your custom client reference (if provided during RFS trade execution)
data[].tradeSide string (enum) BUY or SELL from your perspective — One of: BUY, SELL
data[].settlementAmount object Amount to be settled (what you pay/receive)
data[].settlementAmount.amount number Amount value
data[].settlementAmount.currency string Currency code (ISO 4217 for fiat, asset symbol for crypto)
data[].tradedAmount object Amount traded (what you buy/sell)
data[].tradedAmount.amount number Amount value
data[].tradedAmount.currency string Currency code (ISO 4217 for fiat, asset symbol for crypto)
data[].user string User Account shortcode
data[].accountGroup object Account group information
data[].accountGroup.uuid string (uuid) Account group UUID
data[].accountGroup.name string Account group name
data[].tradeClass string (enum) Trade classification: OTC or RFS — One of: OTC, RFS
data[].tradeState string (enum) Current trade state — One of: CANCELLED, PROCESSED, PENDING_SETTLEMENT
data[].settlementDate string (date) Expected settlement date (YYYY-MM-DD)
data[].quoteId string Quote ID from price stream (for RFS trades, not present for OTC)
data[].beneficiary object Third-party beneficiary details (not present for standard settlement)
data[].beneficiary.uuid string (uuid) Beneficiary UUID
data[].beneficiary.name string Beneficiary name
data[].sender object Third-party sender details (not present for standard settlement)
data[].sender.uuid string (uuid) Sender UUID
data[].sender.name string Sender name
data[].networkId string Settlement network identifier (not present for standard settlement)
data[].executedPrice string Execution price with currency pair
data[].paymentReason string Payment Reason for third party receipt/delivery trades
total integer Total number of trades matching the filter criteria
Field Type Required Description
timestamp string Unix timestamp of the response (milliseconds).
resultCode string (enum) Failure reason. — One of: INVALID_PARAMETERS, UNAUTHORISED