@audiodn/agent-kit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +74 -0
  3. package/assets/content/instructions.md +48 -0
  4. package/assets/content/partials/auth.md +17 -0
  5. package/assets/content/partials/compatibility.md +10 -0
  6. package/assets/content/partials/playback.md +14 -0
  7. package/assets/content/partials/processing.md +17 -0
  8. package/assets/content/partials/security.md +14 -0
  9. package/assets/content/partials/upload.md +17 -0
  10. package/assets/content/partials/webhooks.md +13 -0
  11. package/assets/skill/SKILL.md +52 -0
  12. package/assets/skill/references/authentication.md +27 -0
  13. package/assets/skill/references/playback.md +29 -0
  14. package/assets/skill/references/processing.md +23 -0
  15. package/assets/skill/references/security.md +30 -0
  16. package/assets/skill/references/upload-flow.md +29 -0
  17. package/assets/skill/references/webhooks.md +19 -0
  18. package/assets/skill/scripts/known-endpoints.json +28 -0
  19. package/assets/skill/scripts/validate.mjs +287 -0
  20. package/assets/skill/templates/cloudflare-worker.md +39 -0
  21. package/assets/skill/templates/nextjs.md +47 -0
  22. package/assets/skill/templates/node-server.md +44 -0
  23. package/assets/skill/templates/vue-nuxt.md +49 -0
  24. package/assets/snapshots/llms-full.txt +347 -0
  25. package/assets/snapshots/openapi.json +1416 -0
  26. package/assets/snapshots/sources.json +19 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.js +101 -0
  29. package/dist/commands/init.d.ts +8 -0
  30. package/dist/commands/init.js +35 -0
  31. package/dist/commands/list.d.ts +1 -0
  32. package/dist/commands/list.js +28 -0
  33. package/dist/commands/uninstall.d.ts +6 -0
  34. package/dist/commands/uninstall.js +20 -0
  35. package/dist/commands/validate.d.ts +5 -0
  36. package/dist/commands/validate.js +18 -0
  37. package/dist/core/formats.d.ts +23 -0
  38. package/dist/core/formats.js +43 -0
  39. package/dist/core/fsutil.d.ts +5 -0
  40. package/dist/core/fsutil.js +34 -0
  41. package/dist/core/install.d.ts +16 -0
  42. package/dist/core/install.js +76 -0
  43. package/dist/core/markers.d.ts +5 -0
  44. package/dist/core/markers.js +13 -0
  45. package/dist/core/merge.d.ts +21 -0
  46. package/dist/core/merge.js +38 -0
  47. package/dist/core/prompt.d.ts +2 -0
  48. package/dist/core/prompt.js +23 -0
  49. package/dist/core/render.d.ts +5 -0
  50. package/dist/core/render.js +21 -0
  51. package/dist/core/report.d.ts +10 -0
  52. package/dist/core/report.js +35 -0
  53. package/dist/core/skill.d.ts +13 -0
  54. package/dist/core/skill.js +117 -0
  55. package/dist/paths.d.ts +5 -0
  56. package/dist/paths.js +10 -0
  57. package/dist/version.d.ts +1 -0
  58. package/dist/version.js +12 -0
  59. package/package.json +61 -0
