curl --request GET \
--url https://api.centaur.io/v1/traders/rankings \
--header 'x-api-key: <api-key>'import requests
url = "https://api.centaur.io/v1/traders/rankings"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.centaur.io/v1/traders/rankings', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.centaur.io/v1/traders/rankings",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.centaur.io/v1/traders/rankings"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.centaur.io/v1/traders/rankings")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.centaur.io/v1/traders/rankings")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"filtersApplied": {
"metric": "event_count",
"assetIds": [
123
],
"direction": "long",
"timeBasedPerformanceWindow": "1D",
"minPositions": 123,
"windowEvaluability": "partial",
"appliedTimeRange": {
"startTime": "2023-11-07T05:31:56Z",
"endTime": "2023-11-07T05:31:56Z"
}
},
"results": [
{
"traderId": 123,
"rank": 123,
"metricValue": 123,
"eventCount": 123,
"positionCount": 123,
"directionBias": {
"label": "long",
"longCount": 123,
"shortCount": 123,
"longPercentage": 123,
"shortPercentage": 123
},
"timeBasedPerformance": {
"window": "1D",
"averageReturnPercentage": 123,
"medianReturnPercentage": 123,
"winRatePercentage": 123,
"sharpeRatio": 123,
"positionsCount": 123,
"coverage": {
"sampledPositionsCount": 123,
"scoredPositionsCount": 123,
"ratio": 0.5
}
}
}
],
"meta": {
"totalCandidates": 123,
"serverTime": "2023-11-07T05:31:56Z"
}
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Unauthorized"
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Forbidden"
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "PERFORMANCE_WINDOW_NOT_ELAPSED",
"message": "No position opened in the resolved sample can have a completed 30D time-based evaluation yet. Retry with one of the returned alternatives.",
"details": {
"requested": {
"startTime": "2026-08-23T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "30D"
},
"resolved": {
"startTime": "2026-08-23T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "30D"
},
"alternatives": [
{
"strategy": "preserve_sample",
"startTime": "2026-08-23T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "1D"
},
{
"strategy": "preserve_evaluation",
"startTime": "2026-07-24T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "30D"
}
]
}
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "AUTHENTICATION_UNAVAILABLE",
"message": "Authentication is temporarily unavailable"
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}Rank traders
Ranks traders across the platform by activity or performance over an explicit UTC time window, without requiring trader IDs. Returns a small bounded result ordered by the applied metric. Use this instead of paging raw events or messages for “most active” or “best performing” questions.
curl --request GET \
--url https://api.centaur.io/v1/traders/rankings \
--header 'x-api-key: <api-key>'import requests
url = "https://api.centaur.io/v1/traders/rankings"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.centaur.io/v1/traders/rankings', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.centaur.io/v1/traders/rankings",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.centaur.io/v1/traders/rankings"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.centaur.io/v1/traders/rankings")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.centaur.io/v1/traders/rankings")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"filtersApplied": {
"metric": "event_count",
"assetIds": [
123
],
"direction": "long",
"timeBasedPerformanceWindow": "1D",
"minPositions": 123,
"windowEvaluability": "partial",
"appliedTimeRange": {
"startTime": "2023-11-07T05:31:56Z",
"endTime": "2023-11-07T05:31:56Z"
}
},
"results": [
{
"traderId": 123,
"rank": 123,
"metricValue": 123,
"eventCount": 123,
"positionCount": 123,
"directionBias": {
"label": "long",
"longCount": 123,
"shortCount": 123,
"longPercentage": 123,
"shortPercentage": 123
},
"timeBasedPerformance": {
"window": "1D",
"averageReturnPercentage": 123,
"medianReturnPercentage": 123,
"winRatePercentage": 123,
"sharpeRatio": 123,
"positionsCount": 123,
"coverage": {
"sampledPositionsCount": 123,
"scoredPositionsCount": 123,
"ratio": 0.5
}
}
}
],
"meta": {
"totalCandidates": 123,
"serverTime": "2023-11-07T05:31:56Z"
}
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Unauthorized"
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "FORBIDDEN",
"message": "Forbidden"
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "PERFORMANCE_WINDOW_NOT_ELAPSED",
"message": "No position opened in the resolved sample can have a completed 30D time-based evaluation yet. Retry with one of the returned alternatives.",
"details": {
"requested": {
"startTime": "2026-08-23T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "30D"
},
"resolved": {
"startTime": "2026-08-23T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "30D"
},
"alternatives": [
{
"strategy": "preserve_sample",
"startTime": "2026-08-23T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "1D"
},
{
"strategy": "preserve_evaluation",
"startTime": "2026-07-24T00:00:00.000Z",
"endTime": "2026-08-30T00:00:00.000Z",
"timeBasedPerformanceWindow": "30D"
}
]
}
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}{
"success": false,
"error": {
"code": "AUTHENTICATION_UNAVAILABLE",
"message": "Authentication is temporarily unavailable"
},
"requestId": "c8e2c6e4-80dd-4ffc-9d66-4e31bf64c6b8"
}Query Parameters
Restrict the ranking to traders active in these assets. Positive integer asset IDs only. REST accepts comma-separated values or repeated parameters. MCP accepts an array. Numeric strings become IDs. Maximum 200 non-empty supplied entries per field, including duplicates. Use assetRefs for slugs, tickers, or legacy symbols. Do not supply assetIds and assetRefs together, even if one is empty.
"1,34"
Restrict the ranking to traders active in these assets. Asset slugs, tickers, or legacy symbols as strings only. REST accepts comma-separated values or repeated parameters. MCP accepts a string array, e.g. ["AAPL", "crypto-btc", "700"]. Values are trimmed and matched case-insensitively, in order: slug, ticker, then legacy symbol. Numeric text such as "700" is a literal reference, never an ID. Maximum 200 non-empty supplied entries per field, including duplicates. Do not supply assetIds and assetRefs together, even if one is empty. Unknown references match nothing. Retry ambiguous references with a returned numeric ID in assetIds, omitting assetRefs. Find names with asset discovery search.
"AAPL,crypto-btc,700"