Skip to content

Scenario Walkthrough

Definitive walkthrough of FORA v1.0 as of March 2026. Every field name, signature algorithm, and endpoint matches the current fora.proto.

Agent: Anthropic’s Claude (claude.ai), running the FORA Agent SDK Broker: Anthropic’s hosted Broker (broker.anthropic.com) Subscription: Anthropic has an annual deal with Hearst Media via SSP-Alpha exchange Request: Claude needs an article about AI regulation originally published by Hearst’s TechCrunch (techcrunch.com), syndicated to The Verge (theverge.com) via SSP-Beta exchange Extension Profiles: Both Exchanges declare supported_profiles: ["fora-news-v1"] in their manifests. The Broker forwards supported_profiles from the agent to enable profile-aware metadata in offers (e.g., news.iptc_guid, news.correction_status).


Before any agent request, providers configure their domains and Exchanges ingest content into catalogs.

0a. Hearst (TechCrunch) — RSL + fora.json

Section titled “0a. Hearst (TechCrunch) — RSL + fora.json”

rsl.txt — declares licensing terms and a maximum rate (price ceiling):

<!-- https://techcrunch.com/rsl.txt -->
<content url="/premium/*">
<permits type="usage">ai-input ai-index search</permits>
<prohibits type="usage">ai-train</prohibits>
<payment type="crawl" currency="USD" amount="0.08"/>
<!-- RSL amount is the MAXIMUM (price ceiling). Exchange may offer at or below. -->
</content>

fora.json — declares which Exchange is authorized to transact:

// GET https://techcrunch.com/.well-known/fora.json
{
"ver": "1.0",
"provider": "techcrunch.com",
"contact": "licensing@hearst.com",
"exchanges": [
{
"domain": "exchange.ssp-alpha.com",
"endpoint": "https://exchange.ssp-alpha.com/fora/v1",
"relationship": "PROVIDER_RELATIONSHIP_DIRECT"
}
]
}

Edge function — deployed on Hearst’s CDN (Cloudflare/Fastly/Lambda@Edge). Blocks unauthorized AI bots with 403, an X-Content-Rules header pointing to the provider’s own fora.json, and an X-FORA-Exchange header naming the Exchange that sells the content. Verifies Ed25519 signed URLs for authorized requests, using the Exchange’s published public key.

Anthropic publishes its agent’s Ed25519 public key in its WBA directory (the JWK Set at /.well-known/http-message-signatures-directory):

// GET https://claude.ai/.well-known/http-message-signatures-directory
// Content-Type: application/http-message-signatures-directory+json
{
"keys": [
{
"kty": "OKP",
"crv": "Ed25519",
"use": "sig",
"alg": "EdDSA",
"x": "7Hd8FjXz9K2qR4nPbY1sT0vWxU3gLmN5oA8pC6dE1fI",
"not_before": "2026-01-01T00:00:00Z",
"not_after": "2026-12-31T23:59:59Z"
}
],
"revocation_url": "https://claude.ai/.well-known/fora-invalidations.json"
}

The fora.json manifest still declares the role and contact, but the keys live in the WBA directory:

// GET https://claude.ai/.well-known/fora.json
{
"ver": "1.0",
"role": "ROLE_AGENT",
"domain": "claude.ai",
"contact": "legal@anthropic.com"
}

The Broker announces its key in its own WBA directory the same way:

// GET https://broker.anthropic.com/.well-known/http-message-signatures-directory
// Content-Type: application/http-message-signatures-directory+json
{
"keys": [
{
"kty": "OKP",
"crv": "Ed25519",
"use": "sig",
"alg": "EdDSA",
"x": "qW3rT8mNxVzP7sK1dL0yUoJ5bG2hF4iE6cA9nR3wS8g",
"not_before": "2026-01-01T00:00:00Z",
"not_after": "2026-12-31T23:59:59Z"
}
],
"revocation_url": "https://broker.anthropic.com/.well-known/fora-invalidations.json"
}

SSP-Alpha’s Resource Ingestion Pipeline runs in the background:

