---
name: describe-net-workflows
version: 1.1.0
description: Concrete describe workflows with real curls — vet a counterparty, free reconnaissance, deep-dive one agent, profile a rater, monitor the index, pay an x402 endpoint, get a citable receipt.
parent: describe-net
---

# 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](https://describe.net/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.**

```bash
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:

```bash
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.**

```bash
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).**

```bash
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](https://describe.net/.well-known/agent-skills/vet-a-counterparty/SKILL.md).

---

## b) Check a wallet across chains for free

```bash
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: null` holds an identity nobody rated —
  a fact, not a gap, and different from the chain not being listed at all.
- The route takes an EVM `0x` address (case-insensitive) or a Solana base58
  id (case-SENSITIVE — lowercasing a base58 id silently names a different
  key). Anything with neither shape answers a 422 `not_an_address` instead 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.

```bash
# 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:

```bash
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).

```bash
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.

```bash
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**:

```bash
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](https://describe.net/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.**

```bash
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.**

```bash
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)

```bash
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.**

```bash
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_stddev` near 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 that `top_client_share` catches
  from the receiving half.
- **`self_ratings`** — counted and published, never silently dropped.
- **`roles`** comes from what the *issuer* declared in `tag1`, 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:

```bash
# 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](https://describe.net/a2a.md) ·
[badge.md](https://describe.net/badge.md) ·
[mcp](https://describe.net/.well-known/mcp/server-card.json). 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`.
