Skip to main content
GET
/
erc20
/
{tokenAddress}
/
holders
/
historical
Get timeseries holders data
curl --request GET \
  --url https://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical \
  --header 'X-API-Key: <api-key>'
import requests

url = "https://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical"

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://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical', 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://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical",
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://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical"

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://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical")
.header("X-API-Key", "<api-key>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://deep-index.moralis.io/api/v2.2/erc20/{tokenAddress}/holders/historical")

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
{
  "result": [
    {
      "timestamp": "2021-05-07T11:08:35.000Z",
      "totalHolders": "100",
      "netHolderChange": 123,
      "holderPercentChange": 123,
      "newHoldersByAcquisition": {
        "swap": "10",
        "transfer": "10",
        "airdrop": "10"
      },
      "holdersIn": {
        "whales": "100",
        "sharks": "100",
        "dolphins": "100",
        "fish": "100",
        "octopus": "100",
        "crabs": "100",
        "shrimps": "100"
      },
      "holdersOut": {
        "whales": "100",
        "sharks": "100",
        "dolphins": "100",
        "fish": "100",
        "octopus": "100",
        "crabs": "100",
        "shrimps": "100"
      }
    }
  ],
  "page": "1",
  "pageSize": "100",
  "cursor": "<string>"
}
Deprecated — scheduled for removal on July 31, 2026. The other two EVM token holder endpoints (holder stats and token holders) remain supported. See the changelog for details and migration guidance.

Authorizations

X-API-Key
string
header
default:test
required

Path Parameters

tokenAddress
string
required

The token address

Example:

"0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0"

Query Parameters

chain
enum<string>
default:eth

The chain to query

Available options:
eth,
0x1,
sepolia,
0xaa36a7,
polygon,
0x89,
bsc,
0x38,
bsc testnet,
0x61,
avalanche,
0xa86a,
cronos,
0x19,
arbitrum,
0xa4b1,
chiliz,
0x15b38,
gnosis,
0x64,
base,
0x2105,
base sepolia,
0x14a34,
optimism,
0xa,
polygon amoy,
0x13882,
linea,
0xe708,
moonbeam,
0x504,
moonriver,
0x505,
flow,
0x2eb,
flow-testnet,
0x221,
ronin,
0x7e4,
ronin-testnet,
0x31769,
lisk,
0x46f,
pulse,
0x171,
sei-testnet,
0x530,
sei,
0x531,
monad,
0x8f
Example:

"eth"

fromDate
string
required

The starting date (format in seconds or datestring accepted by momentjs)

Example:

"2025-01-01T10:00:00"

toDate
string
required

The ending date (format in seconds or datestring accepted by momentjs)

Example:

"2025-02-01T11:00:00"

limit
integer

The number of results to return

Required range: x >= 0
cursor
string

The cursor returned in the previous response (used for getting the next page)

timeFrame
enum<string>
default:1min
required

The time frame to group the data by

Available options:
1min,
5min,
10min,
30min,
1h,
4h,
12h,
1d,
1w,
1m
Example:

"1d"

Response

200 - application/json
object | null

Returns token

result
object[]
required
page
integer

The current page of the result

Example:

"1"

pageSize
integer

The number of results per page

Example:

"100"

cursor
string

The cursor to get to the next page