curl --request GET \
--url https://www.oceanx.trade/api/v1/scout/{stage} \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.oceanx.trade/api/v1/scout/{stage}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://www.oceanx.trade/api/v1/scout/{stage}', 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://www.oceanx.trade/api/v1/scout/{stage}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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://www.oceanx.trade/api/v1/scout/{stage}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.oceanx.trade/api/v1/scout/{stage}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.oceanx.trade/api/v1/scout/{stage}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"chain": "solana",
"stage": "new",
"items": [
{
"mint": "<string>",
"name": "<string>",
"symbol": "<string>",
"createdAtMs": 4503599627370496,
"chainCreatedAtMs": 4503599627370496,
"stageEnteredAtMs": 4503599627370496,
"migratedAtMs": 4503599627370496,
"provisionalExpiresAtMs": 4503599627370496,
"launchpad": "<string>",
"poolAddress": "<string>",
"removalReason": "<string>",
"provisional": true,
"priceUsd": "<string>",
"marketCapUsd": "<string>",
"liquidityUsd": "<string>",
"volume5mUsd": "<string>",
"bondingProgressPct": "<string>",
"fieldUpdatedAt": "<unknown>",
"riskSources": "<unknown>",
"mcSource": "<string>",
"curveSource": "<string>",
"migrationEvent": "<unknown>",
"provenance": "<unknown>",
"amountCoverage": {
"status": "<string>",
"reason": "<string>"
}
}
]
},
"meta": {
"requestId": "<string>",
"methodVersion": "public-scout-v1",
"source": "cache",
"snapshotVersion": "<string>",
"snapshotExpiresAtMs": 123,
"observedAtMs": 4503599627370496,
"staleAfterMs": 4503599627370496,
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
},
"replayCursor": null,
"selectionAtMs": 123,
"cursorExpiresAtMs": 123,
"nextCursor": "<string>",
"matchedCount": 100,
"windowCount": 100
}
}{
"error": {
"code": "<string>",
"message": "<string>"
},
"requestId": "<string>",
"meta": {
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
}
}
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
},
"requestId": "<string>",
"meta": {
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
}
}
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
},
"requestId": "<string>",
"meta": {
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
}
}
}Read a retained Scout stage snapshot
Requires md.read and the existing 120/min REST key limiter before any backend read. Solana only. Maps new/latest and migrated/graduated using producer membership. At most 200 retained tokens; not an exhaustive listing. Initialized complete empty windows succeed; unavailable, legacy, corrupt or uninitialized windows fail 503. Nonempty partial windows retain partial coverage even if filters exclude every row. Unknown amounts and clocks are null, never zero. All filters and pagination run over an immutable backend version. Signed cursors bind chain, stage, every filter, sort, order and limit; repeat all selectors. The five-minute expiry and age evaluation time never slide. Sort ties use mint ascending and unknowns sort last in either direction. Backend retention expiry is not freshness. No vendor/enrichment/history work, retries or idle refresh. Cache-Control: no-store. Unknown/repeated selectors and URLs over 8 KiB fail 400. Before the snapshot backend is rolled, this route fails closed with 503.
curl --request GET \
--url https://www.oceanx.trade/api/v1/scout/{stage} \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.oceanx.trade/api/v1/scout/{stage}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://www.oceanx.trade/api/v1/scout/{stage}', 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://www.oceanx.trade/api/v1/scout/{stage}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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://www.oceanx.trade/api/v1/scout/{stage}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.oceanx.trade/api/v1/scout/{stage}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.oceanx.trade/api/v1/scout/{stage}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"chain": "solana",
"stage": "new",
"items": [
{
"mint": "<string>",
"name": "<string>",
"symbol": "<string>",
"createdAtMs": 4503599627370496,
"chainCreatedAtMs": 4503599627370496,
"stageEnteredAtMs": 4503599627370496,
"migratedAtMs": 4503599627370496,
"provisionalExpiresAtMs": 4503599627370496,
"launchpad": "<string>",
"poolAddress": "<string>",
"removalReason": "<string>",
"provisional": true,
"priceUsd": "<string>",
"marketCapUsd": "<string>",
"liquidityUsd": "<string>",
"volume5mUsd": "<string>",
"bondingProgressPct": "<string>",
"fieldUpdatedAt": "<unknown>",
"riskSources": "<unknown>",
"mcSource": "<string>",
"curveSource": "<string>",
"migrationEvent": "<unknown>",
"provenance": "<unknown>",
"amountCoverage": {
"status": "<string>",
"reason": "<string>"
}
}
]
},
"meta": {
"requestId": "<string>",
"methodVersion": "public-scout-v1",
"source": "cache",
"snapshotVersion": "<string>",
"snapshotExpiresAtMs": 123,
"observedAtMs": 4503599627370496,
"staleAfterMs": 4503599627370496,
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
},
"replayCursor": null,
"selectionAtMs": 123,
"cursorExpiresAtMs": 123,
"nextCursor": "<string>",
"matchedCount": 100,
"windowCount": 100
}
}{
"error": {
"code": "<string>",
"message": "<string>"
},
"requestId": "<string>",
"meta": {
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
}
}
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
},
"requestId": "<string>",
"meta": {
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
}
}
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
},
"requestId": "<string>",
"meta": {
"coverage": {
"status": "complete",
"reason": "<string>",
"initialized": true,
"basis": "retained_stage_window",
"complete": true
}
}
}Authorizations
An OceanX API key, created in the app under Settings → Developer API. Send it as Authorization: Bearer ox_live_…. Required scopes are operation-specific: market reads use md.read, tracker uses tracker.read, copy reads use copy.read, and alert operations use alerts.read or alerts.write. New scopes require explicit selection and grant no trading authority. Existing perps operations retain their documented scopes.
Path Parameters
new, graduating, migrated Query Parameters
solana Exact case-sensitive producer launchpad match; unknown excluded.
^[a-zA-Z0-9_.-]{1,64}$Inclusive exact decimal threshold. Unknown liquidity is excluded, including when the minimum is zero.
128^\d+(\.\d+)?$Inclusive age from producer-pinned first observation (createdAtMs), relative to selectionAtMs. Unknown/future creation observations are excluded.
1 <= x <= 2592000createdAt, volume5m, liquidityUsd asc, desc 1 <= x <= 200Opaque HMAC-signed five-minute pagination cursor. Tampering or changed selectors: 400; expiry or evicted version: 410.
1 - 2048