Assert a price answer

Check the number before you ship it. Most of what agents pay for in the Bazaar is data and finance: a price, a quote, a balance. The answer an agent writes from a feed is where the number goes wrong, rounded, stale, or copied from the wrong field, and nobody downstream can tell. assert checks the written answer against the feed’s own text: the JSON shape, the number in a sane range, the timestamp in ISO form, the quoted figure found verbatim in the source, the URL under the feed’s domain. The feed answer here is a fixed sample (a BTC/USD quote as a price API returns it); the two agent answers are a faithful one and one that rounded the price and wrote “today” for a time.

4calls answered
2receipts re-hashed
3records verified
$0.01list price for a stranger
607ms end to end
pass then partial · 3 records verified

Run 2026-10-11 05:26 UTC against api.s2ar.dev 0.1.1 · 4 calls · 607 ms · list price $0.01 for a stranger (these ran on the operator's key and cost nothing) · every number on this page re-derived by tools/walkthrough.py before it was written

1. The quote: HTTP 402

The price, the rails and the witnesses of this route. The quote costs nothing.

curl -s -X POST 'https://api.s2ar.dev/v1/assert' \
  -H 'X-Assay-Quote: 1' \
  -H 'content-type: application/json' \
  -d '{"text": "{\"symbol\": \"BTC-USD\", \"price\": 67234.51, \"as_of\": \"2026-10-10T14:00:00Z\", \"quote\": \"\\\"usd\\\":67234.51\", \"source_url\": \"https://feed.example.com/v1/price/BTC-USD\"}", "checks": [{"check": "json_valid"}]}'

→ HTTP 402 · 197 ms

price_usd0.005
rails["x402", "credits"]
determinismreplayable
witnesses["checks"]
free.per_day_keyless10
the answer, as JSON
{
  "price_usd": 0.005,
  "rails": [
    "x402",
    "credits"
  ],
  "determinism": "replayable",
  "witnesses": [
    "checks"
  ],
  "free.per_day_keyless": 10
}

2. A faithful answer: five checks, five passes

The shape holds, the price lies in range, the timestamp is ISO 8601, the quoted figure is in the feed’s text word for word, the URL is the feed’s.

curl -s -X POST 'https://api.s2ar.dev/v1/assert' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"text": "{\"symbol\": \"BTC-USD\", \"price\": 67234.51, \"as_of\": \"2026-10-10T14:00:00Z\", \"quote\": \"\\\"usd\\\":67234.51\", \"source_url\": \"https://feed.example.com/v1/price/BTC-USD\"}", "source": "{\"symbol\":\"BTC-USD\",\"price\":{\"usd\":67234.51,\"currency\":\"USD\"},\"as_of\":\"2026-10-10T14:00:00Z\",\"exchange\":\"composite\",\"source\":\"https://feed.example.com/v1/price/BTC-USD\"}", "checks": [{"check": "json_schema", "schema": {"type": "object", "required": ["symbol", "price", "as_of", "quote", "source_url"], "properties": {"symbol": {"type": "string", "pattern": "^[A-Z]{3,5}-[A-Z]{3}$"}, "price": {"type": "number"}, "as_of": {"type": "string"}, "quote": {"type": "string"}, "source_url": {"type": "string"}}}}, {"check": "number_in_range", "path": "price", "min": 1000, "max": 1000000}, {"check": "regex_match", "pattern": "\"as_of\": \"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z\""}, {"check": "quotes_in_source", "path": "quote", "min_words": 1}, {"check": "urls_allowed", "domains": ["feed.example.com"]}]}'

PASS → HTTP 200 · 140 ms · list price $0.005 · receipt sha256:4baf94e59c6d02c0…

verdictpass
passed5
checks5
score1.0
results.1.checknumber_in_range
results.1.evidence{"value": 67234.51, "min": 1000, "max": 1000000}
results.3.checkquotes_in_source
results.3.oktrue
record.kindassertion
record.replayabletrue
record_sha256420f0b00a3bf2cda…
x-assay-record420f0b00a3bf2cda…
the answer, as JSON
{
  "verdict": "pass",
  "passed": 5,
  "checks": 5,
  "score": 1.0,
  "results.1.check": "number_in_range",
  "results.1.evidence": {
    "value": 67234.51,
    "min": 1000,
    "max": 1000000
  },
  "results.3.check": "quotes_in_source",
  "results.3.ok": true,
  "record.kind": "assertion",
  "record.replayable": true,
  "record_sha256": "420f0b00a3bf2cda0b6f4e3a2e0f9ff974cb5fb4d3bba9b08d7b1854a7216c65",
  "x-assay-record": "420f0b00a3bf2cda0b6f4e3a2e0f9ff974cb5fb4d3bba9b08d7b1854a7216c65"
}

