Report Trading Data (v2)
Report trading data for your engaged projects across different exchanges using the v2 schema.
Overview
This endpoint allows you to submit market maker data for your engaged projects using the v2 schema. In addition to the metrics supported by v1, v2 captures top-of-book and basis-point order book depth, the instrument type (spot or perpetual/derivatives), and a submission type.
All metric fields are required
Unlike v1, where most numeric fields are optional and default to 0, every metric field is required in v2. The quote coin fields are conditional: provide at least one of quoteCoinId or quoteCoinSymbol; if both are sent, quoteCoinId takes precedence and quoteCoinSymbol is ignored.
Endpoint: POST https://data.api.forgd.com/api/v2/report
Authentication: Required (API Key) (docs)
POST Request
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | API key for authentication Check Authentication for more details |
x-dry-run | boolean | No | Run validation without uploading data Check Dry Run Mode for more details |
Request Body
Request Body Type
type RequestBody = {
data: {
date: string // YYYY-MM-DD format
exchangeId: string // CoinGecko exchange ID
baseCoinId: string // CoinGecko project ID
quoteCoinId?: string // CoinGecko quote coin ID
quoteCoinSymbol?: string // Quote coin symbol (USD, EUR, etc.)
bidDepth50: number // Bid depth at 50 ticks
askDepth50: number // Ask depth at 50 ticks
bidAskDepth50: number // Total depth at 50 ticks
bidDepth100: number // Bid depth at 100 ticks
askDepth100: number // Ask depth at 100 ticks
bidAskDepth100: number // Total depth at 100 ticks
bidDepth200: number // Bid depth at 200 ticks
askDepth200: number // Ask depth at 200 ticks
bidAskDepth200: number // Total depth at 200 ticks
bidAskSpread: number // Bid-ask spread percentage, ie. 0.5% should be reported as 0.5 (not 0.005)
orderFillVolumeMaker: number // Maker order fill volume
orderFillVolumeTaker: number // Taker order fill volume
instrumentType: 'spot' | 'perp' // Spot market or perpetual/derivatives market
type: 'project' | 'exchange' | 'prop' // Submission type
topOfBookPercentage: number // Percentage of instances at top of book (0-100)
bidDepthTob: number // Bid depth at top of book
bidDepth10: number // Bid depth at 10 basis points
bidDepth25: number // Bid depth at 25 basis points
askDepthTob: number // Ask depth at top of book
askDepth10: number // Ask depth at 10 basis points
askDepth25: number // Ask depth at 25 basis points
orderFillVolumeMakerTob: number // Maker order fill volume executed from top of book
}[]
}{
"data": [
{
"date": "2024-03-14",
"exchangeId": "binance",
"baseCoinId": "solana",
"quoteCoinId": "tether",
"bidDepth50": 809,
"askDepth50": 971,
"bidAskDepth50": 1780,
"bidDepth100": 1380,
"askDepth100": 1520,
"bidAskDepth100": 2900,
"bidDepth200": 2180,
"askDepth200": 2320,
"bidAskDepth200": 4500,
"bidAskSpread": 0.1,
"orderFillVolumeMaker": 8902,
"orderFillVolumeTaker": 23479,
"instrumentType": "spot",
"type": "project",
"topOfBookPercentage": 42.5,
"bidDepthTob": 20000,
"bidDepth10": 45000,
"bidDepth25": 75000,
"askDepthTob": 21000,
"askDepth10": 43000,
"askDepth25": 71000,
"orderFillVolumeMakerTob": 125000
},
{
"date": "2024-03-14",
"exchangeId": "binance",
"baseCoinId": "solana",
"quoteCoinSymbol": "EUR",
"bidDepth50": 456,
"askDepth50": 523,
"bidAskDepth50": 979,
"bidDepth100": 789,
"askDepth100": 856,
"bidAskDepth100": 1645,
"bidDepth200": 1245,
"askDepth200": 1321,
"bidAskDepth200": 2566,
"bidAskSpread": 0.15,
"orderFillVolumeMaker": 5432,
"orderFillVolumeTaker": 15678,
"instrumentType": "spot",
"type": "project",
"topOfBookPercentage": 38,
"bidDepthTob": 12000,
"bidDepth10": 26000,
"bidDepth25": 41000,
"askDepthTob": 12500,
"askDepth10": 25000,
"askDepth25": 39000,
"orderFillVolumeMakerTob": 64000
}
]
}A single request accepts between 1 and 300 records in the data array.
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
date | string | required | Trading date in YYYY-MM-DD format |
exchangeId | string | required | Exchange ID from list of available exchanges Available also on exchanges endpoint |
baseCoinId | string | required | Base coin ID from projects endpoint |
quoteCoinId | string | conditional | Quote coin id from list of available coins Required for trading pairs against crypto currencies where quoteCoinSymbol is not provided - when to use |
quoteCoinSymbol | string | conditional | Quote coin symbol (USD, EUR, etc.) from list of available currencies Required for trading pairs against fiat currencies where quoteCoinId is not provided - when to use |
bidDepth50 | number | required | Bid depth at 50 ticks (in USD) |
askDepth50 | number | required | Ask depth at 50 ticks (in USD) |
bidAskDepth50 | number | required | Total depth at 50 ticks (in USD) Prefer providing bidDepth50 and askDepth50 individually |
bidDepth100 | number | required | Bid depth at 100 ticks (in USD) |
askDepth100 | number | required | Ask depth at 100 ticks (in USD) |
bidAskDepth100 | number | required | Total depth at 100 ticks (in USD) Prefer providing bidDepth100 and askDepth100 individually |
bidDepth200 | number | required | Bid depth at 200 ticks (in USD) |
askDepth200 | number | required | Ask depth at 200 ticks (in USD) |
bidAskDepth200 | number | required | Total depth at 200 ticks (in USD) Prefer providing bidDepth200 and askDepth200 individually |
bidAskSpread | number | required | Bid-ask spread percentage value (0–100) ie. spread of 0.5% should be reported as 0.5 (not 0.005) |
orderFillVolumeMaker | number | required | Maker order fill volume (in USD) |
orderFillVolumeTaker | number | required | Taker order fill volume (in USD) |
instrumentType | enum | required | spot or perp — whether the data is for a spot market or a perpetual/derivatives market Must match the exchange - instrument type and exchange compatibility |
type | enum | required | Submission type for this row — one of project, exchange, prop - submission type |
topOfBookPercentage | number | required | Percentage of instances where the market maker was top of book (0–100) |
bidDepthTob | number | required | Bid depth at top of book (in USD) |
bidDepth10 | number | required | Bid depth at 10 basis points (in USD) |
bidDepth25 | number | required | Bid depth at 25 basis points (in USD) |
askDepthTob | number | required | Ask depth at top of book (in USD) |
askDepth10 | number | required | Ask depth at 10 basis points (in USD) |
askDepth25 | number | required | Ask depth at 25 basis points (in USD) |
orderFillVolumeMakerTob | number | required | Maker order fill volume executed from top of book (in USD) |
Instrument type and exchange compatibility
Set instrumentType to spot for spot markets and perp for perpetual/derivatives markets. The value must be compatible with the exchange you report against:
- If you submit
spotdata for an exchange that does not support spot markets, the request fails with:Exchange '<name>' is not a spot exchange; set instrumentType to 'perp' for perpetual/derivatives data - If you submit
perpdata for an exchange that does not support derivatives, the request fails with:Exchange '<name>' is not a derivatives exchange; set instrumentType to 'spot' for spot data - When a matching spot or derivatives venue exists for the same exchange, your report is automatically routed to it.
Use the exchanges endpoint or the list of available exchanges to confirm which markets an exchange supports.
Submission type
Set type to match the kind of engagement the data is reported under:
type | Use it for |
|---|---|
project | Loan + Call Option and Retainer + Working Capital |
exchange | Exchange Engagements |
prop | Prop Trading |
When to use quoteCoinId and quoteCoinSymbol
Use quoteCoinId for trading pairs against crypto currencies:
SOL/USDT(usequoteCoinId: 'tether')SOL/USDC(usequoteCoinId: 'usd-coin')SOL/BTC(usequoteCoinId: 'bitcoin')
Use quoteCoinSymbol for trading pairs against fiat currencies:
SOL/USD(usequoteCoinSymbol: 'USD')SOL/EUR(usequoteCoinSymbol: 'EUR')SOL/KRW(usequoteCoinSymbol: 'KRW')
At least one of quoteCoinId or quoteCoinSymbol is required.
These fields are not mutually exclusive. When quoteCoinId is set, it determines the quote coin and quoteCoinSymbol is ignored.
Examples
curl -X POST "https://data.api.forgd.com/api/v2/report" \
-H "Authorization: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"data": [
{
"date": "2024-03-14",
"exchangeId": "binance",
"baseCoinId": "solana",
"quoteCoinId": "tether",
"bidDepth50": 809,
"askDepth50": 971,
"bidAskDepth50": 1780,
"bidDepth100": 1380,
"askDepth100": 1520,
"bidAskDepth100": 2900,
"bidDepth200": 2180,
"askDepth200": 2320,
"bidAskDepth200": 4500,
"bidAskSpread": 0.1,
"orderFillVolumeMaker": 8902,
"orderFillVolumeTaker": 23479,
"instrumentType": "spot",
"type": "project",
"topOfBookPercentage": 42.5,
"bidDepthTob": 20000,
"bidDepth10": 45000,
"bidDepth25": 75000,
"askDepthTob": 21000,
"askDepth10": 43000,
"askDepth25": 71000,
"orderFillVolumeMakerTob": 125000
}
]
}'const response = await fetch('https://data.api.forgd.com/api/v2/report', {
method: 'POST',
headers: {
Authorization: '<API_KEY>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: [
{
date: '2024-03-14',
exchangeId: 'binance',
baseCoinId: 'solana',
quoteCoinId: 'tether',
bidDepth50: 809,
askDepth50: 971,
bidAskDepth50: 1780,
bidDepth100: 1380,
askDepth100: 1520,
bidAskDepth100: 2900,
bidDepth200: 2180,
askDepth200: 2320,
bidAskDepth200: 4500,
bidAskSpread: 0.1,
orderFillVolumeMaker: 8902,
orderFillVolumeTaker: 23479,
instrumentType: 'spot',
type: 'project',
topOfBookPercentage: 42.5,
bidDepthTob: 20000,
bidDepth10: 45000,
bidDepth25: 75000,
askDepthTob: 21000,
askDepth10: 43000,
askDepth25: 71000,
orderFillVolumeMakerTob: 125000,
},
],
}),
})
const data = await response.json()
if (response.ok) {
console.log('Report:', data)
} else {
console.error('Error:', response.status, response.statusText, data)
}import requests
data = {
"data": [
{
"date": "2024-03-14",
"exchangeId": "binance",
"baseCoinId": "solana",
"quoteCoinId": "tether",
"bidDepth50": 809,
"askDepth50": 971,
"bidAskDepth50": 1780,
"bidDepth100": 1380,
"askDepth100": 1520,
"bidAskDepth100": 2900,
"bidDepth200": 2180,
"askDepth200": 2320,
"bidAskDepth200": 4500,
"bidAskSpread": 0.1,
"orderFillVolumeMaker": 8902,
"orderFillVolumeTaker": 23479,
"instrumentType": "spot",
"type": "project",
"topOfBookPercentage": 42.5,
"bidDepthTob": 20000,
"bidDepth10": 45000,
"bidDepth25": 75000,
"askDepthTob": 21000,
"askDepth10": 43000,
"askDepth25": 71000,
"orderFillVolumeMakerTob": 125000
}
]
}
response = requests.post(
'https://data.api.forgd.com/api/v2/report',
headers={'Authorization': '<API_KEY>'},
json=data
)
data = response.json()
if response.ok:
print('Report:', data)
else:
print('Error:', response.status_code, response.reason, data)Success Response
HTTP 201 Created
Returns information about the uploaded data including counts of created and updated records.
Response Type
type SuccessResponseType = {
createdCount: number
updatedCount: number
}{
"createdCount": 258,
"updatedCount": 42
}Error Responses
HTTP 400 Bad Request
There was an error in the request body. Please check the message field for more details, fix the errors and try again.
type ErrorResponseType = {
message: {
path?: string
message: string
}[]
error: string
statusCode: number
}{
"message": [
{
"path": "data.0.topOfBookPercentage",
"message": "Required"
},
{
"path": "data.0.instrumentType",
"message": "Exchange 'Binance' is not a spot exchange; set instrumentType to 'perp' for perpetual/derivatives data"
},
{
"path": "data.5.bidDepth100",
"message": "Expected number, received string"
}
],
"error": "Bad Request",
"statusCode": 400
}HTTP 401 Unauthorized
The request could not be authenticated. Possible reasons:
- You have not attached an API Key to your request - see Authentication
- Your API key is invalid or has been removed - see Obtaining an API Key
type ErrorResponseType = {
message: string
statusCode: number
}{
"message": "Unauthorized",
"statusCode": 401
}HTTP 5xx Internal Server Error
The request has failed due to an error on the server side. Most likely there is an internal issue with our server or network - please try again after couple of minutes.
We are getting notified about every 5XX response internally but if this is an recurring issue, please contact us at support@forgd.com.
Dry Run Mode
You can test your data format without actually uploading by setting the x-dry-run header to true. This will validate your data and return the same response format without persisting the data.
const response = await fetch('https://data.api.forgd.com/api/v2/report', {
method: 'POST',
headers: {
Authorization: '<API_KEY>',
'Content-Type': 'application/json',
'x-dry-run': 'true',
},
body: JSON.stringify({
data: [...],
}),
})import requests
response = requests.post(
'https://data.api.forgd.com/api/v2/report',
headers={
'Authorization': '<API_KEY>',
'x-dry-run': 'true'
},
json={'data': [...]},
)curl -X POST "https://data.api.forgd.com/api/v2/report" \
-H "Authorization: <API_KEY>" \
-H "Content-Type: application/json" \
-H "x-dry-run: true" \
-d '{"data": [...]}'FAQ & Troubleshooting
Updating existing report data
To update the data, submit the report using this endpoint for the same date, exchangeId, baseCoinId, quote coin (quoteCoinId or quoteCoinSymbol) and instrumentType. Response will contain the counts of created and updated records.
Deleting existing report data
Currently there is no way to delete the report data.
My bid-ask spread in the application is lower than the value I have reported
Common mistake is that the bid-ask spread is reported as a decimal value where 0.5% spread is reported as 0.0005 while it should be reported as 0.5. Please check the your integration and make sure you are reporting the value correctly.
To fix the issue, please submit your past reports again with the correct values and your data will be updated.