Usage
curl --request GET \
--url https://walletlink.social/api/v1/usageimport requests
url = "https://walletlink.social/api/v1/usage"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://walletlink.social/api/v1/usage', 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/usage",
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/usage"
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/usage")
.asString();require 'uri'
require 'net/http'
url = URI("https://walletlink.social/api/v1/usage")
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": {
"key": {},
"plan_limits": {},
"rate_limits": {},
"credits": {},
"usage": {}
}
}Account
Usage
GET /v1/usage
GET
/
api
/
v1
/
usage
Usage
curl --request GET \
--url https://walletlink.social/api/v1/usageimport requests
url = "https://walletlink.social/api/v1/usage"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://walletlink.social/api/v1/usage', 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/usage",
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/usage"
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/usage")
.asString();require 'uri'
require 'net/http'
url = URI("https://walletlink.social/api/v1/usage")
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": {
"key": {},
"plan_limits": {},
"rate_limits": {},
"credits": {},
"usage": {}
}
}Reports your key’s plan, current rate limit state, consumption history, and your remaining match credits. Costs no credits.
Because it costs nothing and reports all three rate limit windows and your match balance at once, this is the right endpoint to poll from a dashboard or to check before starting a large job.
It does not need a balance. A key whose credits are at zero can still call this endpoint and read the zero for itself; that reading is the signal to top up, and refusing it here would lock a drained agent out of its own meter. Only the metered endpoints return
402 NO_CREDITS.
Query parameters
string
default:"month"
Window for the usage figures. One of
day, week, month. Anything else
returns INVALID_PARAMETER.Request
curl "https://walletlink.social/api/v1/usage?period=week" \
-H "Authorization: Bearer wts_live_YOUR_KEY"
Response
object
Show properties
Show properties
object
id, name, prefix, plan, created_at, last_used_at. Only the
prefix is shown, never the key.object
requests_per_minute, requests_per_day, requests_per_month,
max_batch_size. A window with no ceiling is the string "unlimited"
rather than a number; no pack has one today.object
Current state of the
minute, day and month windows, each with
limit, remaining and reset_at. A window can be null if it has not
been exercised yet.object
Your match credit balance, the same one the app spends.
available is the
number of matches left, or null when the account is not metered.
unmetered is true on accounts that are never debited.
on_free_allowance is true when you hold no live pack and are spending
the free 100 matches per rolling 30 days. free_window_resets_at is when
the next free match comes back, as an ISO 8601 timestamp, or null when
it does not apply.object
period, total_requests, total_credits, total_wallets,
avg_latency_ms, error_rate as a percentage, plus
requests_by_endpoint and requests_by_day breakdowns. total_credits
counts rate-limit units, not match credits.requests_by_endpoint is an object keyed by route template.
requests_by_day is an array, ascending, of { date, count, credits }.{
"data": {
"key": {
"id": "key_123",
"name": "production",
"prefix": "wts_live_ab",
"plan": "Developer",
"created_at": "2026-06-01T00:00:00.000Z",
"last_used_at": "2026-08-14T11:58:00.000Z"
},
"plan_limits": {
"requests_per_minute": 60,
"requests_per_day": 5000,
"requests_per_month": 50000,
"max_batch_size": 50
},
"rate_limits": {
"minute": {
"limit": 60,
"remaining": 58,
"reset_at": "2026-08-14T12:01:00.000Z"
},
"day": {
"limit": 5000,
"remaining": 4310,
"reset_at": "2026-08-15T00:00:00.000Z"
},
"month": {
"limit": 50000,
"remaining": 46120,
"reset_at": "2026-09-01T00:00:00.000Z"
}
},
"credits": {
"available": 1180,
"unmetered": false,
"on_free_allowance": false,
"free_window_resets_at": null
},
"usage": {
"period": "week",
"total_requests": 412,
"total_credits": 3880,
"total_wallets": 3860,
"avg_latency_ms": 74,
"error_rate": 0.24,
"requests_by_endpoint": {
"/v1/batch": 380,
"/v1/wallet/{address}": 31
},
"requests_by_day": [
{ "date": "2026-08-13", "count": 210, "credits": 1980 },
{ "date": "2026-08-14", "count": 202, "credits": 1900 }
]
}
},
"meta": { "generated_at": "2026-08-14T12:00:00.000Z" }
}
Notes
plan reports the rate-limit preset currently serving this account, not the pack you bought: Developer by default, Startup while a Scale pack is unexpired, Enterprise while an Index pack is. See plans.
total_credits counts rate-limit units, not match credits, and it is not your bill: a 50-wallet batch is one request and 50 rate-limit units, while what it costs you is one match credit per wallet that resolved. total_credits exceeding total_requests is expected. For what you have left to spend, read credits.available.
error_rate is already a percentage. 0.24 means 0.24%, not 24%.
plan_limits can carry the string "unlimited" instead of a number on a custom plan with no ceiling in a given window. Nothing issued today does, but parse defensively.
requests_by_endpoint is keyed by route template, so single-wallet and reverse
lookups each stay one entry (/v1/wallet/{address},
/v1/reverse/twitter/{handle}, /v1/reverse/farcaster/{username}). The object
holds at most one key per route, whatever the volume. The addresses and handles
you looked up are not stored and never appear here.
Calls made through the MCP server appear under these same keys. The
tools carry your key into the same handlers, so a tool call is recorded as the
endpoint it actually used, and there is no separate MCP entry to reconcile.
Requests made before 2026-08-22 were keyed by the concrete request path. That
history has been rewritten to the templates, so a period that spans the change
still aggregates correctly.
Errors
INVALID_PARAMETER, plus the standard errors.