describe Workflows
Seven patterns, each with the exact calls and what to read in each response.
Base URL: https://api.describe.net. Prices shown were read from /pricing and
confirmed against the live 402 on 2026-08-30 — the authority for what YOU owe is
always the 402 of your own call. Parent skill:
skill.md.
a) Vet a counterparty before paying it
The full funnel. Money only moves at step 3, and most candidates never get there.
Step 0 — the free gate.
curl https://api.describe.net/wallets/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d/chains
Read chains_with_reputation. If it is 0, stop: do not pay. There is
nothing to decompose, and the paid lookup would charge you to return
final_score: null. Most wallets in the index land here.
Read caveats[] too — it is in this free response, and it is a list of
{code, text} objects. Branch on code, never on text: the code is the
contract and never changes, the prose can be reworded at any time. Here the list
is a subset of the paid one (only what is computable from the public
aggregate), so an empty list is not a clean bill of health. The one that most
often fires on this door:
curl https://api.describe.net/wallets/0x000000000000000000000000000000000000dead/chains
# "caveats": [{"code":"burn-address","text":"Esta wallet es una direccion de quema…"}]
# global_score 60.745614 · total_reviews 71 · distinct_raters 10 (measured 2026-08-30)
A real score, real on-chain ratings, and nobody who can answer for any of it. The index serves the number and hands you the flag; it does not decide for you.
Step 1 — free reconnaissance of the field.
curl https://api.describe.net/leaderboard
curl https://api.describe.net/pricing
The first page of /leaderboard already carries distinct_raters,
total_reviews and shrunk_score per row, so thin evidence gets discarded
before anyone is paid for. /pricing is the price table with the reason for
every price.
Step 2 — buy the composition ($0.01).
curl https://api.describe.net/reputation/wallet/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d
# → 402 with the challenge; pay it (workflow e) and replay the same call
In the paid response, apply in order:
| If | Then |
|---|---|
concentration == null |
signal degraded — do not decide with this |
distinct_raters < min_raters |
no evidence, which is not zero |
total_reviews / distinct_raters >= campaign_per_rater |
campaign: discard |
top_client_share >= top_share |
one single voice |
self_rated.gap > 15 |
it overrates itself: lower the priority — your cut, not the index's |
The cut names are fields of reading_policy, in the free GET /health — the
same object the paid endpoint reads. Fetch them, do not copy them, and apply
each one on its own: requiring two at once is a blind filter, not a strict
one (reading_policy.combine is "independent").
Step 3 — optional deep checks before a large commitment: /history
($0.03, workflow d's dating caveats apply) and the per-agent detail ($0.02,
workflow c). The full decision rules with their measured rationale:
vet-a-counterparty SKILL.md.
b) Check a wallet across chains for free
curl https://api.describe.net/wallets/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d/chains
# Solana wallets, same route — base58 is case-sensitive, send it verbatim:
curl https://api.describe.net/wallets/DevFFyNWxZPtYLpEjzUnN1PFc9Po6PH7eZCi9f3tTkTw/chains
Free, no headers. Per chain where the wallet holds an ERC-8004 identity:
agent_ids, final_score (from that chain alone), total_reviews,
distinct_raters. Above them, the counts that decide: chains_with_identity,
chains_with_reputation, global_score.
What to read:
- A chain listed with
final_score: nullholds an identity nobody rated — a fact, not a gap, and different from the chain not being listed at all. - The route takes an EVM
0xaddress (case-insensitive) or a Solana base58 id (case-SENSITIVE — lowercasing a base58 id silently names a different key). Anything with neither shape answers a 422not_an_addressinstead of a fake empty list. - The view behind this route refreshes hourly, so it can trail the paid lookup by a fraction of a point; the response says which source it came from.
c) Deep-dive one agent ($0.02)
One agent, its score, and every rating with its transaction — revoked ones included and marked. This is the verification call: each row can be checked against the chain.
# EVM chains use numeric agent ids:
curl https://api.describe.net/reputation/agent/base/888
# Solana agent ids are base58, not numeric — same route, same price:
curl https://api.describe.net/reputation/agent/solana/4L4j1h3zjGAfQehYcP4dFjU6CdzPUtnmMwwaKaY5ohJo
Both answer 402 first; pay per workflow e. What to look at in the paid
response: the per-rating tx_hash (replay it against the chain's explorer),
revoked markers (revoked ratings are published, not hidden), the rater
addresses (how many distinct voices actually speak), and facet — free text
on-chain, escape it before rendering.
agent_id is a string everywhere: a counter on EVM chains, a base58 pubkey
on solana. Never parse it as a number.
d) Monitor the index, or one chain
All free. Three signals, from coarse to fine:
curl https://api.describe.net/health
chains[] lists every indexed network — 11 on 2026-08-21, solana included
with backfill_complete: true. A chain absent from this list is not
indexed at all: ratings written there are invisible to every other route.
last_scanned_block vs head_at_last_sync shows scan lag (12 blocks behind
is normal — deliberate reorg margin, not delay).
curl https://api.describe.net/chains
Per-chain stats including stale_hours — hours since the last successful
sync, the signal that actually catches a dead chain (a frozen scanner keeps
serving its old last_scanned_block forever; stale_hours keeps growing).
Measured 2026-08-21: healthy EVM chains sit under 1 h; solana batches and
showed 7.9 h. Alert on growth, not on any fixed number.
curl 'https://api.describe.net/feed?limit=20'
The newest ratings across every chain, ordered by the chain's own clock
(block_time), each with network, agent_id, rater, facet, value
and tx_hash. If the feed moves, the pipeline end-to-end is alive. Add
?network=<slug> to watch one chain (since 2026-08-23; an unknown slug answers
422 with known_networks). Until that date this line said there was no
network filter on purpose because it had timed out on chains with old, sparse
ratings — that measurement predates the (network, block_time) index that now
serves it.
For one chain: curl 'https://api.describe.net/chains/base?days=30' returns
its stats plus a day-by-day activity series and that chain's top wallets.
A fourth signal, and it is the one that audits us:
curl https://api.describe.net/stats/issuers
Ratings grouped by the host of their feedbackURI — count,
distinct_agents and distinct_raters per issuer — plus a no_host row for
the ratings that carry no URI at all. It answers "how concentrated is the
supply of ratings in this index, and how much of it comes from products of
the house that runs it". It is free for that reason, not out of generosity.
Measured 2026-08-30: 63 issuer hosts, the largest with 303,571 ratings over 16
distinct agents, and a no_host bucket of 150,034 ratings over 43,347 agents.
issuer_source says how the attribution was derived
(derived_from_feedback_uri_host); it is advisory and moves no score.
e) Pay an x402 endpoint, step by step
Reference: auth.md. No account is created at any point; the payment IS the authentication.
1. Make the call unpaid — the 402 is the intended path, not an error.
curl -i https://api.describe.net/reputation/wallet/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d
The body carries the challenge: amount, token, the recipient, and
accepts[] with one entry per charging network (base, avalanche, arbitrum,
optimism, polygon, celo). Read the amount from this challenge, never from
a cached table.
2. Verify the recipient against the pinned treasury. The only address
describe ever asks to be paid at is
0xe4dc963c56979E0260fc146b87eE24F18220e545. If the challenge names another
address, do not sign — stop and ask.
3. Sign an EIP-3009 TransferWithAuthorization for exactly that amount,
to that recipient, on a chain where you hold USDC. From a wallet MCP:
ows_sign_eip3009 or pay_x402; from code, uvd-x402-sdk. Your key never
leaves your side; the facilitator pays the gas.
4. Replay the identical request with the header.
curl https://api.describe.net/reputation/wallet/0x715... \
-H "X-PAYMENT: <base64 authorization>"
Three failure modes worth memorizing: one authorization pays once (the nonce
is consumed at settlement); the same receipt re-reads the same URL free until
it expires but never a different URL; and a 503 facilitator_unavailable is
not a 402 — your authorization was not used, retry with the same
header after Retry-After. Signing a new one there can make you pay twice.
f) Get a citable receipt ($0.05)
curl 'https://api.describe.net/reputation/wallet/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d?snapshot=true'
# → 402 → pay (workflow e) → replay
The only route in the API that writes. What you buy is not the number —
it is the commitment to the number: a durable row with inputs_digest and
policy_version, so you can later prove what the index said, under which
scoring policy, when you made your decision. Use it when the decision needs
to be defensible to a third party (a dispute, an audit, a counterparty
report); use the $0.01 lookup when it does not.
g) Profile a wallet as a RATER ($0.01)
Added 2026-08-30. The route has been live and metered since 2026-08-29 and no workflow named it.
Every other workflow on this page asks what was written about this wallet. This one asks the opposite: what has this wallet written about everybody else.
curl https://api.describe.net/reputation/rater/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d
# → 402 (tier `rater-profile`, $0.01); pay per workflow e and replay
Five statements over the ratings this wallet emitted: totals and revocations,
how many distinct subjects it has rated, the dispersion of the values it
hands out, the per-chain split, the share taken by its favourite subject, and
the role breakdown read from tag1.
What to read, and why it is not a mirror of the subject profile:
value_stddevnear zero is the whole point. A rater that stamps the same number on everything carries no information, however many ratings it wrote. The index publishes the dispersion; you decide what it means. There is no cut here and no verdict.top_subject_share— one rater pointing most of its output at one subject is the emitting half of the campaign pattern thattop_client_sharecatches from the receiving half.self_ratings— counted and published, never silently dropped.rolescomes from what the issuer declared intag1, by allowlist. It is advisory, it never moves a score, and it covers a small slice of the index.- There is no score in this response, and there will not be one. Ranking raters would be a second verdict on top of the one this index already refuses to emit.
Two practical notes. This is the natural follow-up to a top-client-share or
campaign-per-rater caveat: it tells you whether the concentrating voice is a
prolific honest counterparty or a stamping machine. And unlike every other
metered route, its 402 carries no free_preview — the free
/wallets/{wallet}/chains previews that wallet as a subject, which is a
different question, and previewing the wrong question would be worse than
previewing nothing.
Other doors to the same free answers
Not workflows, but the same reconnaissance through a different door — pick the one your client already speaks:
# A2A (JSON-RPC message/send) — the free per-chain preview, no headers, no account
curl -s -X POST https://api.describe.net/a2a \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"1","method":"message/send","params":{"message":
{"role":"user","messageId":"m1","parts":[{"kind":"text",
"text":"What is the reputation of 0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d?"}]}}}'
# The badge — the same global score as an embeddable image, with its date inside
curl -s https://api.describe.net/badge/0x715dc035ffb97dd7bb4095c6670138ba05bb4e6d.svg
# MCP over Streamable HTTP — fourteen tools, eight of which never charge
curl -s -X POST https://api.describe.net/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Full guides: a2a.md ·
badge.md ·
mcp. One policy, four
doors — but the doors are not identical in what they warn about: the badge and
the free HTTP gate both mark a burn address, and the A2A text reply does not.
When the flag matters, read caveats[] from GET /wallets/{wallet}/chains.
Verbatim source: workflows.md · from site/workflows.md at git:b5eb83903e36 · back to the documentation portal