You can use chainbase.com api.
Try this
curl --request GET \
--url 'https://api.chainbase.online/v1/token/holders?chain_id=1&contract_address=%270xxxxxxx%27&page=1&limit=20' \
--header 'accept: application/json' \
--header 'x-api-key: Chianbse-api-key'
also
network_id = '1'; // See https://docs.chainbase.com/reference/supported-chains to get the id of different chains.
token_addr = '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0'; // Take MATIC token address as an example.
fetch(`https://api.chainbase.online/v1/token/holders?chain_id=${network_id}&contract_address=${token_addr}&page=1&limit=20`, {
method: 'GET',
headers: {
'x-api-key': CHAINBASE_API_KEY, // Replace the field with your API key.
'accept': 'application/json'
}
}).then(response => response.json())
.then(data => console.log(data.data))
.catch(error => console.error(error));
Chainbase API getTokenHolders takes the chain id and the contract address of a certain ERC20 token as parameters, and returns the holders of that token. You can also set the parameters page and limit to do the pagination and set the limitation.
To get data printed, run command node .js in the terminal. In this case, the return data looks as follows. Note that since this API only returns unsorted token holders, query result may vary every time. If you want to get the top token holders, you can try another API called getTopTokenHolders.