-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopenapi.yaml
More file actions
365 lines (340 loc) · 11.6 KB
/
Copy pathopenapi.yaml
File metadata and controls
365 lines (340 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
openapi: 3.0.3
info:
title: Diff Viewer API
description: |
REST API for the Diff Viewer — a side-by-side text diff sharing tool.
Sessions store an original and modified text pair with an optional title.
Edit tokens authenticate write operations. Private sessions require an
edit token for all access.
**Content limit:** 1 MB (combined serialized size of original + modified + title).
**Expiry:** 90 days for browser-created sessions (Turnstile verified),
30 days for agent/script-created sessions. TTL resets on every write.
**ID format:** 12-character URL-safe nanoid matching `[A-Za-z0-9_-]{12}`.
**Binary content** (null bytes in any field) is rejected.
version: 1.0.0
servers:
- url: https://diff.pentagram.me
description: Production
security: []
components:
securitySchemes:
editToken:
type: apiKey
in: header
name: X-Edit-Token
description: >
Edit token for write operations and reading private sessions.
Returned on creation (201). Cannot be retrieved after that — store it.
parameters:
sessionId:
name: id
in: path
required: true
description: 12-character URL-safe session ID
schema:
$ref: '#/components/schemas/SessionId'
schemas:
SessionId:
type: string
pattern: '^[A-Za-z0-9_\-]{12}$'
description: 12-character URL-safe nanoid
example: abc123def456
SessionMetadata:
type: object
required: [createdAt, updatedAt]
properties:
createdAt:
type: integer
description: Unix timestamp in milliseconds
example: 1700000000000
updatedAt:
type: integer
description: Unix timestamp in milliseconds
example: 1700000001000
DiffSession:
type: object
required: [id, original, modified, metadata, private]
properties:
id:
$ref: '#/components/schemas/SessionId'
original:
type: string
description: Original (left-side) text content
modified:
type: string
description: Modified (right-side) text content
title:
type: string
description: Optional display title shown in the diff header
metadata:
$ref: '#/components/schemas/SessionMetadata'
private:
type: boolean
description: When true, viewing requires a valid edit token
expiresAt:
type: string
format: date-time
description: ISO 8601 timestamp when the session expires. Absent for legacy sessions without TTL.
DiffSessionRequest:
type: object
required: [original, modified]
properties:
original:
type: string
description: Original text. Null bytes (binary content) are rejected.
modified:
type: string
description: Modified text. Null bytes (binary content) are rejected.
title:
type: string
description: Optional display title. Null bytes are rejected.
private:
type: boolean
description: When true, viewing requires an edit token (default false)
turnstileToken:
type: string
description: Cloudflare Turnstile verification token. Browser clients should provide this to get a 90-day TTL. Agent/script clients without a token get a 30-day TTL.
DiffSessionCreateResponse:
type: object
description: Returned on successful session creation (201)
required: [id, metadata, editToken, private, url, editUrl]
properties:
id:
$ref: '#/components/schemas/SessionId'
metadata:
$ref: '#/components/schemas/SessionMetadata'
editToken:
type: string
description: >
Token required for all future writes to this session.
Store it immediately — it cannot be retrieved later.
example: AbCdEfGhIjKlMnOpQrStUvWx
private:
type: boolean
url:
type: string
format: uri
description: Shareable URL for this diff
example: https://diff.pentagram.me/abc123def456
editUrl:
type: string
format: uri
description: URL with edit token in the hash fragment — /{id}#token={editToken}
example: https://diff.pentagram.me/abc123def456#token=AbCdEfGhIjKlMnOpQrStUvWx
expiresAt:
type: string
format: date-time
description: ISO 8601 timestamp when the session expires
DiffSessionUpdateResponse:
type: object
description: Returned on successful session update (200)
required: [id, metadata, private]
properties:
id:
$ref: '#/components/schemas/SessionId'
metadata:
$ref: '#/components/schemas/SessionMetadata'
private:
type: boolean
expiresAt:
type: string
format: date-time
description: ISO 8601 timestamp when the session expires
ErrorResponse:
type: object
required: [error]
properties:
error:
type: string
example: Session not found
responses:
NotFound:
description: Session not found or access denied (private sessions return 404, not 403)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Forbidden:
description: Missing or invalid edit token
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
TooLarge:
description: Combined content exceeds 1 MB limit
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
RateLimited:
description: Rate limit exceeded
headers:
Retry-After:
schema:
type: integer
example: 60
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
paths:
/api/sessions/{id}:
parameters:
- $ref: '#/components/parameters/sessionId'
get:
operationId: getSession
summary: Read a diff session
description: |
Retrieve a diff session by ID, including both text sides and metadata.
Private sessions require `X-Edit-Token`. Returns 404 for both "not
found" and "access denied" to avoid revealing the existence of
private sessions.
Supports conditional requests via `If-None-Match` (ETag comparison)
and `If-Modified-Since` (date comparison). Returns 304 when the
session has not changed, skipping body serialization.
tags: [Sessions]
parameters:
- name: X-Edit-Token
in: header
description: Required for private sessions
schema:
type: string
- name: If-None-Match
in: header
description: Return 304 if the ETag matches (weak comparison per RFC 9110)
schema:
type: string
example: 'W/"1700000001000"'
- name: If-Modified-Since
in: header
description: Return 304 if the session has not been modified since this date. Ignored when If-None-Match is present.
schema:
type: string
format: date-time
responses:
'200':
description: Session retrieved successfully
headers:
ETag:
description: Weak ETag derived from updatedAt — `W/"<updatedAt>"`
schema:
type: string
example: 'W/"1700000001000"'
Last-Modified:
description: HTTP date of last update
schema:
type: string
X-Expires-At:
description: HTTP date when the session expires
schema:
type: string
Vary:
description: Content negotiation signal — response varies by Accept header
schema:
type: string
example: Accept
content:
application/json:
schema:
$ref: '#/components/schemas/DiffSession'
'304':
description: Not Modified — session has not changed since the conditional request headers
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
put:
operationId: putSession
summary: Create or update a diff session
description: |
**Create (201):** no `X-Edit-Token` header + new ID.
**Update (200):** valid `X-Edit-Token` + existing ID.
Accepts `application/json` only. Content limit: 1 MB (combined
serialized size). Binary content (null bytes) is rejected.
The private flag can be set via the JSON body or the `X-Private`
header. On update, omitting the flag preserves the existing setting.
tags: [Sessions]
parameters:
- name: X-Edit-Token
in: header
description: Required for updating an existing session
schema:
type: string
- name: X-Private
in: header
description: Set to "true" to make the session private (alternative to JSON body field)
schema:
type: string
enum: ['true', 'false']
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DiffSessionRequest'
responses:
'201':
description: Session created
content:
application/json:
schema:
$ref: '#/components/schemas/DiffSessionCreateResponse'
'200':
description: Session updated
content:
application/json:
schema:
$ref: '#/components/schemas/DiffSessionUpdateResponse'
'400':
description: Invalid request body, missing required fields, or binary content detected
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Bot verification failed (invalid Turnstile token) or invalid edit token on update
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Session not found when edit token is provided but session does not exist
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'413':
$ref: '#/components/responses/TooLarge'
'415':
description: Unsupported Media Type — only application/json is accepted
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
$ref: '#/components/responses/RateLimited'
delete:
operationId: deleteSession
summary: Delete a diff session
description: Permanently deletes a session. Requires a valid edit token.
tags: [Sessions]
security:
- editToken: []
parameters:
- name: X-Edit-Token
in: header
required: true
schema:
type: string
responses:
'204':
description: Session deleted
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
tags:
- name: Sessions
description: Diff session CRUD operations