Reverse Farcaster lookup
curl --request GET \
--url https://walletlink.social/api/v1/reverse/farcaster/{username}import requests
url = "https://walletlink.social/api/v1/reverse/farcaster/{username}"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://walletlink.social/api/v1/reverse/farcaster/{username}', 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/reverse/farcaster/{username}",
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/reverse/farcaster/{username}"
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/reverse/farcaster/{username}")
.asString();require 'uri'
require 'net/http'
url = URI("https://walletlink.social/api/v1/reverse/farcaster/{username}")
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": [
{}
],
"meta": {
"username": "<string>",
"total_count": 123,
"returned_count": 123,
"truncated": true,
"next_cursor": {}
}
}Reverse lookups
Reverse Farcaster lookup
Find every wallet attested to a Farcaster username, for 1 match credit per wallet returned, with a key that belongs to an account.
GET
/
api
/
v1
/
reverse
/
farcaster
/
{username}
Reverse Farcaster lookup
curl --request GET \
--url https://walletlink.social/api/v1/reverse/farcaster/{username}import requests
url = "https://walletlink.social/api/v1/reverse/farcaster/{username}"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://walletlink.social/api/v1/reverse/farcaster/{username}', 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/reverse/farcaster/{username}",
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/reverse/farcaster/{username}"
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/reverse/farcaster/{username}")
.asString();require 'uri'
require 'net/http'
url = URI("https://walletlink.social/api/v1/reverse/farcaster/{username}")
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": [
{}
],
"meta": {
"username": "<string>",
"total_count": 123,
"returned_count": 123,
"truncated": true,
"next_cursor": {}
}
}Finds every wallet attested to a Farcaster username. Costs 1 match credit per wallet returned, 100 per page. A username with no wallets attached costs nothing. Separately, each request weighs 2 units against your rate limit.
Only wallets whose recorded sources are all attested evidence (an onchain record, a Farcaster verification, an owner-signed link) are returned. Sources are recorded per wallet, not per username, so a wallet whose attested link sits beside a correlated source is left out too: we cannot tell which of the two supplied the username. A single-wallet lookup still shows it, with its labels. The total and every page follow the same rule, and an empty result means no such wallet, not that no address is attested anywhere.
This lookup needs a key that belongs to an account. A key bought with USDC and no account resolves addresses but answers this one with
403 ACCOUNT_REQUIRED: turning a username into the wallets behind it is the direction that can find a person, so somebody has to answer for the search.
Like the reverse X lookup, it is a one-time check of which wallets this account has linked to itself, not a way to follow what a person holds over time, which the terms of service forbid.
Because Farcaster coverage is complete, this is the most reliable lookup in the API. An empty result is a statement about attested rows, as above, not a sign that we have not indexed the username yet.
Path parameters
string
required
1 to 32 characters of letters, numbers, dots and hyphens, starting with a letter or a number. Input is lowercased before matching.Both kinds of Farcaster name work: a plain fname such as
dwr, and an ENS name attached to the account such as vitalik.eth. A large share of the index is .eth names, so pass them through unchanged rather than stripping the suffix.Query parameters
string
Continues a paginated result: pass the
next_cursor value from the previous
response, unmodified. Omit it for the first page. A value this API did not
produce returns INVALID_CURSOR.Request
curl https://walletlink.social/api/v1/reverse/farcaster/dwr \
-H "Authorization: Bearer wts_live_YOUR_KEY"
Response
Identical in shape to the reverse X lookup, withfarcaster always present instead of twitter, and meta.username instead of meta.handle.
array
Matching wallets, at most 100 per page, ordered by Farcaster reach (highest
follower count first, wallets without one last, wallet address as the
tiebreak).
object
{
"data": [
{
"wallet": "0x00000000000000000000000000000000000000a1",
"ens_name": "example.eth",
"farcaster": {
"username": "example",
"url": "https://warpcast.com/example",
"followers": 123456,
"fid": 900001,
"verified": true
},
"sources": ["farcaster"],
"quality_score": 65
}
],
"meta": {
"username": "example",
"total_count": 1,
"returned_count": 1,
"truncated": false,
"next_cursor": null
}
}
Several wallets per account
Multiple results are the normal case here, more so than on X. A Farcaster account has one custody address plus any number of verified addresses, and all of them are indexed. A single active account returning three or four wallets is unremarkable. The same 100-per-page pagination applies. See one handle, many wallets.Errors
INVALID_USERNAME, INVALID_CURSOR, plus the standard errors.