Skip to main content
An agent can call walletlink.social directly, without a human first reading this reference. The server is remote, and takes either an OAuth connection or the same key the REST API uses.

Connect

Sign in, from a client that supports OAuth

Add the URL above as a connector and the client does the rest. There is no key to create, copy or paste: the first tool call opens a consent screen, you sign in with your email, approve, and the call continues where it left off. This is the shortest path in Claude, Claude Code and anything else that follows the MCP authorization specification, and it is the one to prefer. A connection carries no long-lived secret anywhere: access is a token that lasts an hour and renews itself, and disconnecting is immediate. The server registers clients two ways, so nothing needs arranging in advance:
  • Client ID metadata documents, which is what Claude and Claude Code use
  • Dynamic client registration (RFC 7591), at https://walletlink.social/api/oauth/register, for clients that do not publish a metadata document
Both register as public clients, so PKCE with S256 is required and no client secret is issued. Discovery starts at /.well-known/oauth-protected-resource.
A connection can spend match credits, so it is worth knowing what it can reach. It can resolve wallets in both directions, run a background job, and read your credit balance. It cannot see your saved lookups, your billing details or your email address, and it cannot buy credits or change anything about your account.

Disconnect

Account menu > API keys > Connected applications, then Disconnect. It takes effect on the next call, not at the end of the hour: the access token is revoked along with the connection, and the refresh token that would have renewed it stops working at the same moment.

One click, from the app

When you create an API key, the modal offers Add to Cursor and Copy Claude Code command, both already carrying that key. That is the shortest path, and it is only offered there: a key is shown exactly once, so a link published on this page could only carry a placeholder, and a placeholder installs a server that fails on first use.

Claude Code, one line

That installs it for the current project. Add -s user to make it available in every project instead.

From Grok

The official walletlink plugin for Grok lives at github.com/starl3xx/walletlink-grok-plugin. It points Grok Build at this server and ships a skill covering tool selection, cost and result semantics. The plugin itself carries no credential. Use an API key here, not OAuth. The chat host cannot open a consent screen and reports no_auth_link, so an OAuth connection can never complete however many times it is retried. Create a key from the account menu and paste it into the connector’s key field.

By hand

Add the server to your client’s config. The key goes in an Authorization header, exactly as it does for the REST API.
Keys are self-serve from the account menu for any signed-in account, including one on the free allowance.
Discovery works without a credential. A client can connect and list the tools with no Authorization header at all, so you can see what is on offer before buying anything. Calling a tool needs one.

Which to use

An OAuth connection is better for a person using a client. A key is better for a server you run yourself, where there is no browser to sign in with.
Some chat hosts cannot do OAuth at all, and a key is the only way in. A connector running inside a chat app may have no way to open a consent screen; X and Grok report no_auth_link when asked to. The symptom is a connector that lists all eight tools happily, because discovery needs no credential, and then reports that it still needs to sign in however many times you authorize. If you see that, stop retrying the connection and paste a key instead.

The skill file

Some agents install a capability from a URL rather than a config block. Give them this one:
It carries the whole contract: the tools, what each costs, how to authenticate, and how to read a result. It contains no key, so it is safe to paste anywhere, and it is generated from the same constants as this page, so the prices and coverage figures in it are the ones actually charged and claimed.

The eight tools

Nine endpoints become eight tools because the single and batch lookups answer the same question at two sizes and bill by the same rule. walletlink_resolve_wallets takes 1 address up to your plan’s batch ceiling (50 on the default plan; a live Scale or Index pack raises it, see plans) and picks the endpoint for you. walletlink_estimate_list is the dry run: counts of what is in the index and the band a resolve would bill inside, free at any balance, weighed against the rate window like the batch it previews. Have an agent call it before spending on an unknown list. walletlink_submit_job is the async surface: it submits a background job that resolves wallets the index has not checked against live sources, so it can find identities the resolve tool reports as never seen. One job may be active per account at a time, a submission is capped at 10 times the match balance, and the matches are billed when the job completes, at the same price as resolving. walletlink_job_status polls it for free on both meters and shows the first 100 result rows; the full set is one free REST call away on the same key.

It is the same meter

