Skip to content

RAMP v1.0 Walkthrough

Complete walkthrough of RAMP v1.0 as of March 2026. Every field name, message structure, and authentication mechanism matches the current ramp.proto. Two scenarios demonstrate how the same protocol handles pay-per-article and subscription access.

This walkthrough covers two real-world scenarios that exercise different parts of the RAMP v1.0 protocol:

Scenario AScenario B
Agentresearch-bot at startup.comhedge-bot at hedgefund.com
ContentTechCrunch article (news)MarketData earnings transcript (financial)
SubscriptionNoneMarketData enterprise subscription
DelegationNonedelegation JWT from marketdata.example.com
Cost$0.05 per article$0.00 (subscription)

Both scenarios follow the same six-step flow:

Discovery → ResourceQuery → ResourceResponse → ExecuteTransaction → Fetch → ReportUsage

Scenario A: Simple Article Access (No Subscription)

Section titled “Scenario A: Simple Article Access (No Subscription)”

An AI research agent at a startup wants a TechCrunch article about AI agents in commerce. No subscription exists — the agent pays per article.

The agent resolves the target domain’s RAMP configuration. Every RAMP-enabled domain publishes a machine-readable manifest at /.well-known/ramp.json:

Terminal window
curl -s https://techcrunch.com/.well-known/ramp.json | jq
{
"ver": "1.0",
"provider": "techcrunch.com",
"contact": "licensing@techcrunch.com",
"exchanges": [
{
"domain": "exchange.ssp-alpha.com",
"endpoint": "https://exchange.ssp-alpha.com/ramp/v1",
"relationship": "PROVIDER_RELATIONSHIP_DIRECT"
}
],
"supported_profiles": ["ramp-news-v1"]
}

The agent now knows which Exchange to query for TechCrunch content. The supported_profiles field tells the agent that this Exchange supports news-specific metadata extensions.

The agent sends a ResourceQuery to the Exchange with its identity in the Requester message. This is the v1.0 replacement for CoMP’s AISystem — it carries identity, scopes, and optional delegation in a single envelope. The request is authenticated separately by an RFC 9421 HTTP Message Signature in the HTTP headers, not by a field in the message body.

POST https://exchange.ssp-alpha.com/ramp/v1/ramp.v1.ExchangeService/DiscoverResources
{
"ver": "1.0",
"id": "sq-001",
"uris": [
"https://techcrunch.com/2026/03/19/ai-agents-commerce.html"
],
"acceptable_restrictions": [
{ "axis": "FUNCTION", "values": ["ai-input"] }
],
"requester": {
"id": "research-bot",
"domain": "startup.com",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
}
}

Key fields in Requester:

  • id + domain — uniquely identifies the agent. The Exchange fetches the agent’s Ed25519 public key from startup.com/.well-known/ramp.json (role=ROLE_AGENT) to verify the request’s RFC 9421 HTTP Message Signature.
  • typeREQUESTER_TYPE_AGENT (autonomous AI agent). Other types: HUMAN_TOOL, SERVICE, DELEGATED, RESEARCH.
  • ResourceQuery.uris — the specific resources being requested (a sibling of requester, not part of the identity envelope).
  • acceptable_restrictions — the query’s restriction tolerances (here axis FUNCTION with ai-input); a sibling of requester.
  • scopes["*"] means unrestricted public access. No subscription, no entitlement filtering.
  • Request signature — an RFC 9421 HTTP Message Signature over the HTTP request (method, target URI, and a Content-Digest of the body), carried in the Signature / Signature-Input headers. Proves the request came from this agent. The Requester message itself carries no signature field.
  • No delegation field — this agent acts on its own behalf, not under a delegated credential.

The Exchange looks up the article in its catalog and returns an offer. It does not filter the offer against the query’s acceptable_restrictions — the restrictions ride on the offer’s terms, and the agent self-selects the term whose RESTRICTION_KIND_FUNCTION permitted list covers its intended use (ai-input); enforcement happens downstream at accept → report → reconcile:

{
"ver": "1.0",
"id": "sq-001",
"exchange": "exchange.ssp-alpha.com",
"offer_groups": [
{
"uri": "https://techcrunch.com/2026/03/19/ai-agents-commerce.html",
"offers": [
{
"offer_id": "offer-tc-agents-001",
"title": "AI Agents Are Rewriting Commerce",
"ext": {
"comp.package_id": "PKG-TC-AGENTS-COMMERCE",
"comp.seller": "techcrunch.com",
"comp.citation_required": true,
"comp.retrieval_type": ["RETRIEVAL_TYPE_HTML"]
},
"pricing": {
"model": "PRICING_MODEL_PER_UNIT",
"rate": 0.05,
"currency": "USD",
"unit_cost": 0.0000156,
"estimated_quantity": 3200,
"unit": "accesses"
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"reporting": {
"required": true,
"window": "86400s",
"required_fields": ["consumed_quantity"]
},
"identity": {
"canonical_url": "https://techcrunch.com/2026/03/19/ai-agents-commerce.html",
"content_hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"hash_method": "sha256",
"resource_mutability": "RESOURCE_MUTABILITY_STATIC"
},
"attestations": [
{
"verifier": "techcrunch.com",
"kid": "tc-key-2026-03",
"attested_at": "2026-03-19T10:00:00Z",
"uri": "https://techcrunch.com/2026/03/19/ai-agents-commerce.html",
"claims": {
"estimated_quantity": 3200,
"word_count": 2400,
"language": "en"
},
"signature": "base64-ed25519-tc-self-attestation..."
}
],
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED",
"restrictions": [
{
"kind": "RESTRICTION_KIND_FUNCTION",
"permitted": ["ai-input", "ai-index", "search"],
"prohibited": ["ai-train"]
}
]
}
],
"signature": "base64-ed25519-offer-sig...",
"signature_algorithm": "EdDSA"
}
]
}
]
}

What the agent learns from this response:

  • Pricing: PRICING_MODEL_PER_UNIT (unit: "accesses") at $0.05, with an estimated 3,200 tokens. The unit_cost ($0.0000156/token) enables cross-exchange comparison when a Broker aggregates offers.
  • Content mutability: RESOURCE_MUTABILITY_STATIC — this article will not change. The agent SHOULD verify the SHA-256 hash on delivery. A mismatch is disputable.
  • Attestation: Level 1 (self-attested by techcrunch.com). The provider signed its own claims about word count and token estimate. A third-party attestation (Level 2, e.g., from gumgum.com) would carry higher trust.
  • Restrictions: AI input (ai-input), indexing (ai-index), and search (search) are permitted. Training (ai-train) is prohibited.
  • signature (the exchange signature): Ed25519 signature over the entire offer. The Exchange will verify this same signature when the agent commits to the offer — no server-side offer storage needed (stateless verification).

The agent commits to the offer by sending the offer_id and the offer’s signature echoed back as offer_signature:

POST https://exchange.ssp-alpha.com/ramp/v1/ramp.v1.ExchangeService/ExecuteTransaction
{
"ver": "1.0",
"id": "tx-001",
"offer_id": "offer-tc-agents-001",
"offer_signature": "base64-ed25519-offer-sig...",
"requester": {
"id": "research-bot",
"domain": "startup.com",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["*"]
}
}

The Exchange performs:

  1. Signature verification — verifies the offer_signature is its own Ed25519 signature (stateless, no stored offers).
  2. Agent authentication — verifies the request’s RFC 9421 HTTP Message Signature against the agent’s published public key.
  3. Balance check — confirms research-bot@startup.com has sufficient balance ($0.05).
  4. WAL write — records the transaction in the write-ahead log before generating the signed URL (write-before-sign invariant).
  5. Signed URL generation — HMAC-SHA256 over (base_url, expires, agent_id, txn_id) using the Exchange-CDN shared secret.

Response:

{
"ver": "1.0",
"id": "tx-001",
"transaction_id": "txn-tc-001",
"billing_id": "bill-tc-001",
"retrieval_endpoint": "https://cdn.techcrunch.com/premium/ai-agents-commerce.html?expires=1742403900&agent_id=7a3f8c1d...&txn_id=txn-tc-001&sig=hmac-sha256-d4e5f6...",
"cost": {
"amount": 0.05,
"currency": "USD"
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"reporting_obligation": {
"required": true,
"window": "86400s",
"required_fields": ["consumed_quantity"]
},
"expires_at": "2026-03-19T12:05:00Z",
"agent_identity_hash": "7a3f8c1d..."
}

The signed URL is valid for 5 minutes. The agent_identity_hash (the agent’s RFC 7638 JWK Thumbprint) is embedded in the URL, preventing URL sharing between agents.

The agent fetches the content via the signed URL:

Terminal window
GET https://cdn.techcrunch.com/premium/ai-agents-commerce.html?expires=1742403900&agent_id=7a3f8c1d...&txn_id=txn-tc-001&sig=hmac-sha256-d4e5f6...

The CDN edge function verifies:

  1. HMAC-SHA256 signature matches (Exchange-CDN shared secret)
  2. URL has not expired
  3. agent_id in URL matches the requesting agent’s identity hash
  4. txn_id is recorded for three-sided reconciliation

Content hash verification: Because resource_mutability is STATIC, the agent computes SHA-256 of the delivered HTML and compares it against identity.content_hash from the offer. Match confirms the content is exactly what was promised. Mismatch would be grounds for a DisputeTransaction.

Usage reporting is mandatory. The agent reports actual consumption:

POST https://exchange.ssp-alpha.com/ramp/v1/ramp.v1.ExchangeService/ReportUsage
{
"ver": "1.0",
"id": "ur-001",
"transaction_id": "txn-tc-001",
"billing_id": "bill-tc-001",
"usage": {
"function": ["ai-input"],
"consumed_quantity": 3150,
"consumed_unit": "tokens",
"displayed_to_user": true,
"citation_included": true
},
"timestamp": "2026-03-19T12:01:00Z",
"assets": [
{
"uri": "https://techcrunch.com/2026/03/19/ai-agents-commerce.html",
"title": "AI Agents Are Rewriting Commerce",
"package_id": "PKG-TC-AGENTS-COMMERCE"
}
]
}

Response:

{
"accepted": true,
"report_id": "rpt-tc-001"
}

The report_id enables the dispute chain: if the agent needs to dispute this transaction later, it must reference this report to prove usage was reported first.


Scenario B: Subscription Access (MarketData Earnings Transcript)

Section titled “Scenario B: Subscription Access (MarketData Earnings Transcript)”

A hedge fund’s AI agent wants an NVIDIA earnings call transcript from MarketData. The hedge fund has an enterprise MarketData subscription. The agent carries a delegation JWT that proves its entitlement — without MarketData needing to be online at request time.

Same pattern as Scenario A. The agent resolves MarketData’s RAMP manifest:

Terminal window
curl -s https://marketdata.example.com/.well-known/ramp.json | jq
{
"ver": "1.0",
"provider": "marketdata.example.com",
"contact": "data-licensing@marketdata.example.com",
"exchanges": [
{
"domain": "exchange.marketdata-data.com",
"endpoint": "https://exchange.marketdata-data.com/ramp/v1",
"relationship": "PROVIDER_RELATIONSHIP_DIRECT"
}
],
"supported_profiles": ["ramp-finance-v1"]
}

Step 2 — ResourceQuery with Delegation (JWT)

Section titled “Step 2 — ResourceQuery with Delegation (JWT)”

Here is where v1.0’s Requester + Delegation model shows its power. The agent includes a delegation JWT that carries its subscription entitlement:

POST https://exchange.marketdata-data.com/ramp/v1/ramp.v1.ExchangeService/DiscoverResources
{
"ver": "1.0",
"id": "sq-bb-001",
"uris": [
"https://marketdata.example.com/earnings/NVDA/2026-Q1-transcript"
],
"acceptable_restrictions": [
{ "axis": "FUNCTION", "values": ["ai-input"] }
],
"requester": {
"id": "hedge-bot",
"domain": "hedgefund.com",
"type": "REQUESTER_TYPE_AGENT",
"scopes": ["quote:*", "earnings:*", "news:read"],
"delegation": {
"principal_domain": "marketdata.example.com",
"principal_id": "enterprise-sub-HF-001",
"scopes": ["quote:*", "earnings:*", "news:read"],
"expires_at": "2026-12-31T23:59:59Z",
"token": "eyJhbGciOiJFZERTQSJ9.<claims: iss, scope, exp, cnf.jkt>.<sig>",
"token_format": "jwt"
}
},
"supported_profiles": ["ramp-finance-v1"]
}

What happens with the delegation token (JWT):

The delegation.token is an authority JWT, signed by MarketData’s Ed25519 key. Its claims carry the grant:

{
"iss": "marketdata.example.com",
"sub": "enterprise-sub-HF-001",
"scope": "quote:* earnings:* news:read",
"exp": 1798761599,
"cnf": { "jkt": "<thumbprint of the agent's key>" }
}

The Exchange verifies the JWT chain:

  1. Signature check — the authority JWT is signed by marketdata.example.com’s Ed25519 key (fetched from marketdata.example.com/.well-known/ramp.json, role=ROLE_AGENT). This proves MarketData actually issued this delegation.
  2. Scope matching — the requested URI (/earnings/NVDA/...) matches the earnings:* scope in the JWT.
  3. Expiry checkexp is in the future.
  4. Holder binding — the key that signed the request (RFC 9421) MUST hash to the final cnf.jkt, so a stolen token is useless without the matching private key.
  5. No network call to MarketData — delegation JWTs are offline-verifiable. MarketData does not need to be online or queried. This is the key property that makes delegation scale.

Narrowing the grant: If the hedge fund wanted to restrict its agent further (e.g., limit to NVDA only, cap spend at $100), it issues a child delegation JWT (narrowing) — signed by the principal key named in the authority’s cnf and bound to the agent’s key — without going back to MarketData:

// child delegation JWT — signed by the principal key, bound to the agent
{
"iss": "hedgefund.com",
"scope": "earnings:NVDA",
"ramp_max_spend_cents": 10000,
"exp": 1798761599,
"cnf": { "jkt": "<thumbprint of the agent's key>" }
}

The Exchange verifies the JWT chain, confirms earnings:* covers the requested URI, and recognizes the subscription. It returns a zero-cost offer:

{
"ver": "1.0",
"id": "sq-bb-001",
"exchange": "exchange.marketdata-data.com",
"offer_groups": [
{
"uri": "https://marketdata.example.com/earnings/NVDA/2026-Q1-transcript",
"offers": [
{
"offer_id": "offer-bb-nvda-q1-001",
"title": "NVIDIA Corp Q1 2026 Earnings Call Transcript",
"ext": {
"comp.package_id": "PKG-BB-NVDA-Q1-TRANSCRIPT",
"comp.seller": "marketdata.example.com",
"comp.citation_required": true,
"comp.retrieval_type": ["RETRIEVAL_TYPE_HTML"]
},
"pricing": {
"model": "PRICING_MODEL_FREE",
"rate": 0,
"currency": "USD",
"unit_cost": 0,
"estimated_quantity": 18500,
"unit": "tokens"
},
"subscription_id": "enterprise-sub-HF-001",
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"reporting": {
"required": true,
"window": "86400s",
"required_fields": ["transaction_id", "function", "consumed_quantity"]
},
"identity": {
"canonical_url": "https://marketdata.example.com/earnings/NVDA/2026-Q1-transcript",
"content_hash": "sha256:3c7d8a2b1e9f4c6d5a0b7e8f2d1c3a4b5e6f7890abcdef1234567890abcdef12",
"hash_method": "sha256",
"resource_mutability": "RESOURCE_MUTABILITY_STATIC"
},
"attestations": [
{
"verifier": "marketdata.example.com",
"kid": "bb-key-2026-q1",
"attested_at": "2026-03-18T08:00:00Z",
"uri": "https://marketdata.example.com/earnings/NVDA/2026-Q1-transcript",
"claims": {
"estimated_quantity": 18500,
"word_count": 14200,
"language": "en"
},
"signature": "base64-ed25519-bb-self-attestation..."
}
],
"terms": [
{
"semantics": "TERM_SEMANTICS_ENUMERATED",
"restrictions": [
{
"kind": "RESTRICTION_KIND_FUNCTION",
"permitted": ["ai-input", "search"],
"prohibited": ["ai-train", "ai-index"]
}
],
"scopes": ["subscription:enterprise-sub-HF-001"]
}
],
"subscription_quota": [
{
"subscription_id": "enterprise-sub-HF-001",
"quota_limit": 50000,
"quota_used": 12400,
"quota_remaining": 37600,
"resets_at": "2026-04-01T00:00:00Z"
}
],
"signature": "base64-ed25519-bb-offer-sig...",
"signature_algorithm": "EdDSA"
}
]
}
]
}

Note the zero-cost offer and quota signaling: rate: 0, unit_cost: 0. The subscription_id confirms access is covered by the enterprise subscription. The hedge fund pays nothing per request — MarketData already collected the annual subscription fee.

The remaining steps follow the same pattern as Scenario A, with one key difference: cost is $0.00.

ExecuteTransaction — same request structure, Exchange returns cost.amount: 0 and subscription_id:

{
"ver": "1.0",
"id": "tx-bb-001",
"transaction_id": "txn-bb-001",
"billing_id": "bill-bb-sub-001",
"retrieval_endpoint": "https://cdn.marketdata.example.com/earnings/NVDA/2026-Q1-transcript.html?expires=1742404200&agent_id=8b4f9d2e...&txn_id=txn-bb-001&sig=hmac-sha256-a7b8c9...",
"cost": {
"amount": 0,
"currency": "USD"
},
"subscription_id": "enterprise-sub-HF-001",
"subscription_unit_value": {
"amount": 0.15,
"currency": "USD"
},
"delivery_method": "DELIVERY_METHOD_INSTRUCTIONS",
"reporting_obligation": {
"required": true,
"window": "86400s",
"required_fields": ["transaction_id", "function", "consumed_quantity"]
},
"expires_at": "2026-03-19T12:10:00Z",
"agent_identity_hash": "8b4f9d2e..."
}

The subscription_unit_value ($0.15) is the imputed value of this access for accounting purposes (ASC 606 prepaid drawdown). Cost is $0.00 because it is covered by the subscription.

Fetch — same signed URL pattern. Agent verifies SHA-256 hash.

ReportUsage — same structure, consumed_quantity: 18200, consumed_unit: "tokens". Usage is tracked against the subscription quota, not billed per request.


AspectWithout Subscription (Scenario A)With Subscription (Scenario B)
DelegationNonedelegation JWT from marketdata.example.com
Requester scopes["*"] (public)["earnings:*"] (from delegation JWT)
Offer pricing$0.05 per article$0.00 (subscription)
How Exchange knowsNo delegation, no subscription scope — per-articledelegation JWT carries subscription scope — zero cost
Round trips to provider00 (delegation JWT is offline-verifiable)
subscription_id in responseAbsent"enterprise-sub-HF-001"
Financial attributioncost.amount = 0.05cost.amount = 0, subscription_unit_value = 0.15

Developer’s Perspective: Same Code, Both Paths

Section titled “Developer’s Perspective: Same Code, Both Paths”

From the SDK, both scenarios use identical code. The Requester message carries the delegation (if present), and the SDK handles everything transparently:

// Scenario A: no delegation — SDK sends Requester without delegation field
result, err := ramp.Fetch(ctx, "https://techcrunch.com/2026/03/19/ai-agents-commerce.html")
// result.Cost = 0.05
// result.SubscriptionID = ""
// Scenario B: delegation present — SDK includes the delegation JWT in Requester.delegation
result, err := ramp.Fetch(ctx, "https://marketdata.example.com/earnings/NVDA/2026-Q1-transcript")
// result.Cost = 0.00
// result.SubscriptionID = "enterprise-sub-HF-001"

The SDK carries the delegation token automatically when configured. The agent code does not branch on subscription vs. pay-per-article — the protocol handles the routing:

client := ramp.NewClient(ramp.Config{
AgentID: "hedge-bot",
Domain: "hedgefund.com",
PrivateKey: ed25519PrivateKey,
// If delegation is set, SDK includes it in every Requester message.
// If not set, SDK sends Requester without delegation.
Delegation: delegationJWT, // nil for Scenario A, populated for Scenario B
})
// This call works identically in both scenarios.
// The Exchange decides the pricing path based on the Requester.
result, err := client.Fetch(ctx, url)

StepRPCScenario A (per-article)Scenario B (subscription)
1ramp.json discoveryramp.json discovery
2DiscoverResourcesRequester with no delegationRequester with Delegation (JWT)
3Offer at $0.05Offer at $0.00 + subscription_id
4ExecuteTransactionCharge $0.05, generate signed URLSkip billing (subscription), generate signed URL
5Fetch + SHA-256 verifyFetch + SHA-256 verify
6ReportUsageReport 3,150 tokens consumedReport 18,200 tokens consumed (tracked against quota)

Authentication at every step:

  • Agent → Exchange: RFC 9421 HTTP Message Signature (Ed25519 over the HTTP request — method, target URI, and body content digest — in the Signature / Signature-Input headers)
  • Delegation: delegation JWT signed by principal’s Ed25519 key, holder-of-key bound via cnf.jkt (offline-verifiable)
  • Exchange → Agent: exchange_signature on Offer (Ed25519, stateless verification)
  • Signed URLs: HMAC-SHA256 (Exchange-CDN shared secret, agent identity bound)