Index stats
curl --request GET \
--url https://walletlink.social/api/v1/statsimport requests
url = "https://walletlink.social/api/v1/stats"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://walletlink.social/api/v1/stats', 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://walletlink.social/api/v1/stats",
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://walletlink.social/api/v1/stats"
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://walletlink.social/api/v1/stats")
.asString();require 'uri'
require 'net/http'
url = URI("https://walletlink.social/api/v1/stats")
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": {
"total_wallets": 123,
"wallets_checked": 123,
"coverage": {},
"farcaster_stats": {},
"match_rates": {}
}
}Account
Index stats
GET /v1/stats
GET
/
api
/
v1
/
stats
Index stats
curl --request GET \
--url https://walletlink.social/api/v1/statsimport requests
url = "https://walletlink.social/api/v1/stats"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://walletlink.social/api/v1/stats', 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://walletlink.social/api/v1/stats",
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://walletlink.social/api/v1/stats"
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://walletlink.social/api/v1/stats")
.asString();require 'uri'
require 'net/http'
url = URI("https://walletlink.social/api/v1/stats")
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": {
"total_wallets": 123,
"wallets_checked": 123,
"coverage": {},
"farcaster_stats": {},
"match_rates": {}
}
}Totals for the whole index, refreshed daily. Costs no credits and needs a valid key, not a balance: this endpoint answers even when your credits are at zero, so an exhausted key can still plan its next purchase. Only the metered endpoints return
402 NO_CREDITS.
The counts are materialized once a day rather than counted live, and meta.as_of says when they were taken. Poll it as often as you like; two calls inside a day return the same numbers.
Use it to check coverage claims for yourself rather than trusting a number on a marketing page, and to monitor whether the index is growing in the dimension you care about.
Request
curl https://walletlink.social/api/v1/stats \
-H "Authorization: Bearer wts_live_YOUR_KEY"
Response
object
Show properties
Show properties
number
Wallets with at least one identity attached. This is the coverage number.
number
Every wallet we have examined, including those we found nothing for.
object
Counts per network:
twitter, farcaster, ens, lens, github. These
overlap, since one wallet can carry several.object
avg_followers and max_followers across indexed Farcaster accounts.object
The measured per-chain match rates:
measured_on, basis,
overall_either_pct, and by_chain rows each carrying collections,
holders, farcaster_pct, x_pct and either_pct. Constants from a
dated measurement, not live counts; see below.{
"data": {
"total_wallets": 4700000,
"wallets_checked": 9200000,
"coverage": {
"twitter": 1070000,
"farcaster": 4690000,
"ens": 890000,
"lens": 42000,
"github": 31000
},
"farcaster_stats": { "avg_followers": 210, "max_followers": 1200000 },
"match_rates": {
"measured_on": "2026-08-17",
"basis": "Measured across 26 real collections and 72,318 holders, against the index alone. The chain decides this more than anything else about a collection; use the row for your chain, not the overall figure.",
"overall_either_pct": 30.8,
"by_chain": {
"base": {
"collections": 8,
"holders": 35294,
"farcaster_pct": 44.4,
"x_pct": 32.1,
"either_pct": 46.2
},
"ethereum": {
"collections": 9,
"holders": 17462,
"farcaster_pct": 12.2,
"x_pct": 12.6,
"either_pct": 16.6
},
"robinhood": {
"collections": 9,
"holders": 19562,
"farcaster_pct": 11.5,
"x_pct": 12.2,
"either_pct": 15.6
}
}
}
},
"meta": {
"generated_at": "2026-08-14T12:00:00.000Z",
"as_of": "2026-08-14T04:30:00.000Z"
}
}
meta.as_of is when the counts were computed; meta.generated_at is when this
response was built. Read as_of when you quote a number.
The counts above are illustrative; call the endpoint for real ones. The
match_rates block is the real measured table.The match-rate table
match_rates is different in kind from the counts around it: a dated
measurement of 26 real collections against the index, served as constants so
an agent can plan a spend at decision time instead of reading
coverage. The chain decides a list’s match rate more
than anything else about it, several-fold between Ethereum and Base, so use
by_chain and the row for your chain; overall_either_pct describes no
collection in particular. either_pct is the planning number: the share of
holders with an X or Farcaster account, which is exactly what
bills. Pair it with
POST /v1/estimate, which reports what your
specific list would bill.
Reading the two totals
total_wallets and wallets_checked are different questions and the gap between them is the point.
wallets_checked includes wallets we examined and found nothing for. Those are deliberately excluded from total_wallets, so that dividing one by the other gives a real hit rate rather than one inflated by counting empty records as coverage.
Do not compute a match rate for your list from these numbers. The index skews toward wallets somebody has already looked up, which is not a random sample of the chain. For your own list, sample it through batch and measure directly. See coverage.