Get wallet history
curl --request GET \
--url https://demo-api.mobula.io/api/1/wallet/historyimport requests
url = "https://demo-api.mobula.io/api/1/wallet/history"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://demo-api.mobula.io/api/1/wallet/history', 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://demo-api.mobula.io/api/1/wallet/history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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://demo-api.mobula.io/api/1/wallet/history"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://demo-api.mobula.io/api/1/wallet/history")
.asString();require 'uri'
require 'net/http'
url = URI("https://demo-api.mobula.io/api/1/wallet/history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": {
"wallets": [
"<string>"
],
"balance_usd": 123,
"balance_history": [
[
123
]
],
"backfill_status": "processed"
}
}Wallet APIs
Get Historical Net Worth
Retrieve historical net worth for one or more wallets with filters for time range, assets, liquidity, period, caching, and chain options.
GET
/
1
/
wallet
/
history
Get wallet history
curl --request GET \
--url https://demo-api.mobula.io/api/1/wallet/historyimport requests
url = "https://demo-api.mobula.io/api/1/wallet/history"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://demo-api.mobula.io/api/1/wallet/history', 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://demo-api.mobula.io/api/1/wallet/history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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://demo-api.mobula.io/api/1/wallet/history"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://demo-api.mobula.io/api/1/wallet/history")
.asString();require 'uri'
require 'net/http'
url = URI("https://demo-api.mobula.io/api/1/wallet/history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": {
"wallets": [
"<string>"
],
"balance_usd": 123,
"balance_history": [
[
123
]
],
"backfill_status": "processed"
}
}Query details
- Either
walletorwalletsmust be provided - Boolean parameters are passed as strings (
"true","false").
| Parameter | Required | Default | Description |
|---|---|---|---|
wallet | Cond. | — | Single wallet address to query. |
wallets | Cond. | — | Comma-separated wallet addresses to query in aggregate. |
blockchains | No | All | Comma-separated list of chains (e.g., ethereum,base). |
from | No | 24h ago | Start of the historical window (Unix ms timestamp). |
to | No | Now | End of the historical window (Unix ms timestamp). |
unlistedAssets | No | true | "true" to include unlisted or non-indexed assets in the calculation. |
period | No | — | Baseline granularity of the time series. Supported values: 5min, 15min, 1h, 6h, 1d, 7d. See the note below — this sets the minimum point spacing, not a hard cap on the number of points. |
accuracy | No | maximum | Set to "maximum" to analyze all assets. By default, to optimize response time, assets making < 1% of total net worth may be skipped. |
testnet | No | false | "true" to include testnet data. |
minliq | No | 1000 | Minimum liquidity threshold in USD. Assets below are excluded. |
filterSpam | No | false | "true" to remove spam or low-quality assets from results. |
fetchUntrackedHistory | No | false | "true" to fetch historical prices for untracked assets. |
fetchAllChains | No | false | "true" to query all supported chains, including those without premium RPCs. |
shouldFetchPriceChange | No | false | Set to "24h" to include 24-hour price change data. Note: This parameter accepts the value "24h", not "true". |
backfillTransfers | No | false | "true" to trigger backfilling of transfer history for the wallet(s). Returns backfill_status in the response. |
How So a 30-day query with
period actually controls the number of pointsperiod defines a fixed grid of timestamps between from and to (e.g. period=1d produces one grid point every 24h). On top of that grid, the response always adds one extra point at the exact timestamp of every balance-changing transfer in the window, so the curve is accurate at the moment each balance change occurs.This means the total number of points is:points ≈ (to − from) / period + number of transfers in the window
period=1d returns ~30 grid points plus one point per transfer — a wallet with frequent activity can easily exceed 100 points. period sets the minimum spacing of the baseline grid, it is not a hard cap on the number of returned points.If you need exactly one point per interval, downsample client-side by bucketing balance_history into your target interval and keeping the last value of each bucket.Step-by-Step Tutorial and Video Walkthrough
- Check out the guide: Here
Usage Examples
- Query historical net worth for a single wallet with a specific time range and daily granularity
curl -X GET http://demo-api.mobula.io/api/1/wallet/history?wallet=4tqMHgB8jjbTgefVfqtVFYzyfQz2LQ8T3E922ePmt6kZ&from=1704067200000&to=1735689600000&period=1d
- Query multiple wallets with liquidity threshold
curl -X GET https://demo-api.mobula.io/api/1/wallet/history?wallets=0x33e833f33ced917af1c2879faa95f375a2a66407,0x12e833f33ced917af1c2879faa95f375a2a66408&minliq=1000&period=1d
- Query Historical Net Worth for Multiple Wallets Across Multiple Chains
curl -X GET https://demo-api.mobula.io/api/1/wallet/history?wallets=0x6b114A6bCACEDE76A714d251949fAaC5ac3245A8,4X2FZ9PqrjRPRRxSConh1r8eQarEwrrMtXLkzhA1J4E9&blockchains=1,8453,42161,10,59144,56,137,43114,81457,169,34443,solana,1030,4200&from=1739878441921&period=1h&unlistedAssets=true&accuracy=maximum
Response Format
The response contains the wallet addresses, current balance, and a time series of historical balances.| Field | Type | Description |
|---|---|---|
wallets | string[] | List of queried wallet addresses |
balance_usd | number | Current total balance in USD |
balance_history | [number, number][] | Array of [timestamp_ms, balance_usd] tuples representing the historical net worth |
backfill_status | string | Transfer backfill status: processed, processing, or pending (only present when backfillTransfers=true) |
Sample Response
{
"data": {
"wallets": ["0x6b114A6bCACEDE76A714d251949fAaC5ac3245A8"],
"balance_usd": 15420.55,
"balance_history": [
[1739878441921, 14200.30],
[1739882041921, 14350.80],
[1739885641921, 14500.10],
[1739889241921, 14800.55],
[1739892841921, 15100.20],
[1739896441921, 15420.55]
],
"backfill_status": "processed"
}
}
Query Parameters
Wallet address
Comma-separated wallet addresses
Comma-separated blockchain IDs
Start date
End date
Include unlisted assets
Baseline granularity of the history grid (5min, 15min, 1h, 6h, 1d, 7d). Sets the minimum spacing between grid points, NOT a hard cap on the number of points: the response also adds one point per balance-changing transfer, so total points ≈ (to-from)/period + number of transfers.
Data accuracy level
Include testnet data
Minimum liquidity threshold
Filter spam tokens
Response
200 - application/json
Wallet history response
Show child attributes
Show child attributes