this repo has no description
attested.network/
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Scenarios — attested.network</title>
7 <meta name="description" content="Real-world usage scenarios for attested payments on ATProtocol.">
8 <link rel="preconnect" href="https://fonts.googleapis.com">
9 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
11 <link rel="icon" type="image/svg+xml" href="logo.svg">
12 <link rel="stylesheet" href="styles.css">
13 <script type="module">
14 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
15 mermaid.initialize({
16 startOnLoad: true,
17 theme: 'base',
18 themeVariables: {
19 primaryColor: '#f5f3ff',
20 primaryTextColor: '#111827',
21 primaryBorderColor: '#ddd6fe',
22 secondaryColor: '#f8f9fb',
23 tertiaryColor: '#ffffff',
24 lineColor: '#8b5cf6',
25 textColor: '#111827',
26 mainBkg: '#f5f3ff',
27 nodeBorder: '#ddd6fe',
28 clusterBkg: '#faf9fc',
29 clusterBorder: '#e5e7eb',
30 fontFamily: 'Inter, -apple-system, system-ui, sans-serif',
31 fontSize: '13px'
32 }
33 });
34 </script>
35</head>
36<body>
37
38<div class="draft-banner">
39 <p><strong>Draft — Not yet published.</strong> This specification is in active development and is not ready for review or critique. Stay tuned for formal announcements.</p>
40</div>
41
42<!-- Top navigation -->
43<div class="topnav">
44 <div class="topnav-inner">
45 <a class="topnav-logo" href="/"><img src="logo.svg" alt="" class="topnav-logo-img"><span><span>attested</span>.network</span></a>
46 <nav>
47 <ul class="topnav-links">
48 <li><a href="index.html">Spec</a></li>
49 <li><a href="brokers.html">Brokers</a></li>
50 <li><a href="app-developers.html">App Developers</a></li>
51 <li><a href="recipients.html">Recipients</a></li>
52 <li><a href="payers.html">Payers</a></li>
53 <li><a href="scenarios.html" class="active">Scenarios</a></li>
54 </ul>
55 </nav>
56 </div>
57</div>
58
59<!-- Hero -->
60<div class="hero-sm">
61 <div class="hero-inner">
62 <div class="breadcrumb"><a href="index.html">Home</a> / Scenarios</div>
63 <h1>Example <span>Scenarios</span></h1>
64 <p class="subtitle">Real-world usage patterns showing how attested payments work end-to-end.</p>
65 </div>
66</div>
67
68<main class="container">
69
70 <!-- Podcast Subscription -->
71 <section id="podcast-subscription">
72 <h2>Podcast Subscription</h2>
73 <p class="section-desc">A podcast offers a $10/month premium subscription. Supporters pay through a broker, which creates a recurring payment record with an entitlement that grants access to premium content. Any app, tile, or appview can verify the subscription by checking for an active payment with the matching entitlement.</p>
74
75 <h3>How it works</h3>
76 <p>The podcast creator publishes their content on ATProtocol and uses a broker to handle subscriptions. When a listener subscribes, three things happen:</p>
77
78 <ol class="steps">
79 <li>The listener’s client initiates a payment through the broker via <code>network.attested.payment.initiate</code></li>
80 <li>The broker processes the $10/month payment and writes a <code>network.attested.payment.recurring</code> record to the listener’s repository, including an <code>entitlements</code> reference pointing to the podcast’s product record</li>
81 <li>The broker and creator each write <code>payment.proof</code> attestation records to their own repositories, linked via the payment’s <code>signatures</code> array</li>
82 </ol>
83
84 <p>From that point on, any app can verify the subscription by calling <code>network.attested.payment.lookup</code> with the entitlement AT-URI. No centralized subscription database needed.</p>
85
86 <div class="mermaid-wrapper">
87 <pre class="mermaid">
88sequenceDiagram
89 participant L as Listener's Client
90 participant B as Broker
91 participant LR as Listener's Repo
92 participant CR as Creator's Repo
93 participant BR as Broker's Repo
94 participant App as Podcast App
95
96 L->>B: network.attested.payment.initiate
97 B-->>L: { token, url }
98 L->>B: Complete payment ($10/month)
99
100 B->>LR: Write payment.recurring record
101 Note right of LR: Includes entitlements[]<br/>pointing to product record
102
103 par Attestations
104 B->>BR: Write payment.proof
105 B->>CR: Notify creator
106 CR->>CR: Write payment.proof
107 end
108
109 App->>B: network.attested.payment.lookup<br/>?payer=...&recipient=...<br/>&paymentType=...recurring<br/>&entitlements=at://...product/...
110 B-->>App: { payments: [recurring record] }
111 App->>App: Subscription verified, grant access
112 </pre>
113 </div>
114
115 <h3 style="margin-top: 40px;">The payment record</h3>
116 <p>The recurring payment record lives in the listener’s repository. It declares the $10/month commitment, references the podcast’s product record as an entitlement, and carries attestation signatures from both the creator and broker.</p>
117
118 <div class="code-block">
119 <div class="code-label">Listener's repo — recurring payment</div>
120<pre><span class="hl-punc">{</span>
121 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"network.attested.payment.recurring"</span><span class="hl-punc">,</span>
122 <span class="hl-key">"subject"</span><span class="hl-punc">:</span> <span class="hl-str">"did:plc:podcast-creator"</span><span class="hl-punc">,</span>
123 <span class="hl-key">"amount"</span><span class="hl-punc">:</span> <span class="hl-num">1000</span><span class="hl-punc">,</span>
124 <span class="hl-key">"currency"</span><span class="hl-punc">:</span> <span class="hl-str">"USD"</span><span class="hl-punc">,</span>
125 <span class="hl-key">"unit"</span><span class="hl-punc">:</span> <span class="hl-str">"monthly"</span><span class="hl-punc">,</span>
126 <span class="hl-key">"frequency"</span><span class="hl-punc">:</span> <span class="hl-num">1</span><span class="hl-punc">,</span>
127 <span class="hl-key">"txnid"</span><span class="hl-punc">:</span> <span class="hl-str">"01J6M4R5XQHV8WNBCM3G9RFBT"</span><span class="hl-punc">,</span>
128 <span class="hl-key">"createdAt"</span><span class="hl-punc">:</span> <span class="hl-str">"2026-03-01T00:00:00.000Z"</span><span class="hl-punc">,</span>
129 <span class="hl-key">"entitlements"</span><span class="hl-punc">:</span> <span class="hl-punc">[</span>
130 <span class="hl-punc">{</span>
131 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"com.atproto.repo.strongRef"</span><span class="hl-punc">,</span>
132 <span class="hl-key">"uri"</span><span class="hl-punc">:</span> <span class="hl-str">"at://did:plc:podcast-creator/com.example.podcast.subscription/premium"</span><span class="hl-punc">,</span>
133 <span class="hl-key">"cid"</span><span class="hl-punc">:</span> <span class="hl-str">"bafyreig7xxgb5tcoqd3ne6gqkvrulzpfnwjmcc5fsgqjdx4huswnhzbekcc"</span>
134 <span class="hl-punc">}</span>
135 <span class="hl-punc">]</span><span class="hl-punc">,</span>
136 <span class="hl-key">"signatures"</span><span class="hl-punc">:</span> <span class="hl-punc">[</span>
137 <span class="hl-punc">{</span>
138 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"com.atproto.repo.strongRef"</span><span class="hl-punc">,</span>
139 <span class="hl-key">"uri"</span><span class="hl-punc">:</span> <span class="hl-str">"at://did:plc:podcast-creator/network.attested.payment.proof/3la8rxz3vdc4t"</span><span class="hl-punc">,</span>
140 <span class="hl-key">"cid"</span><span class="hl-punc">:</span> <span class="hl-str">"bafyreigyh7s6lqf5n3xke4jt6r2x3mqkzf4wpgicbqhqg5k3vdjn7aomfe"</span>
141 <span class="hl-punc">}</span><span class="hl-punc">,</span>
142 <span class="hl-punc">{</span>
143 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"com.atproto.repo.strongRef"</span><span class="hl-punc">,</span>
144 <span class="hl-key">"uri"</span><span class="hl-punc">:</span> <span class="hl-str">"at://did:plc:broker-payments/network.attested.payment.proof/3la8ry4ldsc4u"</span><span class="hl-punc">,</span>
145 <span class="hl-key">"cid"</span><span class="hl-punc">:</span> <span class="hl-str">"bafyreih7wwfa3tcoqd2ne5gqkvrulzpfnwjmcc5fsgqjdx4huswnhzaehqu"</span>
146 <span class="hl-punc">}</span>
147 <span class="hl-punc">]</span>
148<span class="hl-punc">}</span></pre>
149 </div>
150
151 <h3 style="margin-top: 40px;">Verifying access</h3>
152 <p>When a listener opens the podcast in any ATProtocol app, the app checks for an active subscription by querying the broker’s lookup endpoint. The key is filtering by both the recurring payment type and the specific entitlement.</p>
153
154 <div class="code-block">
155 <div class="code-label">Lookup request</div>
156 <pre><span class="hl-comment">// Does this listener have an active premium subscription?</span>
157GET /xrpc/network.attested.payment.lookup
158 <span class="hl-punc">?</span><span class="hl-key">payer</span><span class="hl-punc">=</span><span class="hl-str">did:plc:listener123</span>
159 <span class="hl-punc">&</span><span class="hl-key">recipient</span><span class="hl-punc">=</span><span class="hl-str">did:plc:podcast-creator</span>
160 <span class="hl-punc">&</span><span class="hl-key">paymentType</span><span class="hl-punc">=</span><span class="hl-str">network.attested.payment.recurring</span>
161 <span class="hl-punc">&</span><span class="hl-key">entitlements</span><span class="hl-punc">=</span><span class="hl-str">at://did:plc:podcast-creator/com.example.podcast.subscription/premium</span></pre>
162 </div>
163
164 <p>If the response contains a payment record, the listener has an active subscription and the app grants access to premium episodes. If the <code>payments</code> array is empty, the listener either hasn’t subscribed or their subscription has lapsed.</p>
165
166 <div class="callout">
167 <p><strong>App-agnostic verification.</strong> Because the payment record and its entitlements live on the protocol, any podcast app, tile, or appview can independently verify the subscription. The listener isn’t locked into a single client—their subscription follows them across the ecosystem.</p>
168 </div>
169
170 <div class="callout" style="margin-top: 16px;">
171 <p><strong>Entitlements are flexible.</strong> The <code>com.example.podcast.subscription/premium</code> record is defined by the podcast creator, not by this spec. It could contain tier details, feature flags, or access rules—whatever makes sense for the product. The payment record simply references it as a <code>strongRef</code>, linking proof of payment to what was purchased.</p>
172 </div>
173 </section>
174
175 <!-- One-Time Purchase -->
176 <section id="one-time-purchase">
177 <h2>One-Time Purchase</h2>
178 <p class="section-desc">A user makes a one-time payment to unlock something tied to a specific recipient—a profile badge in a social app, a tip that comes with an award, downloadable content, or any other digital good. The payment is linked to an entitlement record that the app checks to gate access or display.</p>
179
180 <h3>How it works</h3>
181 <p>A user wants to support a creator and get something in return—maybe a supporter badge that appears on their profile, or access to bonus content. The app presents the option, the user pays through a broker, and the resulting payment record carries an entitlement that any app can verify.</p>
182
183 <ol class="steps">
184 <li>The user selects a purchase option in the app (e.g. “Buy Supporter Badge” or “Unlock Bonus Pack”). The app initiates the payment via <code>network.attested.payment.initiate</code> on the creator’s broker</li>
185 <li>The broker processes the one-time payment and writes a <code>network.attested.payment.oneTime</code> record to the payer’s repository. The record includes an <code>entitlements</code> reference pointing to the specific product—a badge, an award, DLC content, or whatever the creator has defined</li>
186 <li>The broker and creator each write <code>payment.proof</code> attestation records to their own repositories, completing the cryptographic chain</li>
187 </ol>
188
189 <p>When any app wants to check whether the user has purchased that item, it calls <code>network.attested.payment.lookup</code> filtered by the entitlement AT-URI. If a matching one-time payment exists, the user has paid and the app renders the badge, unlocks the content, or grants whatever the entitlement represents.</p>
190
191 <div class="mermaid-wrapper">
192 <pre class="mermaid">
193sequenceDiagram
194 participant U as User's Client
195 participant B as Broker
196 participant UR as User's Repo
197 participant CR as Creator's Repo
198 participant BR as Broker's Repo
199 participant App as Social App
200
201 U->>B: network.attested.payment.initiate
202 B-->>U: { token, url }
203 U->>B: Complete payment (one-time)
204
205 B->>UR: Write payment.oneTime record
206 Note right of UR: Includes entitlements[]<br/>pointing to badge/product record
207
208 par Attestations
209 B->>BR: Write payment.proof
210 B->>CR: Notify creator
211 CR->>CR: Write payment.proof
212 end
213
214 App->>B: network.attested.payment.lookup<br/>?payer=...&recipient=...<br/>&entitlements=at://...badge/...
215 B-->>App: { payments: [oneTime record] }
216 App->>App: Show badge on profile
217 </pre>
218 </div>
219
220 <h3 style="margin-top: 40px;">The payment record</h3>
221 <p>The one-time payment record lives in the payer’s repository. In this example, a user pays $5 to get a supporter badge on a creator’s profile. The entitlement references the creator’s badge record.</p>
222
223 <div class="code-block">
224 <div class="code-label">Payer's repo — one-time payment</div>
225<pre><span class="hl-punc">{</span>
226 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"network.attested.payment.oneTime"</span><span class="hl-punc">,</span>
227 <span class="hl-key">"subject"</span><span class="hl-punc">:</span> <span class="hl-str">"did:plc:creator-xyz"</span><span class="hl-punc">,</span>
228 <span class="hl-key">"amount"</span><span class="hl-punc">:</span> <span class="hl-num">500</span><span class="hl-punc">,</span>
229 <span class="hl-key">"currency"</span><span class="hl-punc">:</span> <span class="hl-str">"USD"</span><span class="hl-punc">,</span>
230 <span class="hl-key">"txnid"</span><span class="hl-punc">:</span> <span class="hl-str">"01J7N5S6YRHW0XPBDN4H1UHEV"</span><span class="hl-punc">,</span>
231 <span class="hl-key">"memo"</span><span class="hl-punc">:</span> <span class="hl-str">"Supporter badge"</span><span class="hl-punc">,</span>
232 <span class="hl-key">"createdAt"</span><span class="hl-punc">:</span> <span class="hl-str">"2026-03-20T14:30:00.000Z"</span><span class="hl-punc">,</span>
233 <span class="hl-key">"entitlements"</span><span class="hl-punc">:</span> <span class="hl-punc">[</span>
234 <span class="hl-punc">{</span>
235 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"com.atproto.repo.strongRef"</span><span class="hl-punc">,</span>
236 <span class="hl-key">"uri"</span><span class="hl-punc">:</span> <span class="hl-str">"at://did:plc:creator-xyz/com.example.app.badge/supporter"</span><span class="hl-punc">,</span>
237 <span class="hl-key">"cid"</span><span class="hl-punc">:</span> <span class="hl-str">"bafyreif8xxgb6tcoqd4ne7gqkvrulzpfnwjmcc6fsgqjdx5huswnhzbekdd"</span>
238 <span class="hl-punc">}</span>
239 <span class="hl-punc">]</span><span class="hl-punc">,</span>
240 <span class="hl-key">"signatures"</span><span class="hl-punc">:</span> <span class="hl-punc">[</span>
241 <span class="hl-punc">{</span>
242 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"com.atproto.repo.strongRef"</span><span class="hl-punc">,</span>
243 <span class="hl-key">"uri"</span><span class="hl-punc">:</span> <span class="hl-str">"at://did:plc:creator-xyz/network.attested.payment.proof/3ld4txz5xfe5v"</span><span class="hl-punc">,</span>
244 <span class="hl-key">"cid"</span><span class="hl-punc">:</span> <span class="hl-str">"bafyreigyh8s7lqf6n4xke5jt7r3x4mqkzf5wpgicbqhqg6k4vdjn8bomge"</span>
245 <span class="hl-punc">}</span><span class="hl-punc">,</span>
246 <span class="hl-punc">{</span>
247 <span class="hl-key">"$type"</span><span class="hl-punc">:</span> <span class="hl-str">"com.atproto.repo.strongRef"</span><span class="hl-punc">,</span>
248 <span class="hl-key">"uri"</span><span class="hl-punc">:</span> <span class="hl-str">"at://did:plc:broker-payments/network.attested.payment.proof/3ld4ty5mdtc5w"</span><span class="hl-punc">,</span>
249 <span class="hl-key">"cid"</span><span class="hl-punc">:</span> <span class="hl-str">"bafyreih8wwfa4tcoqd3ne6gqkvrulzpfnwjmcc6fsgqjdx5huswnhzafiqu"</span>
250 <span class="hl-punc">}</span>
251 <span class="hl-punc">]</span>
252<span class="hl-punc">}</span></pre>
253 </div>
254
255 <h3 style="margin-top: 40px;">Verifying the purchase</h3>
256 <p>When an app renders a user’s profile, it checks whether the user has purchased the supporter badge for that creator by querying the lookup endpoint with the entitlement AT-URI.</p>
257
258 <div class="code-block">
259 <div class="code-label">Lookup request</div>
260 <pre><span class="hl-comment">// Does this user have the supporter badge for this creator?</span>
261GET /xrpc/network.attested.payment.lookup
262 <span class="hl-punc">?</span><span class="hl-key">payer</span><span class="hl-punc">=</span><span class="hl-str">did:plc:user456</span>
263 <span class="hl-punc">&</span><span class="hl-key">recipient</span><span class="hl-punc">=</span><span class="hl-str">did:plc:creator-xyz</span>
264 <span class="hl-punc">&</span><span class="hl-key">paymentType</span><span class="hl-punc">=</span><span class="hl-str">network.attested.payment.oneTime</span>
265 <span class="hl-punc">&</span><span class="hl-key">entitlements</span><span class="hl-punc">=</span><span class="hl-str">at://did:plc:creator-xyz/com.example.app.badge/supporter</span></pre>
266 </div>
267
268 <p>If the <code>payments</code> array contains a matching record, the app displays the badge on the user’s profile. Because this is a one-time payment, it persists indefinitely—there’s no renewal to check.</p>
269
270 <div class="callout">
271 <p><strong>Many forms, same pattern.</strong> This scenario covers any one-time digital purchase: supporter badges, tip awards, DLC content packs, custom emoji sets, premium filters, or exclusive stickers. The entitlement record is defined by the app or creator—the payment spec just links proof of payment to whatever was purchased. Different apps can define different products, all verified the same way.</p>
272 </div>
273 </section>
274
275</main>
276
277<footer>
278 <div class="container">
279 <p>attested.network · Built on <a href="https://badge.blue">badge.blue</a> attestations · <a href="https://atproto.com">ATProtocol</a></p>
280 </div>
281</footer>
282
283</body>
284</html>