The tools carry your key into the same handlers the REST API uses, so nothing about billing changes. Misses are free, a match means an X handle or a Farcaster account, and an ENS name on its own is returned and not charged. See credits. Three consequences worth knowing before you point an agent at it: A reverse lookup can spend 100 credits in one call. A page holds up to 100 wallets and each one is a match. The free allowance is 100 matches per rolling 30 days, so a single widely held handle can spend all of it at once. There is no page-size parameter. Have the agent call walletlink_account_balance first, which is free. A batch spends its size in rate limit. A batch call spends one request-unit per address of the per-minute window, and a full batch fills most of a minute on every plan (60 units and 50-address batches on the default plan; a live Scale or Index pack raises both), so a second full batch inside the same minute is refused. Pace multi-batch runs a minute apart and read the reset time from quota. Nothing is reserved. The balance is checked, not held, so a call that resolves more than you have left is allowed to finish and the next one fails with no credits. That is the same behavior the REST API and the app have. A retry is a second purchase. The debit is keyed on the call, so a tool call resent by a retrying framework bills its matches again; the tools declare idempotentHint: false for exactly this reason. A tool call cannot carry an idempotency key; the REST batch endpoint can, so a pipeline that must retry safely should call REST with an Idempotency-Key header instead. A job submission is half-covered on its own: a resend while the job runs is refused with the active id, and only a resend after completion runs and bills again. At zero balance the four free tools keep answering, so a drained agent can always read its own meter and collect a finished job.

What the tools return

Not the raw API record. The 40-odd fields per wallet are trimmed to the identity, whether the owner attested it, and whether the X handle still reaches anyone, which is the field no competing source publishes. A Farcaster identity keeps its fid through the trim, because Farcaster DMs address accounts by fid rather than by username; a username can be renamed out from under a campaign, the fid cannot. Resolved records carry a stale flag when the index has measured their freshness, and a missed address reports previously_checked: a timestamp means we looked and found nothing, null means we have never looked. Absent is not false, at every layer.
attested answers whether the wallet owner published the link themselves. It derives from the record’s evidence classes, the same array evidence shows: a Farcaster verification, an onchain ENS record, an attested-social sign-in, or a manually verified record makes it true; a record resting on correlation alone is false; a record with no classified evidence reports null. Evidence classes are recorded per wallet, so attested reflects the record’s strongest evidence, not each identity separately. It is deliberately not the REST API’s verified flag, which reports false on the majority Farcaster-attested handles: see the verified flags. reaches_someone and reachability are omitted when we have not resolved the handle. Absent is not false: see when a handle stops being true. Every metered tool result carries quota, so an agent learns what its call left without a second call to ask. The balance is the one the call was admitted with, before its own matches were debited: subtract billed_matches to know what remains. The balance key is absent for the legacy unmetered accounts, which have no balance to report; the request counters are always present. walletlink_account_balance still exists for reading the balance without resolving anything.

The REST surface

Everything these tools do is also available over the REST API, described in OpenAPI 3.1 at docs.walletlink.social/openapi.yaml if you would rather generate a client than install a server.

Errors

A failed call comes back as a tool error with a readable message, never as a transport failure, so the session survives and the agent can tell you what went wrong. Out of credits reads as “No credits left. Buy a pack at https://walletlink.social/pricing to continue, or buy one with USDC, no account needed, at POST https://walletlink.social/api/x402/buy.” Authentication is the exception, and deliberately. A tool call arriving with no credential, or with an OAuth access token that has expired or been revoked, is refused with HTTP 401 and a WWW-Authenticate header rather than a tool error. A client reads that as a signal to refresh its token or ask you to sign in, and then retries the same call; a tool error would be handed to the model as text and the turn would move on with nothing fixed. A mistyped API key is not treated that way. It reaches the API and comes back as a tool error saying the key is invalid, which is what somebody who has just pasted one needs to read.

Limits

Tool calls are limited per key, on the same three windows as the REST API. See rate limits. Everything except a tool call is limited per IP address, at 120 requests an hour. That covers initialize, tools/list and every other method, all of which answer without reaching the API and so are not metered against any key. Tool calls are not subject to it. They are metered against your key instead, on the three windows above.