curl --request GET \
--url https://www.oceanx.trade/api/v1/tokens/{chain}/{address}/liquidity \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.oceanx.trade/api/v1/tokens/{chain}/{address}/liquidity"
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/tokens/{chain}/{address}/liquidity', 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/tokens/{chain}/{address}/liquidity",
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/tokens/{chain}/{address}/liquidity"
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/tokens/{chain}/{address}/liquidity")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.oceanx.trade/api/v1/tokens/{chain}/{address}/liquidity")
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": [
{
"eventType": "liquidity",
"id": "<string>",
"signature": "<string>",
"eventAtMs": 123,
"slot": "<string>",
"poolAddress": "<string>",
"maker": "<string>",
"identity": {
"label": "<string>",
"image": "<string>",
"twitter": "<string>",
"type": "<string>",
"platform": "<string>",
"flags": [
"<string>"
],
"source": "oceanx_wallet_labels",
"asOf": 1,
"profileAsOf": 1,
"profileSource": "wallet_label_reviews"
},
"dex": "<string>",
"kind": "add",
"tokenA": {
"asset": "<string>",
"amount": "<string>",
"amountRaw": "<string>",
"decimals": 127,
"feeAmountRaw": "<string>",
"amountBasis": "vault_balance_delta"
},
"tokenB": {
"asset": "<string>",
"amount": "<string>",
"amountRaw": "<string>",
"decimals": 127,
"feeAmountRaw": "<string>",
"amountBasis": "vault_balance_delta"
},
"instruction": "<string>",
"programId": "<string>",
"provisional": false
}
],
"nextCursor": "<string>",
"hasNextPage": true,
"meta": {
"source": "native_activity",
"methodVersion": "public-token-activity-v1",
"chain": "solana",
"address": "<string>",
"events": "all",
"sortDirection": "asc",
"cursorTtlMs": 30000,
"window": {
"fromMs": 123,
"toMs": 123
},
"coverage": {
"complete": false,
"reason": "retained_observations_only",
"liquidityReason": "<string>",
"decodedProtocols": [
"<string>"
]
},
"requestId": "<string>"
}
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}Read captured native liquidity activity
Requires md.read and consumes the existing REST key limiter. Solana only; unsupported chains return 400 unsupported_chain. Unknown/repeated query parameters and URLs over 8 KiB are rejected. Responses use Cache-Control: no-store. No paid enrichment is started. Equivalent to trades?events=liquidity. Own decoded LP captures only; current exact decoder scope is Meteora DAMM v2 WSOL pairs. Amounts are decimal strings and raw strings with decimals, feeAmountRaw (null until proved), amountBasis, instruction and programId. Coverage remains partial; empty unqualified captures return 503. Stable IDs and 30-second pinned cursors; repeat wallet, pool, direction, window and limit. At most 24 hours and 5000 captured rows per snapshot. No swap volume inference. 2 concurrent requests/IP, 60 starts/min/IP, 32 global; limiter failure returns 503.
curl --request GET \
--url https://www.oceanx.trade/api/v1/tokens/{chain}/{address}/liquidity \
--header 'Authorization: Bearer <token>'import requests
url = "https://www.oceanx.trade/api/v1/tokens/{chain}/{address}/liquidity"
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/tokens/{chain}/{address}/liquidity', 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/tokens/{chain}/{address}/liquidity",
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/tokens/{chain}/{address}/liquidity"
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/tokens/{chain}/{address}/liquidity")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.oceanx.trade/api/v1/tokens/{chain}/{address}/liquidity")
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": [
{
"eventType": "liquidity",
"id": "<string>",
"signature": "<string>",
"eventAtMs": 123,
"slot": "<string>",
"poolAddress": "<string>",
"maker": "<string>",
"identity": {
"label": "<string>",
"image": "<string>",
"twitter": "<string>",
"type": "<string>",
"platform": "<string>",
"flags": [
"<string>"
],
"source": "oceanx_wallet_labels",
"asOf": 1,
"profileAsOf": 1,
"profileSource": "wallet_label_reviews"
},
"dex": "<string>",
"kind": "add",
"tokenA": {
"asset": "<string>",
"amount": "<string>",
"amountRaw": "<string>",
"decimals": 127,
"feeAmountRaw": "<string>",
"amountBasis": "vault_balance_delta"
},
"tokenB": {
"asset": "<string>",
"amount": "<string>",
"amountRaw": "<string>",
"decimals": 127,
"feeAmountRaw": "<string>",
"amountBasis": "vault_balance_delta"
},
"instruction": "<string>",
"programId": "<string>",
"provisional": false
}
],
"nextCursor": "<string>",
"hasNextPage": true,
"meta": {
"source": "native_activity",
"methodVersion": "public-token-activity-v1",
"chain": "solana",
"address": "<string>",
"events": "all",
"sortDirection": "asc",
"cursorTtlMs": 30000,
"window": {
"fromMs": 123,
"toMs": 123
},
"coverage": {
"complete": false,
"reason": "retained_observations_only",
"liquidityReason": "<string>",
"decodedProtocols": [
"<string>"
]
},
"requestId": "<string>"
}
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "no_route",
"message": "<string>"
},
"requestId": "<string>"
}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.
Query Parameters
liquidity asc, desc Half-open window, maximum 24h. Default last hour. Repeat both bounds on cursor requests.
x >= 0Half-open window, maximum 24h. Default last hour. Repeat both bounds on cursor requests.
x >= 01 <= x <= 500