curl --request GET \
--url https://api.range.org/v2/treasury/cash-flow \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.range.org/v2/treasury/cash-flow"
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.range.org/v2/treasury/cash-flow', 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.range.org/v2/treasury/cash-flow",
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.range.org/v2/treasury/cash-flow"
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.range.org/v2/treasury/cash-flow")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/treasury/cash-flow")
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{
"period": {
"start": "2026-08-01T00:00:00.000Z",
"end": "2026-09-01T00:00:00.000Z"
},
"bucket": "day",
"items": [
{
"inflow_usd": "1250.75",
"outflow_usd": "900.00",
"net_usd": "350.75",
"transfer_count": 4,
"unpriced_leg_count": 0,
"period_start": "2026-08-15T00:00:00.000Z",
"period_end": "2026-08-16T00:00:00.000Z"
}
],
"totals": {
"inflow_usd": "1250.75",
"outflow_usd": "900.00",
"net_usd": "350.75",
"transfer_count": 4,
"unpriced_leg_count": 0
},
"data_availability": {
"flows": "available",
"notes": [
"Trades are excluded from cash flow; only TRANSFER events are counted.",
"USD for legs without a provider-supplied price is valued at current spot, not price at event time."
]
}
}Get bucketed cash-flow series
Inflow, outflow and net over a caller-chosen window, bucketed by day, ISO week (Monday start), or calendar month. Buckets are calendar-aligned, half-open [period_start, period_end), UTC, contiguous and ascending; a quiet bucket reports real zeros, never an absent entry. The echoed period reflects the window after it is outward-snapped to bucket boundaries, not the raw request. Flows are gross (a movement between two of your own accounts counts once as inflow and once as outflow) — filtering to a single account_id, or to only one side of such a pair, is expected to make net non-zero; this is defined behavior, not a bug. See data_availability for missing or truncated transaction history.
curl --request GET \
--url https://api.range.org/v2/treasury/cash-flow \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.range.org/v2/treasury/cash-flow"
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.range.org/v2/treasury/cash-flow', 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.range.org/v2/treasury/cash-flow",
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.range.org/v2/treasury/cash-flow"
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.range.org/v2/treasury/cash-flow")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.range.org/v2/treasury/cash-flow")
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{
"period": {
"start": "2026-08-01T00:00:00.000Z",
"end": "2026-09-01T00:00:00.000Z"
},
"bucket": "day",
"items": [
{
"inflow_usd": "1250.75",
"outflow_usd": "900.00",
"net_usd": "350.75",
"transfer_count": 4,
"unpriced_leg_count": 0,
"period_start": "2026-08-15T00:00:00.000Z",
"period_end": "2026-08-16T00:00:00.000Z"
}
],
"totals": {
"inflow_usd": "1250.75",
"outflow_usd": "900.00",
"net_usd": "350.75",
"transfer_count": 4,
"unpriced_leg_count": 0
},
"data_availability": {
"flows": "available",
"notes": [
"Trades are excluded from cash flow; only TRANSFER events are counted.",
"USD for legs without a provider-supplied price is valued at current spot, not price at event time."
]
}
}Authorizations
Authorization method required to allow user to access the api endpoints.
Query Parameters
Filter accounts by group name (exact match, case-sensitive).
"Treasury"
eoa, multisig, contract, custodian, exchange, bank, defi "bank"
utila, kraken, binance, okx, bybit, bitget, gate, kucoin, plaid, squads, altitude, coinbase, realms, wise, safe, hyperliquid, cubist, privy, dfns, anchorage, revolut_business, turnkey, fordefi, coins_ph, fireblocks, pave_bank, copper "utila"
Filter by account network/chain.
"ethereum"
Filter balances and transfer legs by asset symbol.
"USDC"
Start of the window (ISO-8601; a bare YYYY-MM-DD is that UTC day). Defaults to 30 days before the effective end_time.
"2026-08-01T00:00:00.000Z"
Exclusive end of the window (ISO-8601; a bare YYYY-MM-DD is the next UTC day). Defaults to now when omitted.
"2026-09-01T00:00:00.000Z"
Bucket granularity.
day, week, month "day"
Filter to a single account id. Endpoint-local — not part of the shared treasury account filters, so summary's and forecast's contracts are unaffected.
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
Response
Show child attributes
Show child attributes
The bucket granularity actually used.
day, week, month "day"
Ascending by period_start, contiguous (each period_end equals the next period_start). Empty when the filters match no accounts — distinct from a real series of zero-valued buckets.
Show child attributes
Show child attributes
Rollup of every item above over the whole effective window.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?