REST API
Every endpoint that answers today, what it returns, and the ones that are specified but not built.
Argued in full in the whitepaper at §11, Layer 2.
Base URL and auth#
export API=https://dapp.cleaton.xyz/api/v1
curl -s "$API/pool/0xbeeff033f34c046626b8d0a041844c5d1a5409dd"No key, no header, no account. Every read below is free and unauthenticated, and stays that way: a record only its author can audit is not a record. Keys exist, but only for the endpoints that write — see below.
Reading a pool#
| Method | Path | Returns |
|---|---|---|
| GET | /pool/{pool} | The current attestation, with its signature |
| GET | /pool/{pool}/history | Every attestation ever published for that pool |
| POST | /verify | Recovers the signer from a signed attestation |
| GET | /attester | The signing address and scheme to check against |
| GET | /analyze | Where a pool's yield comes from: fees or emissions |
{pool} takes a bare address or a full pool key. An address is only unique within a chain — the same contract exists at the same address on several — so a bare address that matches more than one pool returns ambiguous with the keys to choose between, rather than silently picking one.
{
"pool": "0xbeeff033f34c046626b8d0a041844c5d1a5409dd",
"chainId": 4663,
"poolKey": "4663:0xbeeff033f34c046626b8d0a041844c5d1a5409dd",
"symbol": "steakUSDG/USDG",
"protocol": "Morpho",
"horizon": 90,
"confidence": "0.65",
"issuedAt": 1787325423,
"expiry": 1787411823,
"expired": false,
"outcome": "pending",
"signature": "0xd810beb6...4f201b",
"attester": "0xb6486340a930e21b7ee505111188e929120d9eda",
"signed": true,
"sample": false
}confidence is a decimal string, not a number. It is part of the canonical payload the signature covers, and a float has no canonical decimal form across languages — so it travels as text and is compared as text.
The liquidity map#
Cleaton measures four things about a pool, and this is the endpoint that returns them at once: depth (how much is there, how much of it is standing on emissions, how much survives the durability discount), durability (the signed horizon, or the incentive share of yield when no horizon stands), movement (what the depth has done across the stored days), and exitability (how much can actually leave, stated only where it is exact). The rollup returns exitability under its own exit key; the per-pool profile reports it inside depth.
| Method | Path | Returns |
|---|---|---|
| GET | /intel | The four dimensions rolled up over every tracked pool, plus a per-chain split and what moved |
| GET | /intel/{pool} | One pool's depth, durability and movement, with its own gaps named — exitability sits inside depth here rather than as its own key |
Both take ?days= for the history window. An address that names a pool on more than one chain answers 300 with the candidate keys rather than picking one; pass the full {chainId}:{address} key to disambiguate.
Exit capacity, and where the numbers come from#
depth.availableUsd and depth.utilisation answer how much can actually leave right now — and they are null for everything except a lending market. That is the answer, not a gap. For an AMM, exit impact needs reserves and curve maths per protocol; for a vault it is whatever the strategy can unwind. For a lending market it is supplied − borrowed in the loan asset: exact, with no model. One number spanning all three would be a category error.
utilisationis null when nothing is supplied. Zero over zero is not “0% used” — it is a market nobody has lent into.
The public record#
| Method | Path | Returns |
|---|---|---|
| GET | /scoreboard | The accuracy record: totals, outcomes, calibration buckets |
| GET | /dtvl | Durability-weighted TVL per pool and per chain |
| GET | /calendar | Every observed campaign expiry on one forward timeline |
| GET | /challenges | Breach cases opened against published attestations |
| GET | /chain | Whether Cleaton can read the chain right now, and at which block |
/scoreboard takes ?limit= (1–500). /dtvl takes ?chainId=. /calendar takes ?withinDays=. /analyze takes ?q= — a pool key, a token address, a ticker or an asset class.
Batch#
Score a whole book in one round trip.
curl -s "$API/batch" \
-H "Content-Type: application/json" \
-d '{"pools": ["0xbeeff033...5409dd", "0x0000...0001"]}'{
"found": 1,
"missing": ["0x0000000000000000000000000000000000000001"],
"invalid": [],
"ambiguous": {},
"attestations": { "0xbeeff033...5409dd": { /* as above */ } }
}The four buckets are the point. A position Cleaton has never scored is not an error and is not a pass — it is the one nobody is watching, and it is returned separately so it cannot be mistaken for either.
Writing#
These take Authorization: Bearer clt_…, issued from the dapp. They spend third-party quota or write to the public record, which is what the key is for — it is not a paywall on reading.
| Method | Path | For |
|---|---|---|
| POST | /score | Submit observed signals and have them scored |
| POST | /attestations | Submit a pre-scored attestation |
| POST | /checkpoints | Submit a liquidity observation for breach testing |
| POST | /challenges | Open a challenge against an attestation |
| POST | /chain/measure | Measure balances on chain at a pinned block |
| POST | /ingest/run | Trigger an ingestion pass |
Specified, not built#
These appear in whitepaper §11 and in the surface list, and they do not answer yet. They are named here rather than omitted, because a reference that quietly lists only what works cannot be used to tell what is coming.
| Surface | Path it will take | Blocked on |
|---|---|---|
| 17 — Survival curve | /pool/{pool}/curve | The scorer returns a scalar horizon today, not S(t) |
| 24 — Counterfactual | /counterfactual | Needs the survival ensemble, same as the curve |
| 25 — Emission efficiency | /campaign/{id}/efficiency | Computed and shown on the calendar; no endpoint of its own yet |
| 18 — Webhooks | /webhooks | Subscriptions are configured in the dapp; no REST surface yet |
| 21 — Backtest | /backtest | Needs resolved outcomes, of which there are none yet |
Metering#
| Surface | Metering |
|---|---|
| Everything above marked free | Free today, and unmetered by design where §11 says so |
| On-chain read of a committed attestation | Free — gas is the only cost |
| Fresh signed attestation | Per request: the computation is the cost |
| Batch scan | Per pool |
| Historical / backtest | Per-query tier |
| Webhook subscription | Per pool-month |
| Agent (MCP) call | Per call, prepaid or x402 |