Appearance
Get exchange statistics
GET
/exchanges/statsRequired scope: rtb:exchange:read
Authenticate with Authorization: Bearer YOUR_NEXUS_API_KEY. The legacy token query parameter remains available; use one transport per request.
Returns statistics for one exchange explicitly assigned to the authenticated member.
Query parameters
| Parameter | Required | Description |
|---|---|---|
token | Only without Bearer | Compatibility transport for an active member key with explicit rtb:exchange:read. Prefer the Authorization header; do not send both. |
xid | Yes | Granted exchange ID, integer from 1 to 2147483647. |
date_from | Yes | Inclusive UTC start day, YYYY-MM-DD. |
date_to | Yes | Inclusive UTC end day, YYYY-MM-DD; maximum 90 days per request. |
groupBy | No | day (default), app, or domain; each includes the UTC day. |
export | No | json (default) or csv. |
bash
curl --get "https://api.example.com/exchanges/stats" \
--header "Authorization: Bearer YOUR_NEXUS_API_KEY" \
--data-urlencode "xid=7" \
--data-urlencode "date_from=2026-10-28" \
--data-urlencode "date_to=2026-10-28" \
--data-urlencode "groupBy=day"javascript
const params = new URLSearchParams({ xid: '7', date_from: '2026-10-28', date_to: '2026-10-28', groupBy: 'day' });
const response = await fetch(`https://api.example.com/exchanges/stats?${params}`, {
headers: { Authorization: `Bearer ${process.env.NEXUS_API_KEY}` },
});
if (!response.ok) throw new Error(`Nexus returned ${response.status}`);
console.log(await response.json());python
import os
import requests
response = requests.get(
'https://api.example.com/exchanges/stats',
headers={'Authorization': f"Bearer {os.environ['NEXUS_API_KEY']}"},
params={'xid': 7, 'date_from': '2026-10-28', 'date_to': '2026-10-28', 'groupBy': 'day'},
timeout=30,
)
response.raise_for_status()
print(response.json())groupBy=app adds sid to each row. groupBy=domain adds domains. A missing grouping value can be null. Use export=csv for an attachment with the same row fields and spreadsheet-formula protection.
Response
json
{
"status": "success",
"message": "Exchange Stats report",
"data": [
{
"date": "2026-10-28",
"exchange": 7,
"requests": "1000",
"requests_valid": "900",
"requests_error": "100",
"impressions": "100",
"clicks": "5",
"spend": 0.5,
"cpc": "0.1000",
"ctr": "5.00%",
"win": "10.00",
"cpm": "5.0000"
}
]
}Metric semantics
| Field | Calculation |
|---|---|
requests | Valid requests + request errors. |
requests_valid, requests_error, impressions, clicks | Exact summed integer counts as decimal strings, without 32-bit overflow or JSON integer rounding. |
spend | Sum of stored spend divided by 1,000,000; a number in the source's native reporting currency. |
cpc | Spend / clicks, four decimal places. |
ctr | Clicks / impressions times 100, two decimal places plus %. |
win | Impressions / total requests times 100, two decimal places without %. |
cpm | Spend / impressions times 1,000, four decimal places. |
Ratios fall back to 0.00 (0.00% for CTR) when the numerator or denominator is not positive. Dates include the entire final UTC day, including fractional seconds. Only supply-side rows with dsp = 0 are aggregated, avoiding demand-side double counting. No currency conversion occurs.
Errors and limits
400: missing, repeated, or invalid parameters; unsupported grouping/export; or a range over 90 days.401: missing, unknown, disabled, expired, revoked, or inactive key; see authentication errors.403: inactive member account, wrong member role, missing scope, or resource not assigned to this member.404: no rows for the period, for JSON and CSV.413: more than 100,000 rows; shorten the period.429: rate limit exceeded.500/503: reporting failure or temporary database/authentication/capacity unavailability; no database details are returned.
Responses are non-cacheable. Member identity and tenant come from the authenticated key and cannot be overridden with query parameters.