1. Crawl techcrunch.com/sitemap.xml -> discover all /premium/* URLs
2. Fetch rsl.txt -> extract permits/prohibits and RSL pricing ceiling ($0.08/crawl)
3. HTML crawl via readability -> extract text -> word count -> estimate tokens
4. Apply Hearst's private pricing (from SSP-Alpha config DB): $0.05/article
(Below the RSL ceiling of $0.08 — compliant)
5. Third-party attestation (GumGum via CatalogService.PushResources):
GumGum crawls the article, signs attestation claims with Ed25519:
{ verifier: "gumgum.com", claims: { estimated_quantity: 3300, word_count: 2500,
language: "en", iab_categories: ["IAB19-6"] }, signature: "..." }
Exchange validates: gumgum.com is in techcrunch.com's catalog_contributors,
verifies signature against the key in gumgum.com's WBA directory
(the JWK Set at gumgum.com/.well-known/http-message-signatures-directory),
selected by the attestation's keyid (RFC 7638 thumbprint)
6. Build catalog entry:
{
domain: "techcrunch.com",
path: "/premium/ai-regulation-2026.html",
title: "AI Regulation: What Providers Need to Know",
word_count: 2500,
estimated_quantity: 1, // in the price's unit: one access per purchase
pricing: { model: PRICING_MODEL_PER_UNIT, rate: "0.05", currency: "USD", unit: "accesses", unit_cost: "0.00001515" },
// unit_cost = $0.05 / 3300 tokens (the article's attested size), for comparison only
identity: {
canonical_url: "https://techcrunch.com/premium/ai-regulation-2026.html",
iptc_guid: "urn:newsml:techcrunch:20260315:ai-reg-001",
content_hash: "a1b2c3d4e5f6...",
hash_method: "simhash-v1",
resource_mutability: RESOURCE_MUTABILITY_STATIC
},
attestations: [
{ verifier: "gumgum.com", keyid: "kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k",
attested_at: "2026-03-14T09:00:00Z",
uri: "https://techcrunch.com/premium/ai-regulation-2026.html",
claims: { estimated_quantity: 3300, word_count: 2500, language: "en" },
signature: "base64-ed25519-gumgum..." }
],
terms: [
{ semantics: TERM_SEMANTICS_ENUMERATED,
pricing: { model: PRICING_MODEL_PER_UNIT, rate: "0.05", currency: "USD", unit: "accesses" },
restrictions: [
{ kind: RESTRICTION_KIND_FUNCTION,
permitted: ["ai-input", "ai-index", "search"],
prohibited: ["ai-train"] }
] }
]
}
7. Compile into radix trie -> serialize to catalog.bin -> Exchange loads via atomic pointer swap

SSP-Alpha also knows about Anthropic’s subscription, looked up by Anthropic’s account handle (minted at registration):

BillingAdapter.CheckSubscription("acct_7f3e21c9", "hearst-media")
-> { subscription_id: "SUB-ANTHROPIC-HEARST-2026", active: true, quota_remaining: 850000 }
1. The Verge reprinted the TechCrunch article (syndication deal):
theverge.com/premium/ai-regulation-republish.html
2. The Verge has fora.json pointing to SSP-Beta:
{
"ver": "1.0",
"provider": "theverge.com",
"exchanges": [{
"domain": "exchange.ssp-beta.com",
"endpoint": "https://exchange.ssp-beta.com/fora/v1",
"relationship": "PROVIDER_RELATIONSHIP_DIRECT"
}]
}
3. SSP-Beta's ingestion pipeline:
- Discovers the article, estimates 3100 tokens
- The Verge's pricing: $0.07/article (higher than TechCrunch, below RSL ceiling)
- Identity: same iptc_guid (syndicated from same TechCrunch wire)
{
canonical_url: "https://theverge.com/premium/ai-regulation-republish.html",
iptc_guid: "urn:newsml:techcrunch:20260315:ai-reg-001",
content_hash: "a1b2c3d4e5f7...",
hash_method: "simhash-v1",
resource_mutability: RESOURCE_MUTABILITY_STATIC
}
- Attestations: [{ verifier: "gumgum.com", claims: { estimated_quantity: 3100, word_count: 2350 } }]
- Anthropic has NO subscription with SSP-Beta

Phase 1: Agent Request (SDK with Ed25519 Signing)

Section titled “Phase 1: Agent Request (SDK with Ed25519 Signing)”

Claude is answering a user question about AI regulation. The SDK triggers:

results, err := client.FetchBatch(ctx, []string{
"https://techcrunch.com/premium/ai-regulation-2026.html",
})

Inside the SDK:

Step 1: Parse domain -> "techcrunch.com"
Step 2: ExchangeRegistry lookup
- Cache miss for techcrunch.com
- Background: fetch https://techcrunch.com/.well-known/fora.json
- Discovers: exchange.ssp-alpha.com is authorized (PROVIDER_RELATIONSHIP_DIRECT)
- Caches: techcrunch.com -> [ssp-alpha]
Step 3: Prepare RFC 9421 HTTP Message Signature (alg=ed25519)
- requester.id = "claude-agent-001"
- requester.domain = "claude.ai"
- Sign the HTTP request per RFC 9421 under the Web Bot Auth profile: the
SDK adds Content-Digest, an empty Authorization, Signature-Agent
(sig1="https://claude.ai"), Signature-Input and Signature. The signature
covers @method, @target-uri, content-digest, authorization and
"signature-agent";key="sig1", with created, expires, keyid, nonce and
tag="web-bot-auth"
- Authentication is asymmetric:
the agent signs with its Ed25519 private key (never leaves the agent),
the Exchange verifies with the public key fetched from the WBA
directory at claude.ai/.well-known/http-message-signatures-directory

Key insight: The SDK discovers Exchanges from the provider’s fora.json. It only finds the authorized Exchange for THAT domain. Cross-provider discovery (same article on different domains) requires either a hosted Broker that has crawled multiple providers’ fora.json, or the agent explicitly requesting multiple URLs across providers.


Phase 2: Supply Discovery (Requester Identity, Subscription Detection, Content Attestations, Ed25519 Verification)

Section titled “Phase 2: Supply Discovery (Requester Identity, Subscription Detection, Content Attestations, Ed25519 Verification)”

The SDK sends DiscoverResources to SSP-Alpha — POST https://exchange.ssp-alpha.com/fora/v1/fora.v1.ExchangeService/DiscoverResources:

{
"ver": "1.0",
"exchange": "exchange.ssp-alpha.com",
"requester": {
"id": "claude-agent-001",
"domain": "claude.ai",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
},
"uris": ["https://techcrunch.com/premium/ai-regulation-2026.html"],
"acceptable_restrictions": [{ "axis": "RESTRICTION_KIND_FUNCTION", "values": ["ai-input"] }],
"deadline": "0.5s"
}
1. Validate request (proto validation) -> pass
2. Verify the RFC 9421 HTTP Message Signature (alg=ed25519) on the request:
a. Read the Signature-Agent member the signature covers
-> agent="https://claude.ai"
b. Fetch the key directory at
https://claude.ai/.well-known/http-message-signatures-directory,
select the key whose RFC 7638 thumbprint matches the keyid
c. Verify the signature against public key -> pass
3. Resolve tenant: techcrunch.com -> Hearst Media tenant
4. Find offers: lookup "/premium/ai-regulation-2026.html" in radix trie -> match
5. Check subscription with quota (the account handle is resolved from the
agent's key directory, which the RFC 9421 signature authenticated in step 2;
requester.id is only a label and never selects the account):
BillingAdapter.CheckSubscription("acct_7f3e21c9", "hearst-media")
-> { subscription_id: "SUB-ANTHROPIC-HEARST-2026",
active: true,
quota_remaining: 850000 }
850000 > 3300 estimated tokens -> quota sufficient
6. Build TWO offers:
Offer A (per-request):
offer_id: "2325749d-50d3-431a-ac34-900d443ee88e"
pricing: { model: PRICING_MODEL_PER_UNIT, rate: "0.05", currency: "USD",
unit: "accesses", unit_cost: "0.00001515", estimated_quantity: 1 }
identity: { canonical_url: "https://techcrunch.com/premium/ai-regulation-2026.html",
iptc_guid: "urn:newsml:techcrunch:20260315:ai-reg-001",
content_hash: "a1b2c3d4e5f6...", hash_method: "simhash-v1" }
attestations: [
{ verifier: "gumgum.com", keyid: "kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k",
claims: { estimated_quantity: 3300, word_count: 2500, language: "en" },
signature: "base64-ed25519-gumgum..." }
]
terms: [
{ semantics: TERM_SEMANTICS_ENUMERATED,
restrictions: [
{ kind: RESTRICTION_KIND_FUNCTION,
permitted: ["ai-input", "ai-index", "search"],
prohibited: ["ai-train"] }
] }
]
delivery_method: DELIVERY_METHOD_INSTRUCTIONS
signature: "<hex-encoded detached Ed25519 signature over the entire canonical Offer — every field, incl. terms, pricing, expires_at>"
signature_algorithm: "EdDSA"
Offer B (subscription):
offer_id: "4f155204-a53e-42aa-8471-154f87d7d3d5"
pricing: { model: PRICING_MODEL_FREE, rate: "0", currency: "USD",
unit_cost: "0", estimated_quantity: 3300 }
subscription_id: "SUB-ANTHROPIC-HEARST-2026"
identity: { same as Offer A }
attestations: { same as Offer A }
terms: [
{ semantics: TERM_SEMANTICS_ENUMERATED,
restrictions: [ same as Offer A ],
scopes: ["subscription:SUB-ANTHROPIC-HEARST-2026"] }
]
delivery_method: DELIVERY_METHOD_INSTRUCTIONS
reporting: { required: true, window: "86400s",
required_fields: ["transaction_id", "function", "consumed_quantity"] }
signature: "<hex-encoded detached Ed25519 signature over the entire canonical Offer — every field, incl. terms, pricing, expires_at>"
signature_algorithm: "EdDSA"
{
"ver": "1.0",
"exchange": "exchange.ssp-alpha.com",
"offers": [
{
"offer_id": "2325749d-50d3-431a-ac34-900d443ee88e",
"exchange": "exchange.ssp-alpha.com",
"title": "AI Regulation: What Providers Need to Know",
"pricing": {
"model": "PRICING_MODEL_PER_UNIT",
"rate": "0.05",
"currency": "USD",
"unit": "accesses",
"unit_cost": "0.00001515",
"estimated_quantity": 1
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"identity": {
"canonical_url": "https://techcrunch.com/premium/ai-regulation-2026.html",
"iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001",
"content_hash": "a1b2c3d4e5f6...",
"hash_method": "simhash-v1"
},
"attestations": [
{
"verifier": "gumgum.com",
"keyid": "kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k",
"attested_at": "2026-03-14T09:00:00Z",
"uri": "https://techcrunch.com/premium/ai-regulation-2026.html",
"claims": { "estimated_quantity": 3300, "word_count": 2500, "language": "en" },
"signature": "base64-ed25519-gumgum..."
}
],
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED",
"restrictions": [
{
"kind": "RESTRICTION_KIND_FUNCTION",
"permitted": ["ai-input", "ai-index", "search"],
"prohibited": ["ai-train"]
}
]
}
],
"signature": "base64-ed25519-sig-A...",
"signature_algorithm": "EdDSA"
},
{
"offer_id": "4f155204-a53e-42aa-8471-154f87d7d3d5",
"exchange": "exchange.ssp-alpha.com",
"title": "AI Regulation: What Providers Need to Know",
"pricing": {
"model": "PRICING_MODEL_FREE",
"rate": "0",
"currency": "USD",
"unit_cost": "0",
"estimated_quantity": 3300
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"subscription_id": "SUB-ANTHROPIC-HEARST-2026",
"reporting": {
"required": true,
"window": "86400s",
"required_fields": ["transaction_id", "function", "consumed_quantity"]
},
"identity": {
"canonical_url": "https://techcrunch.com/premium/ai-regulation-2026.html",
"iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001",
"content_hash": "a1b2c3d4e5f6...",
"hash_method": "simhash-v1"
},
"attestations": [
{
"verifier": "gumgum.com",
"keyid": "kPrK_qmxVWaYVA9wwBF6Iuo3vVzz7TxHCTwXBygrS4k",
"attested_at": "2026-03-14T09:00:00Z",
"uri": "https://techcrunch.com/premium/ai-regulation-2026.html",
"claims": { "estimated_quantity": 3300, "word_count": 2500, "language": "en" },
"signature": "base64-ed25519-gumgum..."
}
],
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED",
"restrictions": [
{
"kind": "RESTRICTION_KIND_FUNCTION",
"permitted": ["ai-input", "ai-index", "search"],
"prohibited": ["ai-train"]
}
],
"scopes": ["subscription:SUB-ANTHROPIC-HEARST-2026"]
}
],
"signature": "base64-ed25519-sig-B...",
"signature_algorithm": "EdDSA"
}
]
}

Phase 2b: Cross-Provider via Broker (Broker-Signed Queries, OfferGroups, SimHash)

Section titled “Phase 2b: Cross-Provider via Broker (Broker-Signed Queries, OfferGroups, SimHash)”

If Anthropic uses its hosted Broker instead of the SDK directly, the Broker provides cross-provider intelligence. The agent sends a DiscoveryRequest to the Broker with multiple URIs (BrokerService.Resolve is discovery-only — it returns offers grouped by URI; execution happens later via a separate ExecuteTransaction call). Agent → Broker:

{
"ver": "1.0",
"requester": {
"id": "claude-agent-001",
"domain": "claude.ai",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
},
"uris": [
"https://techcrunch.com/premium/ai-regulation-2026.html",
"https://theverge.com/premium/ai-regulation-republish.html"
],
"acceptable_restrictions": [{ "axis": "RESTRICTION_KIND_FUNCTION", "values": ["ai-input"] }],
"constraints": {
"preferred_exchanges": ["exchange.ssp-alpha.com"],
"max_unit_cost": "0.00005",
"reporting_capable": true,
"budget_scope": "team:claude-rag",
"period_budget": { "amount": "500.00", "currency": "USD" },
"budget_period": "2592000s"
}
}

Broker Fans Out with Its Own Signed Queries

Section titled “Broker Fans Out with Its Own Signed Queries”

Discovery through the Broker is Broker-led: the agent asked the Broker, and the Broker chooses which Exchanges to query. For each Exchange, the Broker originates its own query (here it batches the URIs and sets its own deadline) and:

  1. Carries the agent’s requester message, naming as requester.domain the host of the directory the agent’s signature verified against (claude.ai, as the agent sent it)
  2. Signs the query alone, with its own labeled RFC 9421 HTTP Message Signature covering its own request components and only its own Signature-Agent member. The query carries no agent signature headers

Broker → SSP-Alpha (multi-URI batch query) — POST https://exchange.ssp-alpha.com/fora/v1/fora.v1.ExchangeService/DiscoverResources:

{
"ver": "1.0",
"exchange": "exchange.ssp-alpha.com",
"requester": {
"id": "claude-agent-001",
"domain": "claude.ai",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
},
"uris": [
"https://techcrunch.com/premium/ai-regulation-2026.html",
"https://theverge.com/premium/ai-regulation-republish.html"
],
"acceptable_restrictions": [{ "axis": "RESTRICTION_KIND_FUNCTION", "values": ["ai-input"] }],
"deadline": "0.4s"
}

SSP-Alpha’s Exchange verifies the Broker’s signature — it looks up the public key by its keyid thumbprint in the key directory named by the Broker’s Signature-Agent member, Ed25519 verifies, and authenticates the caller as the Broker. The query carries no delegation, and the Exchange would not honour one: nothing on a query the Broker signs alone can pass its holder binding. How an agent proves a holder-of-key entitlement at discovery time through a Broker is an open protocol question. A discovery query moves no money, so it carries no agent consent; see Multi-hop forwarding.

SSP-Alpha returns offer_groups (batch mode — multiple URIs in query):

{
"ver": "1.0",
"exchange": "exchange.ssp-alpha.com",
"offer_groups": [
{
"uri": "https://techcrunch.com/premium/ai-regulation-2026.html",
"offers": [
{
"offer_id": "2325749d-50d3-431a-ac34-900d443ee88e",
"exchange": "exchange.ssp-alpha.com",
"pricing": { "model": "PRICING_MODEL_PER_UNIT", "rate": "0.05", "currency": "USD", "unit": "accesses", "unit_cost": "0.00001515", "estimated_quantity": 1 },
"identity": { "canonical_url": "https://techcrunch.com/premium/ai-regulation-2026.html", "iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001", "content_hash": "a1b2c3d4e5f6...", "hash_method": "simhash-v1" },
"attestations": [{ "verifier": "gumgum.com", "claims": { "estimated_quantity": 3300, "word_count": 2500 }, "signature": "..." }],
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED"
}
],
"signature": "base64-ed25519-sig-A...",
"signature_algorithm": "EdDSA"
},
{
"offer_id": "4f155204-a53e-42aa-8471-154f87d7d3d5",
"exchange": "exchange.ssp-alpha.com",
"pricing": { "model": "PRICING_MODEL_FREE", "rate": "0", "currency": "USD", "unit_cost": "0", "estimated_quantity": 3300 },
"subscription_id": "SUB-ANTHROPIC-HEARST-2026",
"identity": { "canonical_url": "https://techcrunch.com/premium/ai-regulation-2026.html", "iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001", "content_hash": "a1b2c3d4e5f6...", "hash_method": "simhash-v1" },
"attestations": [{ "verifier": "gumgum.com", "claims": { "estimated_quantity": 3300, "word_count": 2500 }, "signature": "..." }],
"reporting": { "required": true, "window": "86400s", "required_fields": ["transaction_id", "function", "consumed_quantity"] },
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED"
}
],
"signature": "base64-ed25519-sig-B...",
"signature_algorithm": "EdDSA"
}
]
},
{
"uri": "https://theverge.com/premium/ai-regulation-republish.html",
"offers": [],
"absence_reason": "OFFER_ABSENCE_REASON_NOT_IN_CATALOG"
}
]
}

Note: SSP-Alpha returns an empty offers array for the theverge.com URI with absence_reason: NOT_IN_CATALOG because The Verge is not an SSP-Alpha tenant. This v1.0 diagnostic lets the Broker distinguish “not in catalog” from “resource blocked for your use case.” The Broker also queries SSP-Beta:

// SSP-Beta returns (single-URI, flat offers):
{
"ver": "1.0",
"exchange": "exchange.ssp-beta.com",
"offers": [
{
"offer_id": "ecb6fef4-1d83-4751-ab92-b3bc7c2fee39",
"exchange": "exchange.ssp-beta.com",
"pricing": { "model": "PRICING_MODEL_PER_UNIT", "rate": "0.07", "currency": "USD", "unit": "accesses", "unit_cost": "0.00002258", "estimated_quantity": 1 },
"identity": {
"canonical_url": "https://theverge.com/premium/ai-regulation-republish.html",
"iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001",
"content_hash": "a1b2c3d4e5f7...",
"hash_method": "simhash-v1"
},
"attestations": [{ "verifier": "gumgum.com", "claims": { "estimated_quantity": 3100, "word_count": 2350 }, "signature": "..." }],
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED"
}
],
"signature": "base64-ed25519-sig-C...",
"signature_algorithm": "EdDSA"
}
]
}

Content Deduplication: IPTC GUID + SimHash Fallback

Section titled “Content Deduplication: IPTC GUID + SimHash Fallback”

The Broker groups offers by content identity:

Step 1: Group by iptc_guid
- iptc_guid "urn:newsml:techcrunch:20260315:ai-reg-001" matches across all 3 offers
- These are ALL the same underlying article (TechCrunch original, syndicated to The Verge)
Step 2: SimHash cross-check (for non-news content without IPTC guids)
- SSP-Alpha hash: "a1b2c3d4e5f6..." (simhash-v1)
- SSP-Beta hash: "a1b2c3d4e5f7..." (simhash-v1)
- Hamming distance = 1 bit -> substantially similar (threshold < 3 bits)
- For 99% of web content that lacks IPTC guids, SimHash is the primary dedup signal.
The Exchange computes SimHash during ingestion from extracted article text.
The Broker groups by SimHash similarity (Hamming distance).
This is approximate but catches obvious syndication and republication.
Step 3: Rank within content group
Priority order:
a) Subscription from preferred exchange
-> 4f155204-a53e-42aa-8471-154f87d7d3d5 ($0, SSP-Alpha, attested by gumgum.com) <- WINNER
b) Subscription from any exchange
-> none
c) Per-request from preferred exchange (rank by attestation trust, then unit_cost)
-> 2325749d-50d3-431a-ac34-900d443ee88e ($0.05, SSP-Alpha, attested by gumgum.com)
d) Per-request by unit_cost (all exchanges)
-> ecb6fef4-1d83-4751-ab92-b3bc7c2fee39 ($0.07, SSP-Beta, attested by gumgum.com)
Note: attestation claims enable selection beyond cheapest price.
Offers with third-party attestations (Level 2) are preferred over
self-attested (Level 1) or unattested (Level 0) content.
Selected: 4f155204-a53e-42aa-8471-154f87d7d3d5 (subscription, zero marginal cost, third-party attested)
Step 4: Budget filter (applied before the offers are returned)
- Spend so far for scope "team:claude-rag", as this Broker counts it: $142.50
of the $500.00 period budget. Resolve never charges.
- An offer that would take spend past $500.00 is dropped from the result.
All three offers fit, so none is dropped. If none had fitted, the URI would
come back with OFFER_ABSENCE_REASON_BUDGET_EXCEEDED (a "no result", not an error).
- Subscription offer: cost = $0 -> fits any budget

Phase 3: Transaction (Requester + Request Signature, Subscription Skip, Quota Check)

Section titled “Phase 3: Transaction (Requester + Request Signature, Subscription Skip, Quota Check)”

SDK or Broker commits to the subscription offer.

Direct (SDK) request — single signature in the headers:

Section titled “Direct (SDK) request — single signature in the headers:”

POST https://exchange.ssp-alpha.com/fora/v1/fora.v1.ExchangeService/ExecuteTransaction

{
"ver": "1.0",
"idempotency_key": "tx-claude-001",
"requester": {
"id": "claude-agent-001",
"domain": "claude.ai",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
},
"items": [
{
"offer": {
"offer_id": "4f155204-a53e-42aa-8471-154f87d7d3d5",
"exchange": "exchange.ssp-alpha.com",
"title": "AI Regulation: What Providers Need to Know",
"pricing": {
"model": "PRICING_MODEL_FREE",
"rate": "0",
"currency": "USD",
"unit_cost": "0",
"estimated_quantity": 3300
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"subscription_id": "SUB-ANTHROPIC-HEARST-2026",
"expires_at": "2026-03-15T14:00:00Z",
"identity": {
"canonical_url": "https://techcrunch.com/premium/ai-regulation-2026.html",
"iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001",
"content_hash": "a1b2c3d4e5f6...",
"hash_method": "simhash-v1",
"resource_mutability": "RESOURCE_MUTABILITY_STATIC"
},
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED"
}
],
"signature": "base64-ed25519-sig-B...",
"signature_algorithm": "EdDSA"
},
"agent_acceptance": {
"signature": "base64-ed25519-acceptance-sig...",
"signature_algorithm": "EdDSA"
}
}
]
}

Orchestrated request — bought through the Broker:

Section titled “Orchestrated request — bought through the Broker:”

The agent sends the purchase to the Broker, POST https://broker.example/fora.v1.BrokerService/ExecuteTransaction, signed for the Broker’s URL. The Broker re-packages it and sends SSP-Alpha’s Exchange its own sub-request:

POST https://exchange.ssp-alpha.com/fora/v1/fora.v1.ExchangeService/ExecuteTransaction

{
"ver": "1.0",
"idempotency_key": "tx-claude-001",
"requester": {
"id": "claude-agent-001",
"domain": "claude.ai",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
},
"items": [
{
"offer": {
"offer_id": "4f155204-a53e-42aa-8471-154f87d7d3d5",
"exchange": "exchange.ssp-alpha.com",
"title": "AI Regulation: What Providers Need to Know",
"pricing": {
"model": "PRICING_MODEL_FREE",
"rate": "0",
"currency": "USD",
"unit_cost": "0",
"estimated_quantity": 3300
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"subscription_id": "SUB-ANTHROPIC-HEARST-2026",
"expires_at": "2026-03-15T14:00:00Z",
"identity": {
"canonical_url": "https://techcrunch.com/premium/ai-regulation-2026.html",
"iptc_guid": "urn:newsml:techcrunch:20260315:ai-reg-001",
"content_hash": "a1b2c3d4e5f6...",
"hash_method": "simhash-v1",
"resource_mutability": "RESOURCE_MUTABILITY_STATIC"
},
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED"
}
],
"signature": "base64-ed25519-sig-B...",
"signature_algorithm": "EdDSA"
},
"agent_acceptance": {
"signature": "base64-ed25519-acceptance-sig...",
"signature_algorithm": "EdDSA"
}
}
]
}

The sub-request body carries SSP-Alpha’s items exactly as the agent signed them, with the agent’s agent_acceptance on each item, its agent_request_acceptance, its requester and its idempotency_key unchanged. The Broker re-packaged this request for SSP-Alpha and signs it alone, with its own labeled RFC 9421 signature covering its own request components and only its own Signature-Agent member. The Exchange authenticates the caller as the Broker (its public key selected by keyid thumbprint in the directory the Broker’s Signature-Agent member names). The agent’s identity and consent are verified from the body: each agent_acceptance is a detached Ed25519 signature over {offer_sig, requester_id, requester_domain, idempotency_key}, which the Exchange verifies against the agent’s registered key, resolved from requester.domain (claude.ai/.well-known/http-message-signatures-directory), and the request acceptance proves these items are the complete in-order set addressed to SSP-Alpha. That key also gives the delivery-URL binding, and a delegation’s cnf.jkt would be checked against it. The Broker returns SSP-Alpha’s answer to the agent inside a BrokerTransactionResponse, alongside the results of any other Exchange in the same purchase.

1. Validate request (proto validation) -> pass
2. Verify the sender's RFC 9421 HTTP Message Signature (alg=ed25519), the
Broker's label:
- Fetch the Broker's public key from the directory its own covered
Signature-Agent member names (key by keyid thumbprint)
- Ed25519 verify -> pass; the caller is the Broker
2b. Verify the agent's agent_acceptance on each item against the agent's
registered key, resolved from requester.domain
(claude.ai/.well-known/http-message-signatures-directory) -> pass
2c. Verify `agent_request_acceptance` when the request carries it (this example
omits the optional field): Ed25519 verify the signed request set against the
requester's published agent key, then require this request's items to be the
complete in-order projection addressed to this Exchange. This runs before
the idempotency check — see
[Projected execute requests](/protocol/authentication/#projected-execute-requests)
3. Check idempotency: tx-claude-001 not seen before -> proceed
4. Verify offer signature:
- Ed25519 verify exchange_signature on offer -> pass
- Reconstruct offer data from signed token (stateless, no offer storage)
5. subscription_id present on offer -> SKIP billing.Authorize (already paid under subscription)
6. Quota check, on the agent's account: the purchase is Anthropic's, resolved
from requester.domain once the agent_acceptance verified in step 2b, never
the Broker's:
- BillingAdapter.CheckSubscription("acct_7f3e21c9", "hearst-media")
-> quota_remaining: 850000 tokens
- Estimated consumption: 3300 tokens
- 850000 > 3300 -> sufficient quota, proceed
- Deduct 3300 from quota -> new remaining: 846700
7. Compute agent identity hash:
agentHash = RFC 7638 JWK thumbprint of the agent's public key
= the key agent_acceptance was just verified with in step 2b
(the Broker signed the transport request, so its keyid is not it)
= "NzbLsXh8..."
(A hash of the agent's id and domain would bind nothing: the edge checks the
hash against a key the fetcher must prove it holds, and anyone can recompute
a hash of two public identifiers.)
8. Write transaction log (WAL) — MUST succeed before signing URL:
{
transaction_id: "txn-alpha-001",
billing_id: "bill-sub-alpha-001",
offer_id: "4f155204-a53e-42aa-8471-154f87d7d3d5",
subscription_id: "SUB-ANTHROPIC-HEARST-2026",
amount: "0",
agent_identity_hash: "NzbLsXh8...",
offer_snapshot_json: "<full offer at transaction time, including exchange_signature>",
reporting_required: true,
reporting_deadline: "2026-03-16T15:00:00Z"
}
9. Sign the delivery URL (Ed25519, tenant signing key — a different key from the
Ed25519 offer signing key, verified by a different party):
canonical = "GET\n" + <the URL below without its sig parameter, query sorted>
sig = base64url(Ed25519-sign(canonical, tenant private key))
Signed URL:
https://cdn.techcrunch.com/server/premium/ai-regulation-2026.html
?agent_id=NzbLsXh8...
&exp=1710517800
&kid=vJ3xR1mQ...
&sig=k7Qm2xR9vT4nB8aL...
10. Create reporting obligation: due by 2026-03-16T15:00:00Z
{
"ver": "1.0",
"agent_identity_hash": "NzbLsXh8...",
"items": [
{
"transaction_id": "txn-alpha-001",
"billing_id": "bill-sub-alpha-001",
"resource_title": "AI Regulation: What Providers Need to Know",
"retrieval_endpoint": "https://cdn.techcrunch.com/server/premium/ai-regulation-2026.html?agent_id=NzbLsXh8...&exp=1710517800&kid=vJ3xR1mQ...&sig=k7Qm2xR9vT4nB8aL...",
"cost": { "amount": "0", "currency": "USD", "unit_cost": "0" },
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"subscription_id": "SUB-ANTHROPIC-HEARST-2026",
"subscription_unit_value": { "amount": "0.05", "currency": "USD", "unit_cost": "0.00001515" },
"reporting_obligation": {
"required": true,
"window": "86400s",
"required_fields": ["transaction_id", "function", "consumed_quantity"]
},
"expires_at": "2026-03-15T15:30:00Z"
}
]
}

The subscription_unit_value field carries the per-unit cost ($0.05) even though cost.amount is 0. This enables financial attribution under ASC 606 prepaid drawdown accounting: Anthropic can track the value of content consumed against the subscription’s total prepaid amount.


Phase 4: Content Fetch (Ed25519 Signed URL, Agent Identity Binding)

Section titled “Phase 4: Content Fetch (Ed25519 Signed URL, Agent Identity Binding)”
Agent -> CDN: GET https://cdn.techcrunch.com/server/premium/ai-regulation-2026.html
?agent_id=NzbLsXh8...
&exp=1710517800
&kid=vJ3xR1mQ...
&sig=k7Qm2xR9vT4nB8aL...
Header: X-FORA-Agent-Key: <agent public key, base64url>
Header: Signature-Agent: sig1="https://claude.ai"
Header: Signature-Input: sig1=("@method" "@target-uri" "signature-agent";key="sig1");created=...;expires=...;keyid=...;alg="ed25519";nonce=...;tag="web-bot-auth"
Header: Signature: sig1=:<standard base64>:
Edge Function:
1. Has a sig param? YES
2. Resolve kid to a public key from the Exchange key directory (cached)
3. Verify the Ed25519 signature over "GET\n<URL without sig, query sorted>" -> PASS
4. Check expiry: exp > now? -> PASS (URL valid for 5 minutes)
5. Check agent identity binding:
thumbprint(presented public key) == agent_id == keyid? -> PASS
Verify the Web Bot Auth signature with that key (proof of possession) -> PASS
(The agent must hold the private half; presenting the public key is not enough)
6. Strip agent_id, exp, kid, sig -> CDN serves content from S3/origin
CDN access log records:
- URL with all params (agent_id, exp, kid, sig)
- Client IP, timestamp, bytes transferred, HTTP 200
- This log is controlled by the provider (Hearst) and used for reconciliation

Canonical message: the literal GET, one newline, then the whole URL with the sig parameter removed and the remaining query sorted by key — so scheme, host, path and every other parameter are covered. The delivery-URL signature and the offer signature are both Ed25519; they use different keys and are verified by different parties. See Signed URL Verification.


Phase 5: Usage Reporting (Mandatory, with Token Count)

Section titled “Phase 5: Usage Reporting (Mandatory, with Token Count)”

The SDK auto-submits a usage report (background, non-blocking). Usage reporting is mandatory for subscription transactions — failure to report within the window triggers DENIAL_REASON_REPORTING_OVERDUE on subsequent transactions.

POST https://exchange.ssp-alpha.com/fora/v1/fora.v1.ExchangeService/ReportUsage

{
"ver": "1.0",
"exchange": "exchange.ssp-alpha.com",
"idempotency_key": "ur-claude-001",
"transaction_id": "txn-alpha-001",
"billing_id": "bill-sub-alpha-001",
"usage": {
"function": ["ai-input"],
"subfn": ["rag"],
"consumed_quantity": 3150,
"displayed_to_user": true,
"citation_included": true
},
"timestamp": "2026-03-15T15:30:00Z",
"assets": [
{
"uri": "https://techcrunch.com/premium/ai-regulation-2026.html",
"title": "AI Regulation: What Providers Need to Know"
}
]
}
1. Validate request fields -> pass
2. Lookup transaction: txn-alpha-001 -> found, billing_id matches -> pass
3. Submit to Reporting Tracker:
a. Validate required_fields present: transaction_id, function, consumed_quantity -> all present
b. Check reporting window: deadline 2026-03-16T15:00:00Z, current time 2026-03-15T15:30:00Z -> within window
c. Record consumed_quantity: 3150 actual vs 3300 estimated -> a difference is never a refusal; the report records it
d. Transition obligation: Pending -> Fulfilled
4. Write usage report to transaction log (durable)
{
"ver": "1.0",
"report_id": "rpt-001"
}

A successful UsageReportResponse carries only the Exchange-assigned report_id (the durable identity the agent references when filing a dispute). A rejected report is not a success body — it travels as a non-OK transport error carrying ErrorDetail.usageReportRejection (e.g. { "usage_report_rejection": { "reason": "USAGE_REPORT_REJECTION_REASON_WINDOW_EXPIRED" } } with the Connect code failed_precondition for a report past its window). A report is never refused because its quantity differs from the estimate.


Three independent records that must agree:

1. Edge delivery log (Hearst controls):
- url_hash=9f2c7a4e... fetched at 15:25:00, 200 OK, 45KB
- agent_id=NzbLsXh8..., signature and agent binding verified by the edge
2. Exchange transaction log (SSP-Alpha controls):
- txn-alpha-001: signed_url_hash=9f2c7a4e... (the join key to the log above)
- subscription SUB-ANTHROPIC-HEARST-2026, amount=$0
- subscription_unit_value: $0.05 (value of the access for accounting)
- offer_snapshot: article "AI Regulation...", 3300 est tokens
- offer_snapshot includes exchange_signature (Ed25519, non-repudiable)
- reporting_deadline: 2026-03-16T15:00:00Z
3. Usage report (Anthropic filed):
- txn-alpha-001: 3150 actual tokens, function=ai-input, citation=yes
- Filed at 15:30:00, within reporting window
PASS: CDN log has txn-alpha-001 -> content was actually served
PASS: Exchange has txn-alpha-001 -> transaction was authorized
PASS: Usage report received before deadline -> reporting obligation fulfilled
PASS: Token count 3150 vs estimate 3300 -> below the estimate, so settled as consumed
PASS: Function ai-input matches the term's RESTRICTION_KIND_FUNCTION permitted list
PASS: Citation included as required by the Offer's attribution terms

Hearst queries the Exchange’s provider audit API to independently verify all transactions for their content:

GET https://exchange.ssp-alpha.com/provider/techcrunch.com/transactions
?from=2026-03-15T00:00:00Z
&to=2026-03-16T00:00:00Z

Response includes signed Offer snapshots for every transaction:

{
"transactions": [
{
"transaction_id": "txn-alpha-001",
"billing_id": "bill-sub-alpha-001",
"offer_snapshot": {
"offer_id": "4f155204-a53e-42aa-8471-154f87d7d3d5",
"exchange": "exchange.ssp-alpha.com",
"pricing": { "model": "PRICING_MODEL_FREE", "rate": "0", "currency": "USD" },
"subscription_id": "SUB-ANTHROPIC-HEARST-2026",
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED"
}
],
"signature": "base64-ed25519-sig-B...",
"signature_algorithm": "EdDSA"
},
"cost": { "amount": "0", "currency": "USD" },
"subscription_unit_value": { "amount": "0.05", "currency": "USD" },
"agent_id": "NzbLsXh8...",
"timestamp": "2026-03-15T15:25:00Z"
}
]
}

What Hearst can verify:

  1. Offer authenticity: Hearst verifies the exchange_signature on each offer_snapshot using SSP-Alpha’s published Ed25519 public key (fetch SSP-Alpha’s WBA directory at exchange.ssp-alpha.com/.well-known/http-message-signatures-directory and read its keys). This proves the Exchange actually issued this Offer — it cannot deny having offered these terms.

  2. RSL price ceiling compliance: Hearst’s RSL declares a maximum rate of $0.08/crawl. The subscription’s subscription_unit_value of $0.05 is below this ceiling. If any per-request Offer exceeded $0.08, Hearst would detect it by comparing offer_snapshot.pricing.rate against their RSL terms.

  3. Private floor compliance: Hearst’s contract with SSP-Alpha specifies a private minimum rate of $0.04/article. The subscription_unit_value of $0.05 is above this floor. Private floor pricing is contractual (not protocol-enforced), but the audit data makes violations detectable.

Under subscription SUB-ANTHROPIC-HEARST-2026, Anthropic consumed
3,150 tokens from "AI Regulation: What Providers Need to Know"
for RAG/grounding. Citation was included. Value: $0.05 per article.

This data feeds into Hearst’s subscription renewal negotiation:

"Anthropic consumed 2.3M tokens from TechCrunch last quarter under
the current deal at $0.05/article. Given our RSL ceiling of $0.08
and the volume, we want to renegotiate to $0.06 for next year."

Phase 7: Dispute Resolution (v1.0 — When Things Go Wrong)

Section titled “Phase 7: Dispute Resolution (v1.0 — When Things Go Wrong)”

If the content delivered by the CDN does not match what was promised in the Offer, the agent can file a dispute. The dispute chain enforces a strict order: the agent MUST have filed a UsageReport (Phase 5) before disputing.

Agent verifies delivered content:
1. Compute SimHash of received HTML -> "a1b2c3d4e5f9..."
2. Compare with Offer's identity.content_hash -> "a1b2c3d4e5f6..."
3. Hamming distance = 2 bits -> within SimHash tolerance (threshold 3)
4. No dispute needed (content is substantially similar)
But if Hamming distance > threshold, or content is entirely different:
Agent files DisputeTransaction
POST https://exchange.ssp-alpha.com/fora/v1/fora.v1.ExchangeService/DisputeTransaction
{
"ver": "1.0",
"transaction_id": "txn-alpha-001",
"billing_id": "bill-sub-alpha-001",
"report_id": "rpt-001",
"reason": "DISPUTE_REASON_CONTENT_MISMATCH",
"description": "Content hash differs from offer: expected a1b2c3d4e5f6, received a1b2c3d4ffff",
"received_content_hash": "a1b2c3d4ffff...",
"received_hash_method": "simhash-v1"
}
{
"dispute_id": "disp-alpha-001",
"status": "DISPUTE_STATUS_AUTO_RESOLVED",
"resolution": "RESOLUTION_TYPE_CREDIT",
"estimated_resolution": "2026-03-15T16:00:00Z"
}

Three-tier resolution: Tier 1 automated (<1s, auto-disputable claims like CDN failure or hash mismatch), Tier 2 rule-based (<24h), Tier 3 pattern investigation (async). The dispute lifecycle progresses through: FILED -> AUTO_RESOLVED / EVIDENCE_NEEDED -> UNDER_REVIEW -> RESOLVED -> FINAL. Appeals re-enter UNDER_REVIEW.


What the Broker Adds (Cross-Provider Intelligence)

Section titled “What the Broker Adds (Cross-Provider Intelligence)”

Without Broker (SDK only): the agent found the article via SSP-Alpha (from fora.json) and got the subscription deal. It never knew The Verge also had the article at $0.07 via SSP-Beta.

With Broker: it queried both Exchanges, discovered the same article via iptc_guid match (confirmed by SimHash similarity), received attestation data from both sources, and still chose the subscription offer — but now Anthropic has intelligence:

"This article is available from two sources:
- SSP-Alpha (TechCrunch, subscription, $0/request, third-party attested by gumgum.com)
- SSP-Beta (The Verge, per-request, $0.07/request, third-party attested by gumgum.com)
Our subscription saves us $0.07 per request from the alternative source.
At 10K requests/month for this provider's content, that's $700/month
in avoided per-request costs — data for the subscription renewal.
Both sources carry Level 2 (third-party) attestations from gumgum.com.
TechCrunch original has higher word_count (2500 vs 2350) — more complete."

This is the Broker’s value: not just cheapest price, but market intelligence for subscription negotiations and attestation-aware content selection.