Skip to main content
Errors return a JSON body with a human-readable error and a stable machine-readable code.
Branch on code. The error string is written for humans and may be reworded.

Codes

Running out of credits

Every metered endpoint checks your match balance before it runs. The free endpoints, /v1/stats, /v1/usage, /v1/estimate and the job status poll, skip the refusal and answer at any balance, so a drained key can always read its own meter, estimate its next list, and collect the results of a job it already paid for; that reading is the signal to top up. On a metered endpoint with nothing left, the call returns 402 with one of two error strings, depending on whether you are spending the free allowance or a pack:
The free allowance is 100 matches per rolling 30 days. A pack adds a balance that lasts 12 months, and the API draws on it exactly as the app does. Both strings carry both remedies. A person buys a pack at walletlink.social/pricing; an agent holding a wallet buys credits with USDC over x402, no account, at POST https://walletlink.social/api/x402/buy. See the agent pack.

Things that are not errors

Two cases return HTTP 200 and are easy to mistake for failures. A wallet with no identities. data: null, meta.found: false. The lookup succeeded and the answer is that there is nothing attached. See found, missing, and checked. A reverse lookup with no matches. data: [], meta.total_count: 0.

Retrying

SERVICE_UNAVAILABLE and INTERNAL_ERROR are worth retrying with exponential backoff. RATE_LIMIT_EXCEEDED is worth retrying once the window resets. A retried request bills again, because a retry is a second resolution. The exception is a batch resent with the same Idempotency-Key: inside the 24-hour window it replays the stored response, marked Idempotency-Replayed: true, and bills nothing. Send the header on any batch you might have to retry. A job resubmission is refused with JOB_ALREADY_ACTIVE while the original runs, so a job cannot double-run by accident; resubmitted after completion, it runs the whole list again and bills again. Poll before resubmitting. NO_CREDITS is not worth retrying. It clears when you buy a pack, or when the free window rolls forward. Nothing in the 400 family is worth retrying. The request is malformed and will fail identically until you change it. BATCH_SIZE_EXCEEDED is the exception in spirit: split the batch and retry the pieces. 401 means the key is wrong. Retrying will not fix it and repeated failures are a good way to look like an attack.