Assay badge for record 420f0b00a3bf2cda

re-derived by the generator
✓receipt sha256:4baf94e59c6d02c0… re-derived: sha256 over the canonical answer, header and body agree
✓record 420f0b00a3bf2cda… fetched back from /v1/verify: sealed, signed, and signed by assay-1 (the key at /.well-known/assay.json)
✓as the prose says: verdict = "pass" · passed = 5 · checks = 5

3. A rounded, undated answer: two of five fail

The schema and the range still pass (67000 is a plausible price), the domain passes; the timestamp is not a time and the quoted figure is not in the feed. The record names both.

curl -s -X POST 'https://api.s2ar.dev/v1/assert' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"text": "{\"symbol\": \"BTC-USD\", \"price\": 67000, \"as_of\": \"today\", \"quote\": \"\\\"usd\\\":67000\", \"source_url\": \"https://feed.example.com/v1/price/BTC-USD\"}", "source": "{\"symbol\":\"BTC-USD\",\"price\":{\"usd\":67234.51,\"currency\":\"USD\"},\"as_of\":\"2026-10-10T14:00:00Z\",\"exchange\":\"composite\",\"source\":\"https://feed.example.com/v1/price/BTC-USD\"}", "checks": [{"check": "json_schema", "schema": {"type": "object", "required": ["symbol", "price", "as_of", "quote", "source_url"], "properties": {"symbol": {"type": "string", "pattern": "^[A-Z]{3,5}-[A-Z]{3}$"}, "price": {"type": "number"}, "as_of": {"type": "string"}, "quote": {"type": "string"}, "source_url": {"type": "string"}}}}, {"check": "number_in_range", "path": "price", "min": 1000, "max": 1000000}, {"check": "regex_match", "pattern": "\"as_of\": \"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z\""}, {"check": "quotes_in_source", "path": "quote", "min_words": 1}, {"check": "urls_allowed", "domains": ["feed.example.com"]}]}'

PARTIAL → HTTP 200 · 159 ms · list price $0.005 · receipt sha256:3f27ebdbadb5f553…

verdictpartial
passed3
checks5
results.2.checkregex_match
results.2.okfalse
results.2.evidence{"reason": "no match"}
results.3.checkquotes_in_source
results.3.okfalse
results.3.evidence{"quotes": 1, "missing": ["\"usd\":67000"], "path": "quote"}
record.outcomepartial
record_sha2567bcba6b794a9716d…
the answer, as JSON
{
  "verdict": "partial",
  "passed": 3,
  "checks": 5,
  "results.2.check": "regex_match",
  "results.2.ok": false,
  "results.2.evidence": {
    "reason": "no match"
  },
  "results.3.check": "quotes_in_source",
  "results.3.ok": false,
  "results.3.evidence": {
    "quotes": 1,
    "missing": [
      "\"usd\":67000"
    ],
    "path": "quote"
  },
  "record.outcome": "partial",
  "record_sha256": "7bcba6b794a9716d80c632b5c4aac731b6e38a8f6fea7530bdd689cbae9946c7"
}

Assay badge for record 7bcba6b794a9716d

re-derived by the generator
✓receipt sha256:3f27ebdbadb5f553… re-derived: sha256 over the canonical answer, header and body agree
✓record 7bcba6b794a9716d… fetched back from /v1/verify: sealed, signed, and signed by assay-1 (the key at /.well-known/assay.json)
✓as the prose says: verdict = "partial" · passed = 3 · checks = 5 · results.2.ok = false · results.3.ok = false

4. Anyone verifies the verdict, free

curl -s -X GET 'https://api.s2ar.dev/v1/verify/7bcba6b794a9716d80c632b5c4aac731b6e38a8f6fea7530bdd689cbae9946c7'

PARTIAL → HTTP 200 · 111 ms

foundtrue
seal_oktrue
signature_oktrue
key_pinnedtrue
certificate.kindassertion
certificate.verdictpartial
certificate.payload.passed3
the answer, as JSON
{
  "found": true,
  "seal_ok": true,
  "signature_ok": true,
  "key_pinned": true,
  "certificate.kind": "assertion",
  "certificate.verdict": "partial",
  "certificate.payload.passed": 3
}
re-derived by the generator
✓seal recomputed ✓ · signature ✓ · key pinned to assay-1 ✓

No model reads the answer; five checks do, and the record names which one failed and where. An agent that calls assert before it ships a number spends half a cent and gets a signed verdict it can hand on with the figure. The same preset serves any feed: swap the schema’s keys, the range and the domain.

What this cannot buy

From the signed proceedings (/.well-known/proceedings.json), verbatim:

Failed calls are never charged. Nothing about a caller is kept. The rules: the charter.