@@ -0,0 +1,1416 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "AudioDN API",
5
+ "version": "1.0.0",
6
+ "summary": "Audio delivery infrastructure: upload, transcode, secure delivery, and playback.",
7
+ "description": "AudioDN provides a REST API and embeddable web components for managing and delivering audio at scale.\n\nAuthentication: bearer token via the `Authorization` header. Use a server-side API key for full access; mint scoped client-side keys (Player or Uploader) for browsers and mobile apps.\n\nAll endpoints are prefixed with `/v1/`.",
8
+ "contact": {
9
+ "name": "Audio Delivery Network",
10
+ "email": "support@audiodeliverynetwork.com",
11
+ "url": "https://audiodeliverynetwork.com"
12
+ },
13
+ "license": {
14
+ "name": "Proprietary"
15
+ }
16
+ },
17
+ "servers": [
18
+ {
19
+ "url": "https://api.audiodelivery.net",
20
+ "description": "Production"
21
+ }
22
+ ],
23
+ "tags": [
24
+ { "name": "API Keys" },
25
+ { "name": "Organizations" },
26
+ { "name": "Creators" },
27
+ { "name": "Collections" },
28
+ { "name": "Tracks" },
29
+ { "name": "Cover Images" },
30
+ { "name": "Upload Sessions" },
31
+ { "name": "Play Sessions" },
32
+ { "name": "Variants" }
33
+ ],
34
+ "security": [{ "BearerAuth": [] }],
35
+ "components": {
36
+ "securitySchemes": {
37
+ "BearerAuth": {
38
+ "type": "http",
39
+ "scheme": "bearer",
40
+ "description": "Server-side API key. Use scoped client-side keys for browser and mobile contexts."
41
+ }
42
+ },
43
+ "parameters": {
44
+ "Limit": {
45
+ "name": "limit",
46
+ "in": "query",
47
+ "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 }
48
+ },
49
+ "Offset": {
50
+ "name": "offset",
51
+ "in": "query",
52
+ "schema": { "type": "integer", "minimum": 0, "default": 0 }
53
+ }
54
+ },
55
+ "schemas": {
56
+ "OkEnvelope": {
57
+ "type": "object",
58
+ "required": ["ok", "api_request_id"],
59
+ "properties": {
60
+ "ok": { "type": "boolean", "const": true },
61
+ "api_request_id": { "type": "string", "format": "uuid" }
62
+ }
63
+ },
64
+ "Error": {
65
+ "type": "object",
66
+ "required": ["ok", "message"],
67
+ "properties": {
68
+ "ok": { "type": "boolean", "const": false },
69
+ "message": { "type": "string" },
70
+ "api_request_id": { "type": "string", "format": "uuid" }
71
+ }
72
+ },
73
+ "ImageColor": {
74
+ "type": "object",
75
+ "properties": {
76
+ "hex": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
77
+ "area": { "type": "number" },
78
+ "lightness": { "type": "number" },
79
+ "saturation": { "type": "number" }
80
+ }
81
+ },
82
+ "UploadHandle": {
83
+ "type": "object",
84
+ "properties": {
85
+ "method": { "type": "string", "enum": ["PUT", "POST"] },
86
+ "upload_url": { "type": "string", "format": "uri" },
87
+ "ttl": { "type": "integer" },
88
+ "expires_at": { "type": "string", "format": "date-time" }
89
+ }
90
+ },
91
+ "Organization": {
92
+ "type": "object",
93
+ "properties": {
94
+ "id": { "type": "string", "format": "uuid" },
95
+ "name": { "type": "string" },
96
+ "theme": { "type": "array", "items": { "$ref": "#/components/schemas/ImageColor" } },
97
+ "is_theme_overridable": { "type": "boolean" },
98
+ "is_cover_overridable": { "type": "boolean" },
99
+ "player_color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
100
+ "player_color_light": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "readOnly": true, "description": "Derived read-only variant of player_color adjusted to stay legible on a light background." },
101
+ "player_color_dark": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "readOnly": true, "description": "Derived read-only variant of player_color adjusted to stay legible on a dark background." },
102
+ "player_subtitle": { "type": "string" }
103
+ }
104
+ },
105
+ "Creator": {
106
+ "type": "object",
107
+ "properties": {
108
+ "id": { "type": "string", "format": "uuid" },
109
+ "organization_id": { "type": "string", "format": "uuid" },
110
+ "folder_id": { "type": "string", "format": "uuid" },
111
+ "organization_index": { "type": "string" },
112
+ "metadata": { "type": "object", "additionalProperties": true },
113
+ "created_at": { "type": "string", "format": "date-time" },
114
+ "updated_at": { "type": "string", "format": "date-time" }
115
+ }
116
+ },
117
+ "Collection": {
118
+ "type": "object",
119
+ "properties": {
120
+ "id": { "type": "string", "format": "uuid" },
121
+ "creator_id": { "type": "string", "format": "uuid" },
122
+ "organization_index": { "type": "string" },
123
+ "title": { "type": "string" },
124
+ "metadata": { "type": "object", "additionalProperties": true },
125
+ "theme": { "type": "array", "items": { "$ref": "#/components/schemas/ImageColor" } },
126
+ "is_cover_overridable": { "type": "boolean" },
127
+ "is_theme_overridable": { "type": "boolean" },
128
+ "player_color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
129
+ "player_color_light": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "readOnly": true, "description": "Derived read-only variant of player_color adjusted to stay legible on a light background." },
130
+ "player_color_dark": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "readOnly": true, "description": "Derived read-only variant of player_color adjusted to stay legible on a dark background." },
131
+ "player_subtitle": { "type": "string" }
132
+ }
133
+ },
134
+ "Track": {
135
+ "type": "object",
136
+ "properties": {
137
+ "id": { "type": "string", "format": "uuid" },
138
+ "collection_id": { "type": "string", "format": "uuid" },
139
+ "creator_id": { "type": "string", "format": "uuid" },
140
+ "file_name": { "type": "string" },
141
+ "duration": { "type": "number" },
142
+ "organization_index": { "type": "string" },
143
+ "metadata": { "type": "object", "additionalProperties": true },
144
+ "is_cover_overridable": { "type": "boolean" },
145
+ "is_theme_overridable": { "type": "boolean" },
146
+ "player_title": { "type": "string" },
147
+ "player_subtitle": { "type": "string" },
148
+ "player_color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
149
+ "player_color_light": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "readOnly": true, "description": "Derived read-only variant of player_color adjusted to stay legible on a light background." },
150
+ "player_color_dark": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "readOnly": true, "description": "Derived read-only variant of player_color adjusted to stay legible on a dark background." },
151
+ "status": { "type": "string", "enum": ["initializing", "processing", "fallback_processing", "ready", "incomplete", "failed"] }
152
+ }
153
+ },
154
+ "Variant": {
155
+ "type": "object",
156
+ "properties": {
157
+ "id": { "type": "string", "format": "uuid" },
158
+ "name": { "type": "string" },
159
+ "type": { "type": "string", "description": "Variant kind (e.g. transcode, preview, waveform, analysis)." },
160
+ "format": { "type": "string" },
161
+ "bitrate": { "type": "integer" }
162
+ }
163
+ },
164
+ "UploadSession": {
165
+ "type": "object",
166
+ "properties": {
167
+ "id": { "type": "string", "format": "uuid" },
168
+ "creator_id": { "type": "string", "format": "uuid" },
169
+ "collection_id": { "type": "string", "format": "uuid" },
170
+ "organization_index": { "type": "string" },
171
+ "metadata": { "type": "object", "additionalProperties": true },
172
+ "expires_at": { "type": "string", "format": "date-time" }
173
+ }
174
+ },
175
+ "PlaySession": {
176
+ "type": "object",
177
+ "properties": {
178
+ "id": { "type": "string", "format": "uuid" },
179
+ "creator_id": { "type": "string", "format": "uuid" },
180
+ "organization_index": { "type": "string" },
181
+ "metadata": { "type": "object", "additionalProperties": true },
182
+ "variants": { "type": "array", "items": { "type": "string" } },
183
+ "is_downloadable": { "type": "boolean" },
184
+ "expires_at": { "type": "string", "format": "date-time" }
185
+ }
186
+ }
187
+ },
188
+ "responses": {
189
+ "Unauthorized": {
190
+ "description": "Missing or invalid API key.",
191
+ "content": {
192
+ "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
193
+ }
194
+ },
195
+ "BadRequest": {
196
+ "description": "Invalid parameters.",
197
+ "content": {
198
+ "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
199
+ }
200
+ },
201
+ "NotFound": {
202
+ "description": "Resource not found.",
203
+ "content": {
204
+ "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
205
+ }
206
+ }
207
+ }
208
+ },
209
+ "paths": {
210
+ "/v1/api_key": {
211
+ "post": {
212
+ "tags": ["API Keys"],
213
+ "operationId": "createApiKey",
214
+ "summary": "Create API key",
215
+ "description": "Generate a new player, uploader, or share API key. Requires an API Access ('api') key; API Access keys themselves must be created in the dashboard.",
216
+ "requestBody": {
217
+ "required": true,
218
+ "content": {
219
+ "application/json": {
220
+ "schema": {
221
+ "type": "object",
222
+ "required": ["title", "api_key_type_id"],
223
+ "properties": {
224
+ "title": { "type": "string", "description": "Name of the API key" },
225
+ "api_key_type_id": { "type": "string", "enum": ["player", "uploader", "share"], "description": "Type of key to create" },
226
+ "collection_id": { "type": "string", "format": "uuid", "description": "Limit the key to a specific collection" },
227
+ "track_id": { "type": "string", "format": "uuid", "description": "Limit the key to a specific track (requires collection_id)" },
228
+ "creator_id": { "type": "string", "format": "uuid", "description": "Limit the key to a specific creator" },
229
+ "variants": { "type": "array", "items": { "type": "string" }, "description": "Allowed variants. Required (exactly one) for share keys; optional for player keys" },
230
+ "expires_at": { "type": "string", "format": "date-time", "description": "Optional expiration for all types; ignored for share keys" }
231
+ }
232
+ }
233
+ }
234
+ }
235
+ },
236
+ "responses": {
237
+ "200": {
238
+ "description": "API key created. The full key is returned once and never stored in plaintext.",
239
+ "content": {
240
+ "application/json": {
241
+ "schema": {
242
+ "allOf": [
243
+ { "$ref": "#/components/schemas/OkEnvelope" },
244
+ {
245
+ "type": "object",
246
+ "properties": {
247
+ "api_key": { "type": "string", "description": "The full API key including org prefix (returned once)" }
248
+ }
249
+ }
250
+ ]
251
+ }
252
+ }
253
+ }
254
+ },
255
+ "400": { "$ref": "#/components/responses/BadRequest" },
256
+ "401": { "$ref": "#/components/responses/Unauthorized" },
257
+ "403": { "description": "Forbidden — API Access keys must be created in the dashboard, or the caller key is not an API Access key" }
258
+ }
259
+ }
260
+ },
261
+ "/v1/organization/{organization_id}": {
262
+ "get": {
263
+ "tags": ["Organizations"],
264
+ "operationId": "getOrganization",
265
+ "summary": "Get organization",
266
+ "parameters": [
267
+ { "name": "organization_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
268
+ ],
269
+ "responses": {
270
+ "200": {
271
+ "description": "Organization details.",
272
+ "content": {
273
+ "application/json": {
274
+ "schema": {
275
+ "allOf": [
276
+ { "$ref": "#/components/schemas/OkEnvelope" },
277
+ {
278
+ "type": "object",
279
+ "properties": {
280
+ "organization_id": { "type": "string", "format": "uuid" },
281
+ "organization": { "$ref": "#/components/schemas/Organization" }
282
+ }
283
+ }
284
+ ]
285
+ }
286
+ }
287
+ }
288
+ },
289
+ "401": { "$ref": "#/components/responses/Unauthorized" },
290
+ "404": { "$ref": "#/components/responses/NotFound" }
291
+ }
292
+ },
293
+ "put": {
294
+ "tags": ["Organizations"],
295
+ "operationId": "updateOrganization",
296
+ "summary": "Update organization",
297
+ "parameters": [
298
+ { "name": "organization_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
299
+ ],
300
+ "requestBody": {
301
+ "required": true,
302
+ "content": {
303
+ "application/json": {
304
+ "schema": { "$ref": "#/components/schemas/Organization" }
305
+ }
306
+ }
307
+ },
308
+ "responses": {
309
+ "200": {
310
+ "description": "Updated organization.",
311
+ "content": {
312
+ "application/json": {
313
+ "schema": {
314
+ "allOf": [
315
+ { "$ref": "#/components/schemas/OkEnvelope" },
316
+ {
317
+ "type": "object",
318
+ "properties": {
319
+ "organization_id": { "type": "string", "format": "uuid" },
320
+ "organization": { "$ref": "#/components/schemas/Organization" }
321
+ }
322
+ }
323
+ ]
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "400": { "$ref": "#/components/responses/BadRequest" },
329
+ "401": { "$ref": "#/components/responses/Unauthorized" },
330
+ "404": { "$ref": "#/components/responses/NotFound" }
331
+ }
332
+ }
333
+ },
334
+ "/v1/creator": {
335
+ "get": {
336
+ "tags": ["Creators"],
337
+ "operationId": "listCreators",
338
+ "summary": "List creators",
339
+ "parameters": [
340
+ { "$ref": "#/components/parameters/Limit" },
341
+ { "$ref": "#/components/parameters/Offset" }
342
+ ],
343
+ "responses": {
344
+ "200": {
345
+ "description": "Creators list.",
346
+ "content": {
347
+ "application/json": {
348
+ "schema": {
349
+ "allOf": [
350
+ { "$ref": "#/components/schemas/OkEnvelope" },
351
+ {
352
+ "type": "object",
353
+ "properties": {
354
+ "count": { "type": "integer" },
355
+ "creators": { "type": "array", "items": { "$ref": "#/components/schemas/Creator" } }
356
+ }
357
+ }
358
+ ]
359
+ }
360
+ }
361
+ }
362
+ },
363
+ "401": { "$ref": "#/components/responses/Unauthorized" }
364
+ }
365
+ },
366
+ "post": {
367
+ "tags": ["Creators"],
368
+ "operationId": "createCreator",
369
+ "summary": "Create creator",
370
+ "requestBody": {
371
+ "required": true,
372
+ "content": {
373
+ "application/json": {
374
+ "schema": {
375
+ "type": "object",
376
+ "required": ["organization_index"],
377
+ "properties": {
378
+ "organization_index": { "type": "string", "description": "Your external identifier for the creator (the remote service identifier)." },
379
+ "metadata": { "type": "object", "additionalProperties": true }
380
+ }
381
+ }
382
+ }
383
+ }
384
+ },
385
+ "responses": {
386
+ "200": {
387
+ "description": "Creator created.",
388
+ "content": {
389
+ "application/json": {
390
+ "schema": {
391
+ "allOf": [
392
+ { "$ref": "#/components/schemas/OkEnvelope" },
393
+ {
394
+ "type": "object",
395
+ "properties": {
396
+ "creator_id": { "type": "string", "format": "uuid" },
397
+ "creator": { "$ref": "#/components/schemas/Creator" }
398
+ }
399
+ }
400
+ ]
401
+ }
402
+ }
403
+ }
404
+ },
405
+ "400": { "$ref": "#/components/responses/BadRequest" },
406
+ "401": { "$ref": "#/components/responses/Unauthorized" }
407
+ }
408
+ }
409
+ },
410
+ "/v1/creator/{creator_id}": {
411
+ "get": {
412
+ "tags": ["Creators"],
413
+ "operationId": "getCreator",
414
+ "summary": "Get creator",
415
+ "parameters": [
416
+ { "name": "creator_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
417
+ ],
418
+ "responses": {
419
+ "200": {
420
+ "description": "Creator details.",
421
+ "content": {
422
+ "application/json": {
423
+ "schema": {
424
+ "allOf": [
425
+ { "$ref": "#/components/schemas/OkEnvelope" },
426
+ {
427
+ "type": "object",
428
+ "properties": {
429
+ "creator_id": { "type": "string", "format": "uuid" },
430
+ "creator": { "$ref": "#/components/schemas/Creator" }
431
+ }
432
+ }
433
+ ]
434
+ }
435
+ }
436
+ }
437
+ },
438
+ "401": { "$ref": "#/components/responses/Unauthorized" },
439
+ "404": { "$ref": "#/components/responses/NotFound" }
440
+ }
441
+ },
442
+ "put": {
443
+ "tags": ["Creators"],
444
+ "operationId": "updateCreator",
445
+ "summary": "Update creator",
446
+ "parameters": [
447
+ { "name": "creator_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
448
+ ],
449
+ "requestBody": {
450
+ "required": true,
451
+ "content": {
452
+ "application/json": {
453
+ "schema": {
454
+ "type": "object",
455
+ "properties": {
456
+ "organization_index": { "type": "string" },
457
+ "metadata": { "type": "object", "additionalProperties": true }
458
+ }
459
+ }
460
+ }
461
+ }
462
+ },
463
+ "responses": {
464
+ "200": {
465
+ "description": "Updated creator.",
466
+ "content": {
467
+ "application/json": {
468
+ "schema": {
469
+ "allOf": [
470
+ { "$ref": "#/components/schemas/OkEnvelope" },
471
+ {
472
+ "type": "object",
473
+ "properties": {
474
+ "creator_id": { "type": "string", "format": "uuid" },
475
+ "creator": { "$ref": "#/components/schemas/Creator" }
476
+ }
477
+ }
478
+ ]
479
+ }
480
+ }
481
+ }
482
+ },
483
+ "400": { "$ref": "#/components/responses/BadRequest" },
484
+ "401": { "$ref": "#/components/responses/Unauthorized" },
485
+ "404": { "$ref": "#/components/responses/NotFound" }
486
+ }
487
+ },
488
+ "delete": {
489
+ "tags": ["Creators"],
490
+ "operationId": "deleteCreator",
491
+ "summary": "Delete creator",
492
+ "parameters": [
493
+ { "name": "creator_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
494
+ ],
495
+ "responses": {
496
+ "200": {
497
+ "description": "Creator deleted.",
498
+ "content": {
499
+ "application/json": {
500
+ "schema": {
501
+ "allOf": [
502
+ { "$ref": "#/components/schemas/OkEnvelope" },
503
+ {
504
+ "type": "object",
505
+ "properties": {
506
+ "creator_id": { "type": "string", "format": "uuid" },
507
+ "deleted_creator": { "$ref": "#/components/schemas/Creator" }
508
+ }
509
+ }
510
+ ]
511
+ }
512
+ }
513
+ }
514
+ },
515
+ "401": { "$ref": "#/components/responses/Unauthorized" },
516
+ "404": { "$ref": "#/components/responses/NotFound" }
517
+ }
518
+ }
519
+ },
520
+ "/v1/collection": {
521
+ "get": {
522
+ "tags": ["Collections"],
523
+ "operationId": "listCollections",
524
+ "summary": "List collections",
525
+ "parameters": [
526
+ { "$ref": "#/components/parameters/Limit" },
527
+ { "$ref": "#/components/parameters/Offset" }
528
+ ],
529
+ "responses": {
530
+ "200": {
531
+ "description": "Collections list.",
532
+ "content": {
533
+ "application/json": {
534
+ "schema": {
535
+ "allOf": [
536
+ { "$ref": "#/components/schemas/OkEnvelope" },
537
+ {
538
+ "type": "object",
539
+ "properties": {
540
+ "count": { "type": "integer" },
541
+ "collections": { "type": "array", "items": { "$ref": "#/components/schemas/Collection" } }
542
+ }
543
+ }
544
+ ]
545
+ }
546
+ }
547
+ }
548
+ },
549
+ "401": { "$ref": "#/components/responses/Unauthorized" }
550
+ }
551
+ },
552
+ "post": {
553
+ "tags": ["Collections"],
554
+ "operationId": "createCollection",
555
+ "summary": "Create collection",
556
+ "requestBody": {
557
+ "required": true,
558
+ "content": {
559
+ "application/json": {
560
+ "schema": {
561
+ "type": "object",
562
+ "required": ["title"],
563
+ "properties": {
564
+ "title": { "type": "string" },
565
+ "creator_id": { "type": "string", "format": "uuid" },
566
+ "organization_index": { "type": "string" },
567
+ "metadata": { "type": "object", "additionalProperties": true },
568
+ "theme": { "type": "array", "items": { "$ref": "#/components/schemas/ImageColor" } },
569
+ "is_cover_overridable": { "type": "boolean" },
570
+ "is_theme_overridable": { "type": "boolean" },
571
+ "player_color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
572
+ "player_subtitle": { "type": "string" }
573
+ }
574
+ }
575
+ }
576
+ }
577
+ },
578
+ "responses": {
579
+ "200": {
580
+ "description": "Collection created.",
581
+ "content": {
582
+ "application/json": {
583
+ "schema": {
584
+ "allOf": [
585
+ { "$ref": "#/components/schemas/OkEnvelope" },
586
+ {
587
+ "type": "object",
588
+ "properties": {
589
+ "collection_id": { "type": "string", "format": "uuid" },
590
+ "collection": { "$ref": "#/components/schemas/Collection" },
591
+ "collection_cover_upload": { "$ref": "#/components/schemas/UploadHandle" }
592
+ }
593
+ }
594
+ ]
595
+ }
596
+ }
597
+ }
598
+ },
599
+ "400": { "$ref": "#/components/responses/BadRequest" },
600
+ "401": { "$ref": "#/components/responses/Unauthorized" }
601
+ }
602
+ }
603
+ },
604
+ "/v1/collection/{collection_id}": {
605
+ "get": {
606
+ "tags": ["Collections"],
607
+ "operationId": "getCollection",
608
+ "summary": "Get collection",
609
+ "parameters": [
610
+ { "name": "collection_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
611
+ ],
612
+ "responses": {
613
+ "200": {
614
+ "description": "Collection details.",
615
+ "content": {
616
+ "application/json": {
617
+ "schema": {
618
+ "allOf": [
619
+ { "$ref": "#/components/schemas/OkEnvelope" },
620
+ {
621
+ "type": "object",
622
+ "properties": {
623
+ "collection_id": { "type": "string", "format": "uuid" },
624
+ "collection": { "$ref": "#/components/schemas/Collection" }
625
+ }
626
+ }
627
+ ]
628
+ }
629
+ }
630
+ }
631
+ },
632
+ "401": { "$ref": "#/components/responses/Unauthorized" },
633
+ "404": { "$ref": "#/components/responses/NotFound" }
634
+ }
635
+ },
636
+ "put": {
637
+ "tags": ["Collections"],
638
+ "operationId": "updateCollection",
639
+ "summary": "Update collection",
640
+ "parameters": [
641
+ { "name": "collection_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
642
+ ],
643
+ "requestBody": {
644
+ "required": true,
645
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Collection" } } }
646
+ },
647
+ "responses": {
648
+ "200": {
649
+ "description": "Updated collection.",
650
+ "content": {
651
+ "application/json": {
652
+ "schema": {
653
+ "allOf": [
654
+ { "$ref": "#/components/schemas/OkEnvelope" },
655
+ {
656
+ "type": "object",
657
+ "properties": {
658
+ "collection_id": { "type": "string", "format": "uuid" },
659
+ "collection": { "$ref": "#/components/schemas/Collection" }
660
+ }
661
+ }
662
+ ]
663
+ }
664
+ }
665
+ }
666
+ },
667
+ "400": { "$ref": "#/components/responses/BadRequest" },
668
+ "401": { "$ref": "#/components/responses/Unauthorized" },
669
+ "404": { "$ref": "#/components/responses/NotFound" }
670
+ }
671
+ },
672
+ "delete": {
673
+ "tags": ["Collections"],
674
+ "operationId": "deleteCollection",
675
+ "summary": "Delete collection",
676
+ "parameters": [
677
+ { "name": "collection_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
678
+ ],
679
+ "responses": {
680
+ "200": {
681
+ "description": "Collection deleted.",
682
+ "content": {
683
+ "application/json": {
684
+ "schema": {
685
+ "allOf": [
686
+ { "$ref": "#/components/schemas/OkEnvelope" },
687
+ {
688
+ "type": "object",
689
+ "properties": {
690
+ "collection_id": { "type": "string", "format": "uuid" },
691
+ "deleted_collection": { "$ref": "#/components/schemas/Collection" }
692
+ }
693
+ }
694
+ ]
695
+ }
696
+ }
697
+ }
698
+ },
699
+ "401": { "$ref": "#/components/responses/Unauthorized" },
700
+ "404": { "$ref": "#/components/responses/NotFound" }
701
+ }
702
+ }
703
+ },
704
+ "/v1/collection/{collection_id}/track": {
705
+ "get": {
706
+ "tags": ["Tracks"],
707
+ "operationId": "listCollectionTracks",
708
+ "summary": "List tracks in a collection",
709
+ "parameters": [
710
+ { "name": "collection_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
711
+ { "$ref": "#/components/parameters/Limit" },
712
+ { "$ref": "#/components/parameters/Offset" }
713
+ ],
714
+ "responses": {
715
+ "200": {
716
+ "description": "Tracks list.",
717
+ "content": {
718
+ "application/json": {
719
+ "schema": {
720
+ "allOf": [
721
+ { "$ref": "#/components/schemas/OkEnvelope" },
722
+ {
723
+ "type": "object",
724
+ "properties": {
725
+ "count": { "type": "integer" },
726
+ "tracks": { "type": "array", "items": { "$ref": "#/components/schemas/Track" } }
727
+ }
728
+ }
729
+ ]
730
+ }
731
+ }
732
+ }
733
+ },
734
+ "401": { "$ref": "#/components/responses/Unauthorized" },
735
+ "404": { "$ref": "#/components/responses/NotFound" }
736
+ }
737
+ }
738
+ },
739
+ "/v1/collection/{collection_id}/cover": {
740
+ "post": {
741
+ "tags": ["Cover Images"],
742
+ "operationId": "createCollectionCover",
743
+ "summary": "Generate a collection cover image upload URL",
744
+ "parameters": [
745
+ { "name": "collection_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
746
+ ],
747
+ "responses": {
748
+ "200": {
749
+ "description": "Upload handle.",
750
+ "content": {
751
+ "application/json": {
752
+ "schema": {
753
+ "allOf": [
754
+ { "$ref": "#/components/schemas/OkEnvelope" },
755
+ {
756
+ "type": "object",
757
+ "properties": {
758
+ "collection_id": { "type": "string", "format": "uuid" },
759
+ "collection": { "$ref": "#/components/schemas/Collection" },
760
+ "collection_cover_upload": { "$ref": "#/components/schemas/UploadHandle" }
761
+ }
762
+ }
763
+ ]
764
+ }
765
+ }
766
+ }
767
+ },
768
+ "401": { "$ref": "#/components/responses/Unauthorized" },
769
+ "404": { "$ref": "#/components/responses/NotFound" }
770
+ }
771
+ }
772
+ },
773
+ "/v1/track": {
774
+ "post": {
775
+ "tags": ["Tracks"],
776
+ "operationId": "createTrack",
777
+ "summary": "Create a track",
778
+ "requestBody": {
779
+ "required": true,
780
+ "content": {
781
+ "application/json": {
782
+ "schema": {
783
+ "type": "object",
784
+ "required": ["collection_id", "file_name"],
785
+ "properties": {
786
+ "collection_id": { "type": "string", "format": "uuid" },
787
+ "creator_id": { "type": "string", "format": "uuid" },
788
+ "file_name": { "type": "string" },
789
+ "organization_index": { "type": "string" },
790
+ "metadata": { "type": "object", "additionalProperties": true },
791
+ "is_cover_overridable": { "type": "boolean" },
792
+ "is_theme_overridable": { "type": "boolean" },
793
+ "player_title": { "type": "string" },
794
+ "player_subtitle": { "type": "string" },
795
+ "player_color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" }
796
+ }
797
+ }
798
+ }
799
+ }
800
+ },
801
+ "responses": {
802
+ "200": {
803
+ "description": "Track created.",
804
+ "content": {
805
+ "application/json": {
806
+ "schema": {
807
+ "allOf": [
808
+ { "$ref": "#/components/schemas/OkEnvelope" },
809
+ {
810
+ "type": "object",
811
+ "properties": {
812
+ "track_id": { "type": "string", "format": "uuid" },
813
+ "track": { "$ref": "#/components/schemas/Track" },
814
+ "track_upload": { "$ref": "#/components/schemas/UploadHandle" },
815
+ "track_cover_upload": { "$ref": "#/components/schemas/UploadHandle" }
816
+ }
817
+ }
818
+ ]
819
+ }
820
+ }
821
+ }
822
+ },
823
+ "400": { "$ref": "#/components/responses/BadRequest" },
824
+ "401": { "$ref": "#/components/responses/Unauthorized" }
825
+ }
826
+ }
827
+ },
828
+ "/v1/track/{track_id}": {
829
+ "get": {
830
+ "tags": ["Tracks"],
831
+ "operationId": "getTrack",
832
+ "summary": "Get track",
833
+ "parameters": [
834
+ { "name": "track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
835
+ ],
836
+ "responses": {
837
+ "200": {
838
+ "description": "Track details.",
839
+ "content": {
840
+ "application/json": {
841
+ "schema": {
842
+ "allOf": [
843
+ { "$ref": "#/components/schemas/OkEnvelope" },
844
+ {
845
+ "type": "object",
846
+ "properties": {
847
+ "track_id": { "type": "string", "format": "uuid" },
848
+ "track": { "$ref": "#/components/schemas/Track" }
849
+ }
850
+ }
851
+ ]
852
+ }
853
+ }
854
+ }
855
+ },
856
+ "401": { "$ref": "#/components/responses/Unauthorized" },
857
+ "404": { "$ref": "#/components/responses/NotFound" }
858
+ }
859
+ },
860
+ "put": {
861
+ "tags": ["Tracks"],
862
+ "operationId": "updateTrack",
863
+ "summary": "Update track",
864
+ "parameters": [
865
+ { "name": "track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
866
+ ],
867
+ "requestBody": {
868
+ "required": true,
869
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Track" } } }
870
+ },
871
+ "responses": {
872
+ "200": {
873
+ "description": "Updated track.",
874
+ "content": {
875
+ "application/json": {
876
+ "schema": {
877
+ "allOf": [
878
+ { "$ref": "#/components/schemas/OkEnvelope" },
879
+ {
880
+ "type": "object",
881
+ "properties": {
882
+ "track_id": { "type": "string", "format": "uuid" },
883
+ "track": { "$ref": "#/components/schemas/Track" }
884
+ }
885
+ }
886
+ ]
887
+ }
888
+ }
889
+ }
890
+ },
891
+ "401": { "$ref": "#/components/responses/Unauthorized" },
892
+ "404": { "$ref": "#/components/responses/NotFound" }
893
+ }
894
+ },
895
+ "delete": {
896
+ "tags": ["Tracks"],
897
+ "operationId": "deleteTrack",
898
+ "summary": "Delete track",
899
+ "parameters": [
900
+ { "name": "track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
901
+ ],
902
+ "responses": {
903
+ "200": {
904
+ "description": "Track deleted.",
905
+ "content": {
906
+ "application/json": {
907
+ "schema": {
908
+ "allOf": [
909
+ { "$ref": "#/components/schemas/OkEnvelope" },
910
+ {
911
+ "type": "object",
912
+ "properties": {
913
+ "track_id": { "type": "string", "format": "uuid" },
914
+ "deleted_track": { "$ref": "#/components/schemas/Track" }
915
+ }
916
+ }
917
+ ]
918
+ }
919
+ }
920
+ }
921
+ },
922
+ "401": { "$ref": "#/components/responses/Unauthorized" },
923
+ "404": { "$ref": "#/components/responses/NotFound" }
924
+ }
925
+ }
926
+ },
927
+ "/v1/track/{track_id}/cover": {
928
+ "post": {
929
+ "tags": ["Cover Images"],
930
+ "operationId": "createTrackCover",
931
+ "summary": "Generate a track cover image upload URL",
932
+ "parameters": [
933
+ { "name": "track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
934
+ ],
935
+ "responses": {
936
+ "200": {
937
+ "description": "Upload handle.",
938
+ "content": {
939
+ "application/json": {
940
+ "schema": {
941
+ "allOf": [
942
+ { "$ref": "#/components/schemas/OkEnvelope" },
943
+ {
944
+ "type": "object",
945
+ "properties": {
946
+ "track_id": { "type": "string", "format": "uuid" },
947
+ "track": { "$ref": "#/components/schemas/Track" },
948
+ "track_cover_upload": { "$ref": "#/components/schemas/UploadHandle" }
949
+ }
950
+ }
951
+ ]
952
+ }
953
+ }
954
+ }
955
+ },
956
+ "401": { "$ref": "#/components/responses/Unauthorized" },
957
+ "404": { "$ref": "#/components/responses/NotFound" }
958
+ }
959
+ }
960
+ },
961
+ "/v1/track/{track_id}/variant": {
962
+ "post": {
963
+ "tags": ["Variants"],
964
+ "operationId": "addTrackVariant",
965
+ "summary": "Add a track-specific variant",
966
+ "description": "Appends a new track file to an already-processed track and queues processing. Only 'transcode' and 'preview' are supported. Common body fields: variant_type_id, index. Transcode fields: codec, bitrate, is_stereo, is_strip_tags, is_strip_cover (lossy codecs only; codec defaults to aac at 128 kbps). Preview fields: preview_type, preview_seconds / preview_min_percent / preview_max_percent (when preview_type is seconds), preview_percent / preview_min_seconds / preview_max_seconds (when preview_type is percent), preview_start_percent — plus the same Transcode audio fields. The track is moved to 'processing' and returns to 'ready' when the file is generated.",
967
+ "parameters": [
968
+ { "name": "track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
969
+ ],
970
+ "requestBody": {
971
+ "required": true,
972
+ "content": {
973
+ "application/json": {
974
+ "schema": {
975
+ "type": "object",
976
+ "required": ["variant_type_id", "index"],
977
+ "properties": {
978
+ "variant_type_id": { "type": "string", "enum": ["transcode", "preview"] },
979
+ "index": { "type": "string", "minLength": 2, "maxLength": 64, "description": "Delivery name; unique across organization and track variants" },
980
+ "codec": { "type": "string", "enum": ["aac", "mp3", "ogg", "opus"], "default": "aac" },
981
+ "bitrate": { "type": "integer", "minimum": 12, "maximum": 320, "default": 128 },
982
+ "is_stereo": { "type": "boolean", "default": true },
983
+ "is_strip_tags": { "type": "boolean", "default": true },
984
+ "is_strip_cover": { "type": "boolean", "default": true },
985
+ "preview_type": { "type": "string", "enum": ["seconds", "percent"], "default": "seconds", "description": "preview only" },
986
+ "preview_seconds": { "type": "number", "default": 60, "description": "preview + preview_type 'seconds'" },
987
+ "preview_min_percent": { "type": "number", "default": 0, "description": "preview + preview_type 'seconds'" },
988
+ "preview_max_percent": { "type": "number", "default": 50, "description": "preview + preview_type 'seconds'" },
989
+ "preview_percent": { "type": "number", "default": 25, "description": "preview + preview_type 'percent'" },
990
+ "preview_min_seconds": { "type": "number", "default": 0, "description": "preview + preview_type 'percent'" },
991
+ "preview_max_seconds": { "type": "number", "default": 90, "description": "preview + preview_type 'percent'" },
992
+ "preview_start_percent": { "type": "number", "minimum": 0, "maximum": 100, "default": 25, "description": "preview only: clip start as a percent of duration" }
993
+ }
994
+ }
995
+ }
996
+ }
997
+ },
998
+ "responses": {
999
+ "200": {
1000
+ "description": "Variant created and processing queued.",
1001
+ "content": {
1002
+ "application/json": {
1003
+ "schema": {
1004
+ "allOf": [
1005
+ { "$ref": "#/components/schemas/OkEnvelope" },
1006
+ {
1007
+ "type": "object",
1008
+ "properties": {
1009
+ "track_id": { "type": "string", "format": "uuid" },
1010
+ "variant_id": { "type": "string", "format": "uuid" },
1011
+ "job_id": { "type": "string", "format": "uuid" },
1012
+ "variant": { "$ref": "#/components/schemas/Variant" }
1013
+ }
1014
+ }
1015
+ ]
1016
+ }
1017
+ }
1018
+ }
1019
+ },
1020
+ "400": { "$ref": "#/components/responses/BadRequest" },
1021
+ "401": { "$ref": "#/components/responses/Unauthorized" },
1022
+ "404": { "$ref": "#/components/responses/NotFound" },
1023
+ "409": { "description": "A variant with the given index already exists for this track." },
1024
+ "422": { "description": "The track has no source file to process yet." }
1025
+ }
1026
+ }
1027
+ },
1028
+ "/v1/upload_session": {
1029
+ "post": {
1030
+ "tags": ["Upload Sessions"],
1031
+ "operationId": "createUploadSession",
1032
+ "summary": "Create upload session",
1033
+ "requestBody": {
1034
+ "required": true,
1035
+ "content": {
1036
+ "application/json": {
1037
+ "schema": {
1038
+ "type": "object",
1039
+ "properties": {
1040
+ "collection_id": { "type": "string", "format": "uuid", "description": "Required unless the API key is scoped to a collection." },
1041
+ "creator_id": { "type": "string", "format": "uuid" },
1042
+ "organization_index": { "type": "string" },
1043
+ "metadata": { "type": "object", "additionalProperties": true },
1044
+ "expires_in": { "type": "integer", "description": "Session duration in seconds (default 3600, min 60, max 86400).", "minimum": 60, "maximum": 86400, "default": 3600 }
1045
+ }
1046
+ }
1047
+ }
1048
+ }
1049
+ },
1050
+ "responses": {
1051
+ "200": {
1052
+ "description": "Upload session created.",
1053
+ "content": {
1054
+ "application/json": {
1055
+ "schema": {
1056
+ "allOf": [
1057
+ { "$ref": "#/components/schemas/OkEnvelope" },
1058
+ {
1059
+ "type": "object",
1060
+ "properties": {
1061
+ "upload_session_id": { "type": "string", "format": "uuid" },
1062
+ "upload_session": { "$ref": "#/components/schemas/UploadSession" },
1063
+ "player_color": { "type": "string", "nullable": true },
1064
+ "player_color_light": { "type": "string", "nullable": true },
1065
+ "player_color_dark": { "type": "string", "nullable": true },
1066
+ "expires_at": { "type": "string", "format": "date-time" }
1067
+ }
1068
+ }
1069
+ ]
1070
+ }
1071
+ }
1072
+ }
1073
+ },
1074
+ "400": { "$ref": "#/components/responses/BadRequest" },
1075
+ "401": { "$ref": "#/components/responses/Unauthorized" }
1076
+ }
1077
+ }
1078
+ },
1079
+ "/v1/upload_session/{upload_session_id}": {
1080
+ "get": {
1081
+ "tags": ["Upload Sessions"],
1082
+ "operationId": "getUploadSession",
1083
+ "summary": "Get upload session",
1084
+ "description": "No authentication required — the session ID acts as the credential.",
1085
+ "security": [],
1086
+ "parameters": [
1087
+ { "name": "upload_session_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
1088
+ ],
1089
+ "responses": {
1090
+ "200": {
1091
+ "description": "Upload session details.",
1092
+ "content": {
1093
+ "application/json": {
1094
+ "schema": {
1095
+ "allOf": [
1096
+ { "$ref": "#/components/schemas/OkEnvelope" },
1097
+ {
1098
+ "type": "object",
1099
+ "properties": {
1100
+ "upload_session_id": { "type": "string", "format": "uuid" },
1101
+ "upload_session": { "$ref": "#/components/schemas/UploadSession" }
1102
+ }
1103
+ }
1104
+ ]
1105
+ }
1106
+ }
1107
+ }
1108
+ },
1109
+ "401": { "$ref": "#/components/responses/Unauthorized" },
1110
+ "404": { "$ref": "#/components/responses/NotFound" }
1111
+ }
1112
+ }
1113
+ },
1114
+ "/v1/upload/{upload_session_id}/track": {
1115
+ "post": {
1116
+ "tags": ["Upload Sessions"],
1117
+ "operationId": "createUploadSessionTrack",
1118
+ "summary": "Create a track within an upload session",
1119
+ "description": "Call once per file to obtain a per-track upload URL. No authentication required — the session ID acts as the credential.",
1120
+ "security": [],
1121
+ "parameters": [
1122
+ { "name": "upload_session_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
1123
+ ],
1124
+ "requestBody": {
1125
+ "required": true,
1126
+ "content": {
1127
+ "application/json": {
1128
+ "schema": {
1129
+ "type": "object",
1130
+ "required": ["file_name"],
1131
+ "properties": {
1132
+ "file_name": { "type": "string" },
1133
+ "organization_index": { "type": "string" },
1134
+ "metadata": { "type": "object", "additionalProperties": true }
1135
+ }
1136
+ }
1137
+ }
1138
+ }
1139
+ },
1140
+ "responses": {
1141
+ "200": {
1142
+ "description": "Track and upload handle returned.",
1143
+ "content": {
1144
+ "application/json": {
1145
+ "schema": {
1146
+ "allOf": [
1147
+ { "$ref": "#/components/schemas/OkEnvelope" },
1148
+ {
1149
+ "type": "object",
1150
+ "properties": {
1151
+ "upload_session_id": { "type": "string", "format": "uuid" },
1152
+ "track_id": { "type": "string", "format": "uuid" },
1153
+ "track": { "$ref": "#/components/schemas/Track" },
1154
+ "upload_session": { "$ref": "#/components/schemas/UploadSession" },
1155
+ "track_upload": { "$ref": "#/components/schemas/UploadHandle" },
1156
+ "track_cover_upload": { "$ref": "#/components/schemas/UploadHandle" }
1157
+ }
1158
+ }
1159
+ ]
1160
+ }
1161
+ }
1162
+ }
1163
+ },
1164
+ "400": { "$ref": "#/components/responses/BadRequest" },
1165
+ "401": { "$ref": "#/components/responses/Unauthorized" },
1166
+ "404": { "$ref": "#/components/responses/NotFound" }
1167
+ }
1168
+ }
1169
+ },
1170
+ "/v1/play_session/{scope}": {
1171
+ "post": {
1172
+ "tags": ["Play Sessions"],
1173
+ "operationId": "createPlaySession",
1174
+ "summary": "Create play session",
1175
+ "parameters": [
1176
+ { "name": "scope", "in": "path", "required": true, "schema": { "type": "string", "enum": ["collection", "track"] }, "description": "\"collection\" or \"track\". \"playlist\" is reserved for a future release and currently returns 400." }
1177
+ ],
1178
+ "requestBody": {
1179
+ "required": true,
1180
+ "content": {
1181
+ "application/json": {
1182
+ "schema": {
1183
+ "type": "object",
1184
+ "properties": {
1185
+ "variants": { "type": "array", "items": { "type": "string" } },
1186
+ "collection_id": { "type": "string", "format": "uuid", "description": "Required when scope is 'collection'." },
1187
+ "track_id": { "type": "string", "format": "uuid", "description": "Required when scope is 'track'." },
1188
+ "is_downloadable": { "type": "boolean", "description": "Requests downloadable tracks. Only honored when the API key also allows downloads; the stored value is api_key.is_downloadable AND this request." },
1189
+ "expires_in": { "type": "integer", "description": "Session duration in seconds (default 3600, min 60, max 86400).", "minimum": 60, "maximum": 86400, "default": 3600 }
1190
+ }
1191
+ }
1192
+ }
1193
+ }
1194
+ },
1195
+ "responses": {
1196
+ "200": {
1197
+ "description": "Play session created.",
1198
+ "content": {
1199
+ "application/json": {
1200
+ "schema": {
1201
+ "allOf": [
1202
+ { "$ref": "#/components/schemas/OkEnvelope" },
1203
+ {
1204
+ "type": "object",
1205
+ "properties": {
1206
+ "play_session_id": { "type": "string", "format": "uuid" },
1207
+ "play_session": { "$ref": "#/components/schemas/PlaySession" },
1208
+ "tracks": { "type": "array", "items": { "$ref": "#/components/schemas/Track" } },
1209
+ "first_track": { "type": "object", "additionalProperties": true, "description": "Full playback data for the first track, including signed variant URLs, so a player can render without a second call." },
1210
+ "expires_at": { "type": "string", "format": "date-time" }
1211
+ }
1212
+ }
1213
+ ]
1214
+ }
1215
+ }
1216
+ }
1217
+ },
1218
+ "400": { "$ref": "#/components/responses/BadRequest" },
1219
+ "401": { "$ref": "#/components/responses/Unauthorized" }
1220
+ }
1221
+ }
1222
+ },
1223
+ "/v1/play_session/{play_session_id}": {
1224
+ "get": {
1225
+ "tags": ["Play Sessions"],
1226
+ "operationId": "getPlaySession",
1227
+ "summary": "Get play session",
1228
+ "parameters": [
1229
+ { "name": "play_session_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
1230
+ ],
1231
+ "responses": {
1232
+ "200": {
1233
+ "description": "Play session details.",
1234
+ "content": {
1235
+ "application/json": {
1236
+ "schema": {
1237
+ "allOf": [
1238
+ { "$ref": "#/components/schemas/OkEnvelope" },
1239
+ {
1240
+ "type": "object",
1241
+ "properties": {
1242
+ "play_session_id": { "type": "string", "format": "uuid" },
1243
+ "play_session": { "$ref": "#/components/schemas/PlaySession" },
1244
+ "tracks": { "type": "array", "items": { "$ref": "#/components/schemas/Track" } }
1245
+ }
1246
+ }
1247
+ ]
1248
+ }
1249
+ }
1250
+ }
1251
+ },
1252
+ "401": { "$ref": "#/components/responses/Unauthorized" },
1253
+ "404": { "$ref": "#/components/responses/NotFound" }
1254
+ }
1255
+ }
1256
+ },
1257
+ "/v1/play/{play_session_id}/{play_track_id}": {
1258
+ "get": {
1259
+ "tags": ["Play Sessions"],
1260
+ "operationId": "getPlayTrack",
1261
+ "summary": "Get a track within a play session",
1262
+ "description": "No authentication required — the session ID acts as the credential.",
1263
+ "security": [],
1264
+ "parameters": [
1265
+ { "name": "play_session_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
1266
+ { "name": "play_track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
1267
+ ],
1268
+ "responses": {
1269
+ "200": {
1270
+ "description": "Track within the play session, including signed variant URLs.",
1271
+ "content": {
1272
+ "application/json": {
1273
+ "schema": {
1274
+ "allOf": [
1275
+ { "$ref": "#/components/schemas/OkEnvelope" },
1276
+ {
1277
+ "type": "object",
1278
+ "properties": {
1279
+ "play_session_id": { "type": "string", "format": "uuid" },
1280
+ "track_id": { "type": "string", "format": "uuid" },
1281
+ "play_session": { "$ref": "#/components/schemas/PlaySession" },
1282
+ "cover_image": { "type": "string", "format": "uri" },
1283
+ "track": { "$ref": "#/components/schemas/Track" },
1284
+ "levels": { "type": "object", "additionalProperties": true },
1285
+ "variants": {
1286
+ "type": "array",
1287
+ "items": {
1288
+ "type": "object",
1289
+ "properties": {
1290
+ "path": { "type": "string", "format": "uri" },
1291
+ "url": { "type": "string", "format": "uri" }
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+ }
1297
+ ]
1298
+ }
1299
+ }
1300
+ }
1301
+ },
1302
+ "401": { "$ref": "#/components/responses/Unauthorized" },
1303
+ "404": { "$ref": "#/components/responses/NotFound" }
1304
+ }
1305
+ }
1306
+ },
1307
+ "/v1/play/{play_session_id}/{play_track_id}/{variant_index}/download": {
1308
+ "get": {
1309
+ "tags": ["Play Sessions"],
1310
+ "operationId": "downloadPlayTrackVariant",
1311
+ "summary": "Download a variant of a track within a play session",
1312
+ "description": "Returns a short-lived signed download URL for a specific variant. Only available when the session's stored is_downloadable is true; otherwise returns 403. No authentication required — the session ID acts as the credential.",
1313
+ "security": [],
1314
+ "parameters": [
1315
+ { "name": "play_session_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
1316
+ { "name": "play_track_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
1317
+ { "name": "variant_index", "in": "path", "required": true, "schema": { "type": "string" } }
1318
+ ],
1319
+ "responses": {
1320
+ "200": {
1321
+ "description": "Signed download URL.",
1322
+ "content": {
1323
+ "application/json": {
1324
+ "schema": {
1325
+ "allOf": [
1326
+ { "$ref": "#/components/schemas/OkEnvelope" },
1327
+ {
1328
+ "type": "object",
1329
+ "properties": {
1330
+ "download": {
1331
+ "type": "object",
1332
+ "properties": {
1333
+ "url": { "type": "string", "format": "uri" },
1334
+ "expires_at": { "type": "string", "format": "date-time" }
1335
+ }
1336
+ }
1337
+ }
1338
+ }
1339
+ ]
1340
+ }
1341
+ }
1342
+ }
1343
+ },
1344
+ "403": { "description": "The session is not downloadable." },
1345
+ "404": { "$ref": "#/components/responses/NotFound" }
1346
+ }
1347
+ }
1348
+ },
1349
+ "/v1/variant": {
1350
+ "get": {
1351
+ "tags": ["Variants"],
1352
+ "operationId": "listVariants",
1353
+ "summary": "List variants",
1354
+ "parameters": [
1355
+ { "$ref": "#/components/parameters/Limit" },
1356
+ { "$ref": "#/components/parameters/Offset" }
1357
+ ],
1358
+ "responses": {
1359
+ "200": {
1360
+ "description": "Variants list.",
1361
+ "content": {
1362
+ "application/json": {
1363
+ "schema": {
1364
+ "allOf": [
1365
+ { "$ref": "#/components/schemas/OkEnvelope" },
1366
+ {
1367
+ "type": "object",
1368
+ "properties": {
1369
+ "count": { "type": "integer" },
1370
+ "variants": { "type": "array", "items": { "$ref": "#/components/schemas/Variant" } }
1371
+ }
1372
+ }
1373
+ ]
1374
+ }
1375
+ }
1376
+ }
1377
+ },
1378
+ "401": { "$ref": "#/components/responses/Unauthorized" }
1379
+ }
1380
+ }
1381
+ },
1382
+ "/v1/variant/{variant_id}": {
1383
+ "get": {
1384
+ "tags": ["Variants"],
1385
+ "operationId": "getVariant",
1386
+ "summary": "Get variant",
1387
+ "parameters": [
1388
+ { "name": "variant_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
1389
+ ],
1390
+ "responses": {
1391
+ "200": {
1392
+ "description": "Variant details.",
1393
+ "content": {
1394
+ "application/json": {
1395
+ "schema": {
1396
+ "allOf": [
1397
+ { "$ref": "#/components/schemas/OkEnvelope" },
1398
+ {
1399
+ "type": "object",
1400
+ "properties": {
1401
+ "variant_id": { "type": "string", "format": "uuid" },
1402
+ "variant": { "$ref": "#/components/schemas/Variant" }
1403
+ }
1404
+ }
1405
+ ]
1406
+ }
1407
+ }
1408
+ }
1409
+ },
1410
+ "401": { "$ref": "#/components/responses/Unauthorized" },
1411
+ "404": { "$ref": "#/components/responses/NotFound" }
1412
+ }
1413
+ }
1414
+ }
1415
+ }
1416
+ }