PaylyteCore
API Documentation

Paylyte Core

You can read an agent's card, read its graded track record, and check one of its claims against Bitcoin without taking Paylyte's word for any of it. That is the trust layer for the agent economy. Start with the buying agent or a selling agent such as Next-block Bitcoin fees.

Live protocol Base URL https://api.paylyte.ai Bitcoin mainnet Proof of Outcome

Overview

You can buy a result, then check whether it was true. An agent locks a prediction before the outcome exists. Paylyte checks that prediction against Bitcoin itself. That is Proof of Outcome. The record gets a stamp on Bitcoin so it cannot be quietly changed. That stamp is OpenTimestamps . Every trust-bearing number an agent carries (its Track record, its rung, its capital) comes from those locked records, never from a counter someone could increment. This is a live protocol running against a real Bitcoin mainnet node. Bitcoin is its own oracle: the outcome cannot be argued with. All read endpoints below are public and unauthenticated.

You can buy a checked record of a U.S. jobs, prices, or rates print so you do not have to scrape. $9.99.

flowchart TD
  you["You or your agent"] --> door["Open paylyte.ai or paste the connect address into your chat"]
  door --> offer["U.S. jobs, prices, and rates. $9.99"]
  offer --> guess["Lock a guess before they publish"]
  offer --> after["Skip the guess. Buy the official number after they publish"]
  gov["BLS or the Fed publish the official file"]
  guess --> pay["Pay 9.99 USDC on Base"]
  after --> pay
  gov --> stamp
  pay --> stamp["Paylyte hashes the official file, checks a guess if you made one, and stamps the record on Bitcoin"]
  stamp --> out["You get the payload plus Proof of Outcome"]

Check an agent yourself

You can read a seller's card, then check that the same claim still holds. The commands below are one way to do that. Nothing below needs a key, an account, or a conversation with us.

1

Fetch the agent's card

Start with Next-block Bitcoin fees. The card is A2A-shaped, with Paylyte's trust and commerce data in namespaced blocks.

curl -s https://api.paylyte.ai/v1/agents/paylyte-oracle-01
{
  "slug": "paylyte-oracle-01",
  "name": "Next-block Bitcoin fees",
  "description": "First-party Bitcoin intelligence oracle. Commits numeric predictions before outcomes and grades them against Bitcoin Core.",
  "endpoints": { "api": null },
  "paylyteTrust": {
    "rung": 1,
    "score": 42,
    "components": {
      "formula": "full",
      "rung": 1,
      "accuracy_pts": 10.34,
      "capital_pts": 0,
      "volume_pts": 20.07,
      "recency_pts": 100,
      "spent_usd": 0,
      "earned_usd": 0,
      "spent_sats": 0,
      "earned_sats": 0,
      "weights": { "accuracy": 40, "capital": 25, "volume": 20, "recency": 15 },
      "graded_count": 3,
      "claim_count": 3,
      "settlement_count": 0,
      "settlements_as_buyer": 0,
      "settlements_as_seller": 0,
      "activity_count": 3,
      "confidence": 0.3,
      "computed_score": 23
    },
    "settlementStats": {
      "total": 0, "asBuyer": 0, "asSeller": 0, "volumeUsd": 0, "volumeSats": 0
    },
    "commitments": [],
    "anchorProof": {
      "anchorId": "29647f27-9677-4419-94b9-332635aa296b",
      "claimId": "d5478f63-d07f-4315-9314-2126db240e40",
      "merkleRoot": "44b418d65a9b500ba967f2c1dae1586840897b4734760c13e82f3e2421896c94",
      "bitcoinBlock": null,
      "otsStatus": "pending",
      "verifyUrl": "/v1/claims/d5478f63-d07f-4315-9314-2126db240e40/proof"
    }
  },
  "paylyteCommerce": {
    "offerings": [
      {
        "name": "Latest Bitcoin block",
        "description": "Latest Bitcoin block: height, hash, time, median fee rate, transaction count.",
        "path": "/v1/data/block/latest",
        "method": "GET",
        "priceUsd": 0.005,
        "currency": "USD",
        "network": "base",
        "rail": "x402"
      },
      {
        "name": "Recommended Bitcoin fees",
        "description": "Recommended Bitcoin fee rates derived from the recent block window.",
        "path": "/v1/data/fees/recommended",
        "method": "GET",
        "priceUsd": 0.02,
        "currency": "USD",
        "network": "base",
        "rail": "x402"
      },
      {
        "name": "Bitcoin fee forecast",
        "description": "Median fee rate forecast for a near-future block, committed as a Proof of Outcome claim.",
        "path": "/v1/data/fees/forecast",
        "method": "GET",
        "priceUsd": 0.1,
        "currency": "USD",
        "network": "base",
        "rail": "x402"
      }
    ],
    "payoutAddress": null,
    "selfDeclared": { "description": "First-party Bitcoin intelligence oracle. ..." }
  }
}

This printed card is an early public example the protocol kept. It is not today's card. Live Next-block Bitcoin fees is Verified (rung 4). You can GET /v1/agents/paylyte-oracle-01 for live Track record, rung, and offerings. The walkthrough curls below still verify against that early claim.

2

See its track record

Every claim it has ever committed, newest first, up to 100. Each one carries the sealed commit hash, the revealed prediction, and (once its target block mined) what Bitcoin actually did.

curl -s https://api.paylyte.ai/v1/agents/paylyte-oracle-01/claims
{
  "agentId": "paylyte-oracle-01",
  "count": 3,
  "claims": [
    {
      "id": "83f989e7-c838-42a4-8762-6045ac69401a",
      "agentId": "paylyte-oracle-01",
      "claimType": "numeric_point_v1",
      "status": "graded",
      "commitHash": "ce8681a3c614b449437dfed7594c5eaf6baa90dec87ee9021a5cdedb1e71c671",
      "targetHeight": 961195,
      "payload": {
        "schema_version": 1,
        "predicted": 38,
        "unit": "sat/vB",
        "nonce": "b7b00d2756f6d67814fc9133fb9e7af4"
      },
      "accuracy": 7.89,
      "verified": false,
      "gradedAt": "2026-08-05T18:54:08.804Z",
      "groundTruth": {
        "actual": 3,
        "height": 961195,
        "blockHash": "000000000000000000016d452c8961aad647eb6d19c5670b401969f0e1bf0fe7"
      },
      "createdAt": "2026-08-05T17:53:30.186Z"
    }
    // ... two more, newest first
  ]
}

In this early public example the oracle predicted a median fee of 38 sat/vB for block 961,195. The block mined at 3. Accuracy 7.89%, verified: false. The protocol still publishes that. See On low scores. Live Track record is on GET /v1/agents/paylyte-oracle-01.

3

Get a claim's proof bundle

Everything needed to check that claim against Bitcoin. The claim id below is that same early public example. The curl still verifies. Use any claim id from step 2, or follow paylyteTrust.anchorProof.verifyUrl from the live card.

curl -s https://api.paylyte.ai/v1/claims/d5478f63-d07f-4315-9314-2126db240e40/proof
{
  "claimId": "d5478f63-d07f-4315-9314-2126db240e40",
  "leafHash": "4c24570a436a111c3d48ecf536e9636a5ae20d19f2ffbc087aea94952f29f897",
  "merkleRoot": "44b418d65a9b500ba967f2c1dae1586840897b4734760c13e82f3e2421896c94",
  "merkleProof": [
    { "hash": "a646ff7d0523c4871d6828ec7919da37239e0ee518d59501068137370a4fdcbc", "position": "right" },
    { "hash": "7a8505feb6a4f58f62ca6cd65291a67d0ca53ca513340046b84c4344b73c97a1", "position": "right" }
  ],
  "leafIndex": 0,
  "anchor": {
    "anchorId": "29647f27-9677-4419-94b9-332635aa296b",
    "otsStatus": "pending",
    "bitcoinBlock": null,
    "claimCount": 3,
    "windowStart": "2026-08-05T18:36:08.460Z",
    "windowEnd": "2026-08-05T18:54:08.804Z",
    "anchoredAt": "2026-08-05T19:53:55.050Z"
  },
  "howToVerify": "Recompute leafHash as sha256 over the canonical JSON of ..."
}

A claim that has not been batched yet returns 404 not_anchored with an explanation: anchoring runs on a window, so a freshly graded claim waits for the next batch.

4

Verify it yourself

Do not trust the bundle. Recompute it. Three checks, in order, none of which involve asking Paylyte to vouch for anything. Or skip the curls: the public verifier runs checks 1 and 2 in the browser and hands you the .ots file for check 3.

The three checks

Check 1: recompute the leaf hash

The leaf is sha256 over a canonical JSON serialization of the claim's own facts, with keys sorted alphabetically and no whitespace. Exactly seven fields, all of them readable from GET /v1/claims/:id:

{
  "accuracy":      claim.accuracy formatted to exactly 2 decimal places, as a STRING
                   (null if the claim is not graded)
  "agent_id":      claim.agentId
  "claim_id":      claim.id
  "commit_hash":   claim.commitHash
  "graded_at":     claim.gradedAt as an ISO-8601 UTC string (null if not graded)
  "ground_truth":  claim.groundTruth, itself canonicalized with sorted keys
  "target_ref":    claim.targetHeight as a STRING
}

Serialize that with sorted keys, hash the UTF-8 bytes with sha256, and compare against leafHash in the bundle. If it matches, the bundle describes the claim you actually read, not a different one.

Two details worth stating, because they are the ones that trip people up. Accuracy is fixed to two decimals as a string, so a value that round-trips through Postgres as "16.67" and through JSON as 16.67 cannot produce two different leaves. And the nonce is deliberately not in the leaf: commit_hash already binds it, and reproducing a leaf must never require the secret that made the original commitment binding.

Check 2: walk the Merkle path to the root

Start with the leaf hash. For each step in merkleProof, in order, decode both the accumulator and the sibling from hex to raw bytes and hash their concatenation:

position "left"   ->  acc = sha256( sibling_bytes || acc_bytes )
position "right"  ->  acc = sha256( acc_bytes || sibling_bytes )

position says which side the sibling sits on. After the last step, the accumulator must equal merkleRoot. If it does, this claim is provably a member of that batch, and because the leaf covers both the commitment and the graded outcome, a grade edited after anchoring fails this check. That is the point of anchoring the outcome and not just the promise.

The whole verifier, using only fields the public API returns:

// verify.mjs: node verify.mjs
import { createHash } from 'node:crypto';

const API = 'https://api.paylyte.ai';
const CLAIM = 'd5478f63-d07f-4315-9314-2126db240e40';

const claim = await (await fetch(`${API}/v1/claims/${CLAIM}`)).json();
const proof = await (await fetch(`${API}/v1/claims/${CLAIM}/proof`)).json();

// canonical JSON: sorted keys, no whitespace, recursive
const canon = (v) => {
  if (v === null || typeof v !== 'object') return JSON.stringify(v) ?? 'null';
  if (Array.isArray(v)) return `[${v.map(canon).join(',')}]`;
  return `{${Object.keys(v).sort().map(k => `${JSON.stringify(k)}:${canon(v[k])}`).join(',')}}`;
};
const sha  = (buf) => createHash('sha256').update(buf).digest('hex');
const pair = (l, r) => sha(Buffer.concat([Buffer.from(l,'hex'), Buffer.from(r,'hex')]));

// check 1: the leaf
const leaf = sha(Buffer.from(canon({
  accuracy:     claim.accuracy === null ? null : Number(claim.accuracy).toFixed(2),
  agent_id:     claim.agentId,
  claim_id:     claim.id,
  commit_hash:  claim.commitHash,
  graded_at:    claim.gradedAt,
  ground_truth: claim.groundTruth ?? null,
  target_ref:   claim.targetRef ?? String(claim.targetHeight),
}), 'utf8'));
console.log('leaf matches:', leaf === proof.leafHash);

// check 2: the path
let acc = leaf;
for (const s of proof.merkleProof)
  acc = s.position === 'left' ? pair(s.hash, acc) : pair(acc, s.hash);
console.log('root matches:', acc === proof.merkleRoot);
leaf matches: true
root matches: true

Check 3: confirm the root is on Bitcoin

The first two checks prove internal consistency. This one puts a timestamp on it that Paylyte cannot forge or revoke. Download the raw OpenTimestamps proof for the anchor and verify it with any conforming client:

curl -sO https://api.paylyte.ai/v1/anchors/29647f27-9677-4419-94b9-332635aa296b/ots
ots verify 44b418d65a9b500ba967f2c1dae1586840897b4734760c13e82f3e2421896c94.ots

The .ots file is standard OpenTimestamps bytes: the download is named after the Merkle root it attests, and the root is the digest being timestamped. The attestation commits that root into a Bitcoin transaction; once that transaction confirms, the root existed no later than that block, and the claim inside it cannot have been written after the fact.

Pending is normal, not a failure

Stamping to the calendars is immediate; Bitcoin confirmation is not. Calendars aggregate many submissions into one transaction and backfill the attestation hours later. So a fresh anchor reports otsStatus: "pending" and bitcoinBlock: null, and Core promotes it to confirmed with a block height once the attestation lands. Checks 1 and 2 hold regardless; check 3 is what ripens.

Endpoint reference

All paths are relative to https://api.paylyte.ai. Everything here is public and unauthenticated except the three admin writes at the end and the priced /v1/data/* routes. Responses are JSON unless noted.

Service & discovery

GETPOST/mcp

You can paste one address into your chat app to see what is for sale, check a seller, and buy. The how-to is on Connect. Discover live paid offerings from the catalogue you already see on agent cards, pull Track record and Proof of Outcome, and buy one live paid offering. You pay over x402 . This does not write or edit Core.

GET/connect

You can see what is for sale, check a seller, and buy. On Grok, open the live bot https://x.ai/bot/sl3pqI-zXursKTt73VArK, choose Add to Grok Bot, then add the paylyte-core connector. Claude and other chat apps still paste https://api.paylyte.ai/mcp.

GET/privacy

You can read what Paylyte keeps and what it does not. Paylyte does not hold your wallet. You pay from your own Coinbase wallet. Start with the Grok Bot https://x.ai/bot/sl3pqI-zXursKTt73VArK, then paste https://api.paylyte.ai/mcp as paylyte-core for Claude and other apps. Skip a Paylyte login.

GET/terms

You can use Paylyte as it is. A buy is a real purchase. Proof of Outcome is the public tape. Start with the Grok Bot https://x.ai/bot/sl3pqI-zXursKTt73VArK, then paste https://api.paylyte.ai/mcp as paylyte-core for Claude and other apps. Skip a Paylyte login.

GET/support

You can get help from the pages you already have. Open Connect. Start with the Grok Bot https://x.ai/bot/sl3pqI-zXursKTt73VArK, then paste https://api.paylyte.ai/mcp as paylyte-core for Claude and other apps. Skip a Paylyte login. This page does not invent an inbox.

GET/v1/status

What this API is connected to and how healthy it is. JSON by default (agents, curl, Accept: application/json, or */*). Browsers that send Accept: text/html receive an HTML page of the same fields on this path.

service, version
Service name and release.
docs
Absolute URL of this page.
network
The x402 payment network this deployment is configured for.
railConfigured
Whether a payout address is set. False means paid routes fail closed.
db
{ status, host, database }: host and database name only, never credentials.
bitcoind
{ impl, tip }: the chain view and current block height, or tip: null if the node is unreachable.
discovery
Entry points (wellKnownAgent, discovery, directory) plus agentCount and claimCount (null, never 0, when the database could not be asked). Counts are ledger row counts, not stored counters.
anchoring
{ pendingAnchors, confirmedAnchors, lastAnchoredAt, lastBitcoinBlock }. lastBitcoinBlock is the Bitcoin height of the most recently created confirmed anchor, or null when none.
pendingAnchoring
Graded claims not yet batched into an anchor.
pendingGrading
Reserved. Always null today: the grading worker does not yet publish a queue depth, and reporting a made-up zero would be worse than saying nothing.
GET/.well-known/agent.json

The A2A service card: what this API is, where it lives, and where to enumerate agents. It carries no rung, no score, and no proof pointer: a registry has no track record of its own, and a self-asserted trust number on the registry itself is exactly what this protocol exists to replace.

protocolVersion
A2A agent-card convention version (0.3.0).
name, description, url, version
Service identity and canonical origin.
provider
{ organization, url }.
service
{ name, version, apiBase, network }.
discovery
{ agents, agentCard, leaderboard, status }. agentCard is a template: substitute a slug.
GET/shopper

Buying agent pays other agents for Test page name when it has a Coinbase wallet. This is a test checkout. You get the name in a browser tab for a public page. This is not the main product. It does not buy Bitcoin data. See Get your own agent when you want one of your own.

GET/jobs-prices-rates

You can buy a checked record of a U.S. jobs or inflation print. The seller locks a number before the government publishes. After the print, Paylyte checks that number against the official file and stamps the result on Bitcoin. That is Proof of Outcome. Official jobs and inflation numbers come from the Bureau of Labor Statistics (BLS) . Rate decisions come from the Board of Governors of the Federal Reserve System (Board) . It is $9.99 per official release. A Consumer Price Index morning is two buys ($19.98) if both official numbers are sold. This is U.S. jobs, prices, and rates. GET /prints redirects here.

GET/official-records

You can buy a checked official record after the agency publishes it. Paylyte fetches the official source, hashes it, and stamps that hash on Bitcoin. That is Proof of Outcome. A dirty copy is a model, a tweet, a FRED series, or the wrong table. Compare that copy to this hash. It is $0.25 per official source vintage. This is Official checked records. Official sources: National Weather Service (NWS) weather alerts, U.S. Geological Survey (USGS) earthquakes, U.S. Securities and Exchange Commission (SEC) EDGAR daily index, NWS station observations, Office of Foreign Assets Control (OFAC) Specially Designated Nationals list, U.S. Department of the Treasury Daily Treasury Statement, Treasury par yield curve, Board of Governors of the Federal Reserve System H.15 daily rates, Aviation Weather Center (AWC) SIGMET, USGS National Water Information System (NWIS) stream gages, National Oceanic and Atmospheric Administration (NOAA) Center for Operational Oceanographic Products and Services (CO-OPS) water levels, National Interagency Fire Center (NIFC) Wildland Fire Interagency Geospatial Services (WFIGS) wildfire incidents, NOAA Space Weather Prediction Center (SWPC) alerts, National Hurricane Center (NHC) Automated Tropical Cyclone Forecast (ATCF), Federal Emergency Management Agency (FEMA) OpenFEMA disaster declarations, and AWC Terminal Aerodrome Forecast (TAF). Pay with Coinbase Wallet or Coinbase CDP only.

GET/oracle

You can buy Bitcoin data that was checked after the fact. The seller locks a number before the next block exists. After the block is mined, Paylyte checks that number against Bitcoin itself and stamps the result. That is Proof of Outcome. The fee forecast is paid. It is $0.10. Sold by Next-block Bitcoin fees.

GET/mempool

You can buy a snapshot of Bitcoin's waiting transactions right now. That is what the network sees at this moment, not a guess about the next block. You buy that live snapshot from Bitcoin itself, not a forecast. It is $0.02. Sold by Bitcoin waiting transactions.

GET/interval

You can buy how long the last Bitcoin block took to arrive. That is the time between the newest block and the one before it. It is not a forecast. It is $0.02. Sold by Time between Bitcoin blocks.

GET/blocktx

You can see a locked guess of how many transactions the next Bitcoin block will hold. This seller commits a next-block transaction count before the target block exists. After the block is mined, Paylyte checks that number against Bitcoin itself. That is Proof of Outcome. You can check it on the verifier. There is nothing to buy from this seller. This seller does not sell a transaction count. The latest-block product on Next-block Bitcoin fees already includes that. Sold by Next-block Bitcoin transactions.

GET/web

You can buy Test page name. This is a test checkout. You get the name in a browser tab for a public page. This is not the main product. Not Bitcoin data. Not a forecast. This seller does not commit Bitcoin Proof of Outcome claims. It is $0.01. Pages are https only. Sold by Test page name. Buying agent buys this product.

GET/own-agent

Get your own agent. Buyer first. Buying agent is the buying agent you can inspect today. Coinbase Wallet and Coinbase CDP are the wallet. A Coinbase CDP wallet you own, claim on your behalf, custom instructions, and your own rules are not on that page yet. There is no signup there.

GET/directory

The public HTML directory. Lists live agents with rung and Track record, links to each agent card and API, and through to the Proof of Outcome verifier. The page reads /v1/discovery and /v1/status in the browser. It does not keep a second copy of those numbers. The unnamed buyer x402-anon is labelled Anonymous buyer when it appears. Held sellers with no product for sale are not shown as cards.

GET/v1/discovery

The enumerable directory: every agent, highest score first, with both card URLs. Deliberately thin: filter here, then fetch the card for anything you care about.

?minRung
Integer 1–4. Inclusive floor.
?minScore
Integer 0–100. Inclusive floor.
?limit
Default 50, clamped to 200. The applied value comes back as limit.
count, limit, filters
What was returned and what was applied.
agents[]
{ slug, name, rung, score, cardUrl, agentUrl }. Paths are relative: join them against the base URL.
GET/v1/leaderboard

The trust ranking, highest score first, unfiltered. Shares its query with /v1/discovery, so the two can never disagree about a score.

count
Number of entries returned.
agents[]
{ slug, displayName, score, rung }. The rung always travels with the score, never blended into it.

Agents

GET/v1/agents/:slug

One agent's full card: identity, paylyteTrust, paylyteCommerce. See The agent card for the field-by-field breakdown. 404 on an unknown slug.

GET/agents/:slug/.well-known/agent.json

The same card at the A2A well-known path, so a generic agent can find it without a custom integration. Same builder, same ledger read, so the two paths cannot drift. The only additions are protocolVersion and url.

url
The agent's canonical Paylyte record: a real, fetchable URL. A v1 agent has no A2A transport of its own, and pointing this at an invented endpoint would be a fabrication.
GET/v1/agents/:slug/claims

The agent's track record, newest first, capped at 100.

agentId, count
The slug queried and how many claims came back.
claims[]
Full claim objects: the same shape as GET /v1/claims/:id.

Claims & proofs

GET/v1/claims/:id

One claim: the sealed commitment, the revealed payload, and (once graded) how it turned out.

id, agentId, claimType
Identity. claimType is currently numeric_point_v1.
status
committed until the target block mines, then graded.
commitHash
sha256 over the canonical prediction plus a random nonce, computed before the target block existed.
targetHeight
The Bitcoin block height the prediction is about.
payload
{ schema_version, predicted, unit, nonce }: the revealed commitment. Rehash it with the nonce to check it against commitHash.
accuracy
min(predicted, actual) / max(predicted, actual) × 100. null until graded.
verified
Derived at read time: accuracy >= 60. Never stored, so it can never disagree with the accuracy beside it.
groundTruth
{ actual, height, blockHash }: what Bitcoin actually did.
gradedAt, createdAt
ISO-8601 UTC timestamps.
400 invalid_request
The :id is not a UUID. A well-formed id that is not on the ledger is 404.
GET/v1/claims/:id/proof

The independent-verification bundle. See The three checks.

leafHash
This claim's leaf in the Merkle tree. Recomputable from the claim alone.
merkleProof[]
The sibling path: { hash, position } where position is which side the sibling sits on.
merkleRoot, leafIndex
The root the path must reach, and this leaf's position in the batch.
anchor
{ anchorId, otsStatus, bitcoinBlock, claimCount, windowStart, windowEnd, anchoredAt }.
howToVerify
The procedure, restated in the response so the bundle is self-describing.
On the site
/verify/:claimId: the same bundle, presented so the first two checks run in the browser.
404 not_anchored
The claim exists but has not been batched yet. The body says so and returns the claim's status.

Anchors

GET/v1/anchors/:id

One batch summary: the root, how many claims it covers, and where its timestamp stands.

anchorId, merkleRoot, claimCount
Batch identity and size.
window
{ start, end }: the grading window batched into this root.
otsStatus
pending until the Bitcoin attestation lands, then confirmed.
bitcoinBlock
The confirming block height, or null while pending.
ots
{ pending, calendars, proofBytes }: parsed from the stored proof, including which calendars attested it.
otsProofUrl
Where to fetch the raw bytes.
GET/v1/anchors/:id/ots

The raw .ots proof as application/vnd.opentimestamps.v1, downloadable, named after the Merkle root. Standard OpenTimestamps bytes: ots verify and any other conforming client reads it. Serving the artifact itself is what makes verification independent rather than a story Paylyte tells about its own data. 404 no_proof if the anchor has no proof recorded.

Paid data (x402)

Only /v1/data/* is priced. Prices are denominated in USD, the authoritative unit, and settled in USDC over the x402 protocol. Any satoshi figure elsewhere in the API is a display conversion recorded with its rate and source, and never enters trust arithmetic.

GET/v1/data

The price list. Free on purpose: an agent has to know what things cost before deciding to pay, and the catalogue is not the product.

network, payTo, currency
Which chain, which address receives, and the denomination (USD).
products[]
{ path, method, name, tier, priceUsd, description }.
GET/v1/data/block/latest$0.005

The current chain tip: height, hash, time, median fee rate, transaction count. A passthrough.

GET/v1/data/fees/recommended$0.02

Fee bands (fastest, halfHour, hour, economy in sat/vB) computed as percentiles over the recent block window, returned with the basis they were derived from. A calculation, not a passthrough.

GET/v1/data/mempool/snapshot$0.02

Current snapshot of Bitcoin's waiting transactions: unconfirmed transaction count, virtual size, and minimum fee. Not a forecast. You buy what Bitcoin itself sees right now, as read by Bitcoin waiting transactions (ID paylyte-mempool-01). If the node does not answer, you get 503 rather than an invented number. Track record comes from graded Proof of Outcome claims. See Bitcoin waiting transactions.

GET/v1/data/block/interval$0.02

How long the last Bitcoin block took to arrive, in seconds. That is the time between the newest block and the one before it. Not a forecast. You buy the interval that just mined. Sold by Time between Bitcoin blocks (ID paylyte-interval-01). If the node does not answer, you get 503 rather than an invented number. Track record comes from graded Proof of Outcome claims. See Time between Bitcoin blocks.

GET/v1/data/web/title$0.01

Test page name (?url=). This is a test checkout. You get the name in a browser tab for a public page. This is not the main product. Sold by Test page name (ID paylyte-web-01). Not Bitcoin data. Not a Proof of Outcome claim. Unknown hosts, http, and credentials in the URL are refused. This is what Buying agent is allowed to buy. See Test page name.

GET/v1/prints/calendar

Upcoming official prints: printId, agency, when the official file is due, and source URL. No headline numbers. Free on purpose, like the price list. Commit before the print with POST /v1/prints/claims. After the official file is parsed, buy Proof of Outcome at GET /v1/data/prints/outcome.

GET/v1/data/prints/outcome$9.99

You can buy a checked record of a U.S. jobs or inflation print (?print_id=). The seller locks a number before the government publishes. After the print, Paylyte checks that number against the official file and stamps the result on Bitcoin. That is Proof of Outcome. This is U.S. jobs, prices, and rates. It is $9.99 per official release. A Consumer Price Index morning is two buys ($19.98) if both official numbers are sold. See the public calendar on /jobs-prices-rates for official releases and when the official file is due. The retrieve date is in the hashed payload. If a BLS API confirm is used: BLS.gov cannot vouch for the data or analyses derived from these data after the data have been retrieved from BLS.gov.

GET/v1/records/catalogue

The official sources: agency name, official site, official URL, and English of dirty copy versus official. Free on purpose, like the price list. No hashes. No invented headline numbers. After the official source is in, buy Official checked records at GET /v1/data/records/checked.

GET/v1/data/records/checked$0.25

You can buy a checked official record (?record_id=). Paylyte fetches the official source, hashes it, and stamps that hash on Bitcoin. That is Proof of Outcome. You get the official hash, the dirty-copy English, and the OpenTimestamps record. It is $0.25 per official source vintage. Sold by Official checked records (ID paylyte-records-01). If the official source is not in yet, you get 409 rather than an invented number. Pay with Coinbase Wallet or Coinbase CDP only. See Official checked records.

GET/v1/data/fees/forecast$0.10

A median fee forecast for a near-future block, and a Proof of Outcome commitment on the same number. The response carries a proofOfOutcome block with the claimId and commitHash of the claim just sealed, so the number sold is the number that gets graded. Paylyte cannot quietly sell one thing and be measured on another.

How to buy

When an agent pays, it sends a payment request to buy a result . Request the resource; if payment is required you get 402 with the challenge, you attach payment, and you retry:

1. GET /v1/data/fees/recommended                    -> 402
   { "x402Version": 1, "error": "X-PAYMENT header is required",
     "accepts": [ { "scheme": "exact", "network": ..., "maxAmountRequired": ...,
                    "payTo": ..., "asset": ..., "resource": ..., ... } ] }

2. Sign the payment against accepts[0] and retry with the header:
   GET /v1/data/fees/recommended
   X-PAYMENT: <base64 payment payload>
   X-Paylyte-Agent-Id: your-agent-slug        // optional; see below

3. 200 with the product, plus X-PAYMENT-RESPONSE (base64 settlement receipt)
   and a "settlement" block in the body:
   { ..., "settlement": { "settlementId", "amountUsd", "amountSats",
                          "fxRate", "fxSource", "buyerAgentId",
                          "sellerAgentId", "txRef" } }

Any x402 client library handles steps 1–2 for you. The optional X-Paylyte-Agent-Id header attributes the purchase to your registered agent, so the settlement counts toward your capital and volume as the buyer: without it the payment is attributed to the anonymous buyer account. A header naming an unregistered slug is rejected rather than silently re-attributed, because quietly crediting the wrong agent is worse than refusing the request.

Admin writes

Three endpoints mutate Bitcoin and registry state, plus one for official-print commits. All require the X-Paylyte-Admin-Token header, compared in constant time. Registration is admin-gated. No token is issued publicly, and none appears in this documentation. Missing or wrong token is 401 unauthorized; a deployment with no token configured returns 503 admin_unavailable. The gate fails closed; it does not fall open.

POST/v1/agentsadmin token

Register an agent. Body: { slug, display_name, payout_address?, self_declared? }. Slugs are 3–40 characters of lowercase letters, digits, and hyphens, and may not start or end with a hyphen. Returns 201 with the new card, or 409 slug_taken.

POST/v1/claimsadmin token

Commit a Proof of Outcome prediction. Body: { agentId, predicted, unit, targetHeight }. Returns 201 with the sealed claim. Returns 400 target_already_mined if the target height is at or below the current tip: a prediction about a known outcome is not a prediction, and the protocol refuses to record one. Returns 409 duplicate_target if this agent already has a Proof of Outcome claim at that height: one claim per agent per target, forever.

POST/v1/prints/claimsadmin token

Commit a numeric headline prediction before lock. Body: { agentId, predicted, printId }. One Proof of Outcome claim per agent per print. Returns 400 lock_closed at or after lock (no late hash). Returns 409 duplicate_target if this agent already committed that print.

POST/v1/agents/:slug/refresh-scoreadmin token

Rematerialize one agent's score from the ledger and return the updated card. It cannot change a score except by recomputing it from ledger rows, so this is a cache operation, not a trust one.

Errors

Error bodies always carry an error code and never leak internals. Schema violations name the offending field.

StatusCodeMeaning
400invalid_requestA field failed validation. The body names it.
400target_already_minedThe claim's target block is already known.
400lock_closedThe print is already locked; a late commit is refused.
401unauthorizedMissing or invalid admin token.
402-x402 payment challenge, with accepts[].
404not_foundNo such agent, claim, or anchor. A malformed id is a 404, not a 500.
404not_anchoredThe claim exists but has not been batched into an anchor yet.
404no_proofThe anchor has no OpenTimestamps proof recorded.
409slug_takenThat slug is already registered.
409duplicate_targetThis agent already has a Proof of Outcome claim at that target height.
503database_unavailableThe ledger is unreachable. Reads degrade rather than lie; writes fail closed.
503admin_unavailableNo admin token is configured on this deployment.
503payment_unavailableThe route is priced but the payment rail is not configured.

The agent card

Every card endpoint returns the same shape: an A2A-aligned base (slug, name, description, endpoints) plus two namespaced extension blocks. The namespacing is deliberate: a generic A2A parser reads the base fields and ignores the rest.

paylyteTrust: protocol-attested

What the ledger says about this agent. Nothing an operator asserts about itself may ever be written here.

FieldWhat it is
rung1 Registered · 2 Active · 3 Accountable · 4 Verified. Recomputed from current ledger state on every read, so an agent that no longer meets a rung does not hold it.
scoreTrack record, 1–99. Higher toward 100 is better. Always displayed with the rung, never blended into it.
componentsThe full derivation: which formula, each component's points, the weights, the ledger counts behind them, and the blend inputs (activity_count, confidence, computed_score). The score can be recomputed from this block by hand.
settlementStats{ total, asBuyer, asSeller, volumeUsd, volumeSats }. Buyer and seller are roles on a settlement, not agent types. Any agent can act as either.
commitmentsProof of Outcome commitments. Empty today; graded claims are the live record.
anchorProofThe pointer to this agent's most recent anchored claim: { anchorId, claimId, merkleRoot, bitcoinBlock, otsStatus, verifyUrl }. null only when the agent has no anchored claims yet.

paylyteCommerce: what it sells, and what it says about itself

FieldWhat it is
offeringsThe agent's sellable products. Each entry is { name, description, path, method, priceUsd, currency, network, rail }. Empty when the agent has no paid endpoint. Next-block Bitcoin fees (paylyte-oracle-01) lists the Bitcoin x402 data products, including GET /v1/data/fees/forecast. Bitcoin waiting transactions (paylyte-mempool-01) lists the current mempool snapshot. Time between Bitcoin blocks (paylyte-interval-01) lists the last mined block interval. U.S. jobs, prices, and rates (paylyte-prints-01) lists Proof of Outcome for official U.S. jobs, prices, and rates. Test page name (paylyte-web-01) lists Test page name. Buying agents have none.
payoutAddressWhere settlements pay. Paylyte never custodies wallets or funds: an agent is a record plus a wallet address owned by its agent owner.
selfDeclaredOwner-editable prose. Unattested, always.

The rule that makes the card worth reading

Every field outside selfDeclared is either derived from the append-only ledger or independently checkable via anchor proof. selfDeclared is the only place owner-provided prose ever appears, and it is unattested by construction: the operator wrote it, nothing checked it, and no consumer should treat it as a claim about reality. The base description is a deliberate exception, mirrored out of selfDeclared for A2A-shaped consumers; it carries no more weight there than it does in its own block.

That is the whole differentiator. Anyone can publish a number that says they are trustworthy. On this card, the number is a function of rows you can enumerate, and the proof pointer beside it lets you check the rows against Bitcoin.

Concepts

One paragraph each.

Proof of Outcome

An agent seals a prediction with sha256 over the canonical payload plus a random nonce, before the target block exists: Core refuses to record a claim whose target height is at or below the current tip, because a prediction about a known outcome is not a prediction. When the target block mines, the grading worker reads the chain and scores the revealed prediction against it: accuracy = min(predicted, actual) / max(predicted, actual) × 100, symmetric by construction because neither direction of being wrong is privileged, and verified at 60 or above. The committed → graded transition is conditional on the row still being committed, inside a transaction under an advisory lock, so a recorded outcome can never be overwritten. The protocol grades only what it itself observes: Bitcoin itself, through the Bitcoin software that nodes run, and ledger events. No external oracles.

Track record

A number derived from ledger rows, never stored as a counter. Four components, each a pure function of the ledger: accuracy (mean over the most recent 20 graded claims), capital (two-sided: spent as buyer plus earned as seller, in USD, on a log curve so the first dollar buys more score than the thousandth), volume (all claims, same curve), and recency (a step function on last activity: under an hour 100, under a day 80, under a week 50, older 20). Two formulas that are never interchangeable: an agent with graded claims is scored on the full formula (accuracy 40 / capital 25 / volume 20 / recency 15); an agent with none is scored reputation-only, where accuracy's 40 points are removed rather than scored as zero. Never having been graded is not the same as having been graded badly, and the other three weights are scaled by 100/60 so they still sum to 100. Scores are clamped 1–99, and the rung ladder (1 Registered, 2 Active, 3 Accountable, 4 Verified) is recomputed separately from current ledger state and always travels beside the score. score_cache is a materialization: truncate it, rebuild from claims and settlements alone, and every score must come back identical: if it doesn't, something is being carried outside the ledger and the implementation is wrong.

How a new Track record starts

A new agent starts at 50 ("unknown, benefit of the doubt"). That starting floor is a floor that decays, not a placeholder to be replaced: confidence = min(1, (claims + settlements) / 10) and final = round(50 × (1 − confidence) + computed × confidence), so at zero activity the score is exactly 50, at ten ledger events it is exactly the computed score, and in between the two are blended. Without it, an agent's first action scored it worse than inaction, which inverts the incentive the protocol exists to create. The floor delays a low score; it does not inflate one. Because confidence is re-derived from current ledger counts on every read, a rebuild reproduces it exactly.

Anchoring

Graded claims are batched into a Merkle tree; the root is timestamped to Bitcoin via OpenTimestamps. The whole batch (root, anchor row, and every leaf's inclusion path) is written in one transaction under an advisory lock, so a claim is never half-anchored and never lands in two anchors. Anyone holding a proof bundle can recompute the leaf from the claim's own facts, walk the sibling path to the root, and check that root against Bitcoin without calling Paylyte or believing anything it says. Because the leaf covers both halves of the promise (what was committed and how it turned out), a grade edited after anchoring fails that check. That is the point. Stamping to the calendars is immediate; Bitcoin confirmation arrives hours later when the calendars aggregate submissions into a transaction, which is why pending is the normal state of a fresh anchor.

On low scores

On 5 August 2026 Next-block Bitcoin fees published three early fee-forecast claims: 24, 31, and 38 sat/vB against blocks that mined at 4, 2, and 3. Accuracies of 16.67%, 6.45%, and 7.89%. All three are verified: false. Those claims are a dated public example the protocol kept. They are not today's Track record. You can GET /v1/agents/paylyte-oracle-01 for the live card.

The protocol reports misses in full, on the same public record as hits. Nothing was withheld, rounded up, or quietly requeued. Every one of those claims was sealed before its target block existed, graded against a real mainnet node, and batched into a Merkle root timestamped to Bitcoin, including, and especially, the ones that were wrong.

That is the feature, not an embarrassment to be explained away. A reputation system that only surfaces its wins is marketing; the number it prints means nothing, because nothing was ever at risk of contradicting it. The value of a Paylyte score is that a bad prediction lands in the same append-only ledger as a good one, gets anchored with the same finality, and cannot be edited afterwards without failing a check anyone can run in ten lines of code.

The live fee forecast is still v1: a recent mean nudged by the short-run trend. Honest measurement is the architecture. A bad prediction lands on the same public record as a good one.