# Vet a counterparty

Check a stranger's real payment history before you pay them, in one second and for nothing.

Section: Guides
Source: https://www.roundhouse.studio/docs/guides/vet-a-counterparty

---

The reason to index payments is so that paying a stranger stops being a guess. These are the checks,
the queries behind them, and what each answer is actually worth.

All of it is free and takes a second.

## The problem, stated precisely

An agent about to pay another agent has one decision — pay or do not pay — and almost no information.
What is available is public and cheap: a wallet address, possibly a registration, possibly a card, and
whatever the chain has recorded. What is *not* available is anything resembling a legal identity, a
contract, or recourse.

So the honest framing is not "who is this agent". It is **"what is the expected cost of being
wrong"**, and the goal is to make that cost bounded and informed rather than unknown.

Two temptations to resist:

- **Treating a registration as a credential.** Anyone can register, and anyone can write anything in a
  card. The only proven fact is that a wallet signed it.
- **Treating absence of history as evidence of fraud.** Most wallets transacting today have never
  registered, and every legitimate service was new once.

## The one distinction that matters

**A listing is a claim. A settlement is evidence.**

A catalog entry costs nothing to create: any price, any description, any name. A distinct payer over
time costs real money to manufacture. So when the two disagree, believe the ledger.

Every check below is an application of that.

## Check 1 — is anyone paying them?

```bash
curl -sL "https://www.roundhouse.studio/api/v0/merchants/<payTo>" | jq
```

Look at three things, in this order:

| Field | Reading it |
| --- | --- |
| Distinct payers | The strongest signal. One payer could be the operator; twenty are customers |
| Last settlement | A service last paid in March is not a service |
| Volume | Weakest of the three — one large payer inflates it |

Distinct payers over a period beats total volume every time, because volume is the easiest of the
three to manufacture with your own wallets.

## Check 2 — is the endpoint alive, and honest about its price?

```bash
curl -sL "https://www.roundhouse.studio/api/v0/endpoints?q=<service>" | jq \
  '.endpoints[] | {service_name, resource, price_usdc, pay_to, is_live, http_status, last_indexed_at, l30_unique_payers}'
```

- `is_live: false` — an external probe could not reach it. Do not pay.
- `last_indexed_at` much older than about forty minutes — probably dropped from the upstream catalog.
  Stale rows are [not yet pruned](https://www.roundhouse.studio/docs/guides/get-listed-as-a-merchant#known-limitation-stale-rows).
- `price_usdc` far from what has actually been paid — read the live `402` rather than trusting either.

## Check 3 — does the identity hold together?

Only if they claim one:

```bash
curl -sL "https://www.roundhouse.studio/api/v0/agents/<payTo>" \
  | jq '.erc8004_agents[] | {chain_id, agent_id, agent_wallet, score}'
```

The check is **consistency**: does the registry's wallet match the `payTo` you were quoted? A
mismatch is the interesting case — it may be legitimate (a separate payment address) or it may be
someone else's card attached to their address.

Remember what this proves and does not. A registration proves a wallet signed a document. It does not
prove competence, and its absence proves almost nothing — most wallets transacting today have never
registered.

## Check 4 — what does the reputation say?

```bash
curl -sL "https://www.roundhouse.studio/api/v0/agents/<agentId>/feedback" | jq
```

Weakest of the four, deliberately discounted in the [trust score](https://www.roundhouse.studio/docs/identity/trust-and-reputation),
and worth reading for *content* rather than for the number — a dispute in the feedback history tells
you something an aggregate cannot.

`score: null` means **unknown, not bad**.

## The queries behind it

When the endpoints do not cut it, ask directly.

**Repeat customers — the single best quality proxy.** Anyone can buy once; people come back to things
that work.

```sql
select count(*) as payers,
       count(*) filter (where n > 1) as repeat_payers,
       round(100.0 * count(*) filter (where n > 1) / nullif(count(*), 0), 1) as repeat_pct
from (
  select payer, count(*) as n
  from settlements
  where payee = lower('0xTheirWallet')
    and block_time > now() - interval '90 days'
  group by payer
) t
```

**Is the trend up or down?**

```sql
select day, settlements, usd
from mv_entity_daily
where wallet = lower('0xTheirWallet')
order by day desc
limit 30
```

**What are they actually being paid for?**

```sql
select e.service_name, e.resource, count(*) as calls, count(distinct s.payer) as payers
from settlements s
join external_resources e on e.pay_to = s.payee
where s.payee = lower('0xTheirWallet')
  and s.block_time > now() - interval '30 days'
group by 1, 2
order by calls desc
```

**Proven, not merely probable.** A settlement with `verified_x402 = true` carries an on-chain EIP-3009
marker; without the filter you are counting rows that may be ordinary transfers.

```sql
select count(*) as all_rows,
       count(*) filter (where verified_x402) as proven
from settlements
where payee = lower('0xTheirWallet')
  and block_time > now() - interval '90 days'
```

## Reading absence

This is where judgement is needed, so here is the position rather than a rule.

Absence of history means one of: brand new, low volume, paid off-chain, or paid on a chain we do not
index. Only the first two are common. None of them is evidence of fraud.

A reasonable response to absence is **a bounded first payment** rather than a refusal: cap the
exposure, transact, and let the record accumulate. Declining every counterparty without history also
declines every new entrant, including the legitimate ones.

What *is* a refusal, regardless of history: a `402` naming a scheme, network or asset your client does
not implement. That is not a risk assessment, it is a capability mismatch.

## A policy you can implement

Not advice about your risk appetite — a shape. The tiers are what a
[wallet policy](https://www.roundhouse.studio/docs/guides/set-up-an-agent) can actually enforce.

| Tier | Checks | Cap |
| --- | --- | --- |
| Routine | Endpoint is live; scheme, asset and network recognised | Whatever a call is worth |
| Elevated | Above, plus non-zero distinct payers over 30 days | Bounded per counterparty per day |
| High | Above, plus consistent identity, plus feedback history read | Explicit, per payment |
| Never | Unrecognised asset, network or scheme, whatever else checks out | — |

The summary of the whole page: **an identity is necessary but not sufficient, and payment history is
strong evidence that new counterparties cannot have yet.** Without an identity there is nothing to
accumulate reputation against, but an identity alone establishes only that a wallet signed a name. A
settlement record is hard to fabricate, which makes it the strongest signal available — and it is one
every new entrant starts without. Hence the bounded first payment.

## Hand it to an agent

```prompt
Vet this counterparty before I pay them. Report each check with the evidence,
then a recommendation.

payTo: <0x…>
Service: <name or URL>
Proposed payment: <$…>

1. GET /api/v0/merchants/<payTo> — distinct payers, last settlement, volume.
2. GET /api/v0/endpoints?q=<service> — is_live, http_status, last_indexed_at,
   listed price versus what has actually been paid.
3. GET /api/v0/agents/<payTo> and read erc8004_agents — which registry entries
   claim this wallet? If they claimed an agentId, check it is one of them and
   that its chain matches. Flag any mismatch.
4. Using POST /api/v0/sql, compute the 90-day repeat-payer percentage and the
   proportion of their settlements with verified_x402 = true.
5. Fetch their 402 live and confirm the scheme, network and asset are ones I can
   pay.

Recommend one of: proceed, proceed with a cap (say what cap), or refuse — and
name the single check that decided it. Absence of history is a reason for a cap,
not a refusal.
```

## Next steps

- [The KYA memo](https://www.roundhouse.studio/docs/identity/kya) — what a counterparty can sign and commit to
- [SQL over the index](https://www.roundhouse.studio/docs/data/sql) — more query shapes
- [Coverage and confidence](https://www.roundhouse.studio/docs/data/coverage-and-confidence) — how much we can see

---

Every page in these docs is available as markdown at its own URL plus `.md`.
Full index: https://www.roundhouse.studio/docs.md
