diffusr 0.0.0-stage → 0.2.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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -2
  3. package/dist/cli/account.d.ts +19 -0
  4. package/dist/cli/account.js +250 -0
  5. package/dist/cli/account.js.map +1 -0
  6. package/dist/cli/args.d.ts +28 -0
  7. package/dist/cli/args.js +204 -0
  8. package/dist/cli/args.js.map +1 -0
  9. package/dist/cli/format.d.ts +10 -0
  10. package/dist/cli/format.js +80 -0
  11. package/dist/cli/format.js.map +1 -0
  12. package/dist/cli/io.d.ts +32 -0
  13. package/dist/cli/io.js +56 -0
  14. package/dist/cli/io.js.map +1 -0
  15. package/dist/cli/main.d.ts +3 -0
  16. package/dist/cli/main.js +176 -0
  17. package/dist/cli/main.js.map +1 -0
  18. package/dist/cli/ops.d.ts +22 -0
  19. package/dist/cli/ops.js +367 -0
  20. package/dist/cli/ops.js.map +1 -0
  21. package/dist/cli/spec.d.ts +37 -0
  22. package/dist/cli/spec.js +117 -0
  23. package/dist/cli/spec.js.map +1 -0
  24. package/dist/cli/spec.json +4207 -0
  25. package/dist/cli/test-helpers.d.ts +32 -0
  26. package/dist/cli/test-helpers.js +70 -0
  27. package/dist/cli/test-helpers.js.map +1 -0
  28. package/dist/cli.d.ts +2 -0
  29. package/dist/cli.js +9 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/client.d.ts +116 -0
  32. package/dist/client.js +281 -0
  33. package/dist/client.js.map +1 -0
  34. package/dist/config.d.ts +30 -0
  35. package/dist/config.js +71 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/errors.d.ts +21 -0
  38. package/dist/errors.js +23 -0
  39. package/dist/errors.js.map +1 -0
  40. package/dist/index.d.ts +8 -0
  41. package/dist/index.js +6 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/types.d.ts +208 -0
  44. package/dist/types.js +5 -0
  45. package/dist/types.js.map +1 -0
  46. package/dist/verify.d.ts +11 -0
  47. package/dist/verify.js +43 -0
  48. package/dist/verify.js.map +1 -0
  49. package/package.json +56 -3
@@ -0,0 +1,4207 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "diffusr API",
5
+ "version": "2",
6
+ "summary": "Make videos, images and music over REST.",
7
+ "description": "Every call that makes something costs credits (1 credit = $0.01). Start with `dry_run: true` to get the price for free.\n\nMake calls answer at once with a job id; the work runs in the background. Poll GET /results/{id} until status is SUCCEEDED, FAILED or CANCELED, or pass `callback_url` to be told.\n\nAuthenticate with `Authorization: Bearer dfsr_live_…` (real) or `dfsr_test_…` (free, fake output, real prices). Keys come from the Developers page in the app, or from `npx diffusr login` (see start_cli_login).\n\nSend an `Idempotency-Key` on every make call so a retry never pays twice."
8
+ },
9
+ "servers": [
10
+ {
11
+ "url": "https://app.diffusr.ai/api/v2"
12
+ }
13
+ ],
14
+ "tags": [
15
+ {
16
+ "name": "Make"
17
+ },
18
+ {
19
+ "name": "Results"
20
+ },
21
+ {
22
+ "name": "Uploads"
23
+ },
24
+ {
25
+ "name": "Models"
26
+ },
27
+ {
28
+ "name": "Creators"
29
+ },
30
+ {
31
+ "name": "Templates"
32
+ },
33
+ {
34
+ "name": "Callbacks"
35
+ },
36
+ {
37
+ "name": "Ads"
38
+ },
39
+ {
40
+ "name": "Account"
41
+ },
42
+ {
43
+ "name": "Login"
44
+ }
45
+ ],
46
+ "security": [
47
+ {
48
+ "bearerAuth": []
49
+ }
50
+ ],
51
+ "paths": {
52
+ "/make_video": {
53
+ "post": {
54
+ "operationId": "make_video",
55
+ "tags": [
56
+ "Make"
57
+ ],
58
+ "summary": "Make a video from a prompt",
59
+ "description": "Starts a video job. Send `dry_run: true` first to get the price without spending. Video takes 1-10 minutes: poll GET /results/{id} or pass `callback_url`.\n\nNeeds the `generate` scope.\n\nPrice list: direct. Add `dry_run: true` to see the price without spending.",
60
+ "x-tariff": "direct",
61
+ "parameters": [
62
+ {
63
+ "name": "Idempotency-Key",
64
+ "in": "header",
65
+ "required": false,
66
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
67
+ "schema": {
68
+ "type": "string",
69
+ "minLength": 1,
70
+ "maxLength": 255,
71
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
72
+ }
73
+ }
74
+ ],
75
+ "requestBody": {
76
+ "required": true,
77
+ "content": {
78
+ "application/json": {
79
+ "schema": {
80
+ "type": "object",
81
+ "properties": {
82
+ "prompt": {
83
+ "type": "string",
84
+ "maxLength": 10000,
85
+ "description": "The shot: subject, action, camera, setting, sound."
86
+ },
87
+ "image_urls": {
88
+ "description": "Optional reference pictures (a person, a product, a room, a first frame). Say in the prompt what each one is, by its place in this list — on Seedance: \"Image 1 is Mia, the speaker\". Public URLs — upload_asset gives you one for a local file.",
89
+ "type": "array",
90
+ "items": {
91
+ "type": "string",
92
+ "minLength": 1
93
+ }
94
+ },
95
+ "audio_urls": {
96
+ "description": "Optional voice or sound clips (models with takes_audio in list_models — the Seedance family). E.g. 5–10 s of the speaker's voice cut from an earlier clip, so the next clip keeps that voice. Name each in the prompt: \"Audio 1 is Mia's voice\". Public URLs.",
97
+ "type": "array",
98
+ "items": {
99
+ "type": "string",
100
+ "minLength": 1
101
+ }
102
+ },
103
+ "duration_sec": {
104
+ "description": "Length in seconds. Leave out for the model's default.",
105
+ "type": "integer",
106
+ "exclusiveMinimum": 0,
107
+ "maximum": 9007199254740991
108
+ },
109
+ "aspect_ratio": {
110
+ "description": "e.g. \"9:16\", \"16:9\", \"1:1\". Leave out for the model's default.",
111
+ "type": "string",
112
+ "minLength": 1
113
+ },
114
+ "resolution": {
115
+ "description": "e.g. \"720p\". Leave out for the model's default.",
116
+ "type": "string",
117
+ "minLength": 1
118
+ },
119
+ "model": {
120
+ "description": "Leave out for the recommended model. Ids come from list_models.",
121
+ "type": "string",
122
+ "minLength": 1
123
+ },
124
+ "dry_run": {
125
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
126
+ "type": "boolean"
127
+ },
128
+ "idempotency_key": {
129
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
130
+ "type": "string",
131
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
132
+ },
133
+ "callback_url": {
134
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
135
+ "type": "string",
136
+ "maxLength": 2048
137
+ }
138
+ },
139
+ "required": [
140
+ "prompt"
141
+ ]
142
+ }
143
+ }
144
+ }
145
+ },
146
+ "responses": {
147
+ "200": {
148
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
149
+ "content": {
150
+ "application/json": {
151
+ "schema": {
152
+ "$ref": "#/components/schemas/ApiDryRun"
153
+ }
154
+ }
155
+ }
156
+ },
157
+ "202": {
158
+ "description": "The job started. Poll GET /results/{id}.",
159
+ "content": {
160
+ "application/json": {
161
+ "schema": {
162
+ "$ref": "#/components/schemas/ApiStarted"
163
+ }
164
+ }
165
+ }
166
+ },
167
+ "401": {
168
+ "$ref": "#/components/responses/Unauthorized"
169
+ },
170
+ "402": {
171
+ "$ref": "#/components/responses/PaymentRequired"
172
+ },
173
+ "403": {
174
+ "$ref": "#/components/responses/Forbidden"
175
+ },
176
+ "409": {
177
+ "$ref": "#/components/responses/Conflict"
178
+ },
179
+ "413": {
180
+ "$ref": "#/components/responses/TooLarge"
181
+ },
182
+ "422": {
183
+ "$ref": "#/components/responses/Unprocessable"
184
+ },
185
+ "429": {
186
+ "$ref": "#/components/responses/RateLimited"
187
+ },
188
+ "500": {
189
+ "$ref": "#/components/responses/InternalError"
190
+ },
191
+ "503": {
192
+ "$ref": "#/components/responses/Unavailable"
193
+ }
194
+ }
195
+ }
196
+ },
197
+ "/make_image": {
198
+ "post": {
199
+ "operationId": "make_image",
200
+ "tags": [
201
+ "Make"
202
+ ],
203
+ "summary": "Make an image from a prompt",
204
+ "description": "Starts an image job (about 10-30 seconds).\n\nNeeds the `generate` scope.\n\nPrice list: direct. Add `dry_run: true` to see the price without spending.",
205
+ "x-tariff": "direct",
206
+ "parameters": [
207
+ {
208
+ "name": "Idempotency-Key",
209
+ "in": "header",
210
+ "required": false,
211
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
212
+ "schema": {
213
+ "type": "string",
214
+ "minLength": 1,
215
+ "maxLength": 255,
216
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
217
+ }
218
+ }
219
+ ],
220
+ "requestBody": {
221
+ "required": true,
222
+ "content": {
223
+ "application/json": {
224
+ "schema": {
225
+ "type": "object",
226
+ "properties": {
227
+ "prompt": {
228
+ "type": "string",
229
+ "maxLength": 10000,
230
+ "description": "The picture: subject, setting, light, style."
231
+ },
232
+ "image_urls": {
233
+ "description": "Optional reference pictures. Public URLs.",
234
+ "type": "array",
235
+ "items": {
236
+ "type": "string",
237
+ "minLength": 1
238
+ }
239
+ },
240
+ "aspect_ratio": {
241
+ "description": "e.g. \"9:16\", \"16:9\", \"1:1\". Leave out for the model's default.",
242
+ "type": "string",
243
+ "minLength": 1
244
+ },
245
+ "resolution": {
246
+ "description": "e.g. \"720p\". Leave out for the model's default.",
247
+ "type": "string",
248
+ "minLength": 1
249
+ },
250
+ "model": {
251
+ "description": "Leave out for the recommended model. Ids come from list_models.",
252
+ "type": "string",
253
+ "minLength": 1
254
+ },
255
+ "dry_run": {
256
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
257
+ "type": "boolean"
258
+ },
259
+ "idempotency_key": {
260
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
261
+ "type": "string",
262
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
263
+ },
264
+ "callback_url": {
265
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
266
+ "type": "string",
267
+ "maxLength": 2048
268
+ }
269
+ },
270
+ "required": [
271
+ "prompt"
272
+ ]
273
+ }
274
+ }
275
+ }
276
+ },
277
+ "responses": {
278
+ "200": {
279
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
280
+ "content": {
281
+ "application/json": {
282
+ "schema": {
283
+ "$ref": "#/components/schemas/ApiDryRun"
284
+ }
285
+ }
286
+ }
287
+ },
288
+ "202": {
289
+ "description": "The job started. Poll GET /results/{id}.",
290
+ "content": {
291
+ "application/json": {
292
+ "schema": {
293
+ "$ref": "#/components/schemas/ApiStarted"
294
+ }
295
+ }
296
+ }
297
+ },
298
+ "401": {
299
+ "$ref": "#/components/responses/Unauthorized"
300
+ },
301
+ "402": {
302
+ "$ref": "#/components/responses/PaymentRequired"
303
+ },
304
+ "403": {
305
+ "$ref": "#/components/responses/Forbidden"
306
+ },
307
+ "409": {
308
+ "$ref": "#/components/responses/Conflict"
309
+ },
310
+ "413": {
311
+ "$ref": "#/components/responses/TooLarge"
312
+ },
313
+ "422": {
314
+ "$ref": "#/components/responses/Unprocessable"
315
+ },
316
+ "429": {
317
+ "$ref": "#/components/responses/RateLimited"
318
+ },
319
+ "500": {
320
+ "$ref": "#/components/responses/InternalError"
321
+ },
322
+ "503": {
323
+ "$ref": "#/components/responses/Unavailable"
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "/edit_image": {
329
+ "post": {
330
+ "operationId": "edit_image",
331
+ "tags": [
332
+ "Make"
333
+ ],
334
+ "summary": "Edit a picture with a prompt",
335
+ "description": "Changes the picture in image_urls[0] as the prompt says.\n\nNeeds the `generate` scope.\n\nPrice list: direct. Add `dry_run: true` to see the price without spending.",
336
+ "x-tariff": "direct",
337
+ "parameters": [
338
+ {
339
+ "name": "Idempotency-Key",
340
+ "in": "header",
341
+ "required": false,
342
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
343
+ "schema": {
344
+ "type": "string",
345
+ "minLength": 1,
346
+ "maxLength": 255,
347
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
348
+ }
349
+ }
350
+ ],
351
+ "requestBody": {
352
+ "required": true,
353
+ "content": {
354
+ "application/json": {
355
+ "schema": {
356
+ "type": "object",
357
+ "properties": {
358
+ "image_urls": {
359
+ "minItems": 1,
360
+ "type": "array",
361
+ "items": {
362
+ "type": "string",
363
+ "minLength": 1
364
+ },
365
+ "description": "The picture to edit first, then any extra references. Public URLs."
366
+ },
367
+ "prompt": {
368
+ "type": "string",
369
+ "maxLength": 10000,
370
+ "description": "What changes, and what stays. e.g. \"Make the can matte black. Keep the hand and the rain.\""
371
+ },
372
+ "aspect_ratio": {
373
+ "description": "e.g. \"9:16\", \"16:9\", \"1:1\". Leave out for the model's default.",
374
+ "type": "string",
375
+ "minLength": 1
376
+ },
377
+ "resolution": {
378
+ "description": "e.g. \"720p\". Leave out for the model's default.",
379
+ "type": "string",
380
+ "minLength": 1
381
+ },
382
+ "model": {
383
+ "description": "Leave out for the recommended model. Ids come from list_models.",
384
+ "type": "string",
385
+ "minLength": 1
386
+ },
387
+ "dry_run": {
388
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
389
+ "type": "boolean"
390
+ },
391
+ "idempotency_key": {
392
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
393
+ "type": "string",
394
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
395
+ },
396
+ "callback_url": {
397
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
398
+ "type": "string",
399
+ "maxLength": 2048
400
+ }
401
+ },
402
+ "required": [
403
+ "image_urls",
404
+ "prompt"
405
+ ]
406
+ }
407
+ }
408
+ }
409
+ },
410
+ "responses": {
411
+ "200": {
412
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
413
+ "content": {
414
+ "application/json": {
415
+ "schema": {
416
+ "$ref": "#/components/schemas/ApiDryRun"
417
+ }
418
+ }
419
+ }
420
+ },
421
+ "202": {
422
+ "description": "The job started. Poll GET /results/{id}.",
423
+ "content": {
424
+ "application/json": {
425
+ "schema": {
426
+ "$ref": "#/components/schemas/ApiStarted"
427
+ }
428
+ }
429
+ }
430
+ },
431
+ "401": {
432
+ "$ref": "#/components/responses/Unauthorized"
433
+ },
434
+ "402": {
435
+ "$ref": "#/components/responses/PaymentRequired"
436
+ },
437
+ "403": {
438
+ "$ref": "#/components/responses/Forbidden"
439
+ },
440
+ "409": {
441
+ "$ref": "#/components/responses/Conflict"
442
+ },
443
+ "413": {
444
+ "$ref": "#/components/responses/TooLarge"
445
+ },
446
+ "422": {
447
+ "$ref": "#/components/responses/Unprocessable"
448
+ },
449
+ "429": {
450
+ "$ref": "#/components/responses/RateLimited"
451
+ },
452
+ "500": {
453
+ "$ref": "#/components/responses/InternalError"
454
+ },
455
+ "503": {
456
+ "$ref": "#/components/responses/Unavailable"
457
+ }
458
+ }
459
+ }
460
+ },
461
+ "/recast": {
462
+ "post": {
463
+ "operationId": "recast",
464
+ "tags": [
465
+ "Make"
466
+ ],
467
+ "summary": "Recast a video clip",
468
+ "description": "Keeps a clip's motion, camera and timing and swaps who or what is in it. The price follows the clip's real length, read from the file.\n\nNeeds the `generate` scope.\n\nPrice list: outcome. Add `dry_run: true` to see the price without spending.",
469
+ "x-tariff": "outcome",
470
+ "parameters": [
471
+ {
472
+ "name": "Idempotency-Key",
473
+ "in": "header",
474
+ "required": false,
475
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
476
+ "schema": {
477
+ "type": "string",
478
+ "minLength": 1,
479
+ "maxLength": 255,
480
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
481
+ }
482
+ }
483
+ ],
484
+ "requestBody": {
485
+ "required": true,
486
+ "content": {
487
+ "application/json": {
488
+ "schema": {
489
+ "type": "object",
490
+ "properties": {
491
+ "video_url": {
492
+ "type": "string",
493
+ "minLength": 1,
494
+ "description": "The source clip, an MP4 or MOV link (upload_asset gives one). Its motion, camera and timing are kept. At most 10 s on the default model (30 s on seedance-2-5): a longer clip is refused before anything is spent, so trim it first. Its real length is read from the file and is what you are priced on."
495
+ },
496
+ "image_urls": {
497
+ "description": "Photos of who or what should appear in the clip.",
498
+ "type": "array",
499
+ "items": {
500
+ "type": "string",
501
+ "minLength": 1
502
+ }
503
+ },
504
+ "mode": {
505
+ "description": "\"world\" = same motion, new people, place and look from the photos. \"swap\" = replace the main subject with the first photo, keep the rest. Use this OR prompt.",
506
+ "type": "string",
507
+ "enum": [
508
+ "world",
509
+ "swap"
510
+ ]
511
+ },
512
+ "prompt": {
513
+ "description": "Your own instruction instead of a mode. Say the change, then what to keep.",
514
+ "type": "string",
515
+ "maxLength": 10000
516
+ },
517
+ "duration_sec": {
518
+ "description": "Ignored. The output length follows your clip's real length, read from video_url (rounded, within the model's range). It is also what you are priced on.",
519
+ "type": "integer",
520
+ "exclusiveMinimum": 0,
521
+ "maximum": 9007199254740991
522
+ },
523
+ "aspect_ratio": {
524
+ "description": "e.g. \"9:16\", \"16:9\", \"1:1\". Leave out for the model's default.",
525
+ "type": "string",
526
+ "minLength": 1
527
+ },
528
+ "resolution": {
529
+ "description": "e.g. \"720p\". Leave out for the model's default.",
530
+ "type": "string",
531
+ "minLength": 1
532
+ },
533
+ "model": {
534
+ "description": "Leave out for the recommended model. Ids come from list_models.",
535
+ "type": "string",
536
+ "minLength": 1
537
+ },
538
+ "dry_run": {
539
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
540
+ "type": "boolean"
541
+ },
542
+ "idempotency_key": {
543
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
544
+ "type": "string",
545
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
546
+ },
547
+ "callback_url": {
548
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
549
+ "type": "string",
550
+ "maxLength": 2048
551
+ }
552
+ },
553
+ "required": [
554
+ "video_url"
555
+ ]
556
+ }
557
+ }
558
+ }
559
+ },
560
+ "responses": {
561
+ "200": {
562
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
563
+ "content": {
564
+ "application/json": {
565
+ "schema": {
566
+ "$ref": "#/components/schemas/ApiDryRun"
567
+ }
568
+ }
569
+ }
570
+ },
571
+ "202": {
572
+ "description": "The job started. Poll GET /results/{id}.",
573
+ "content": {
574
+ "application/json": {
575
+ "schema": {
576
+ "$ref": "#/components/schemas/ApiStarted"
577
+ }
578
+ }
579
+ }
580
+ },
581
+ "401": {
582
+ "$ref": "#/components/responses/Unauthorized"
583
+ },
584
+ "402": {
585
+ "$ref": "#/components/responses/PaymentRequired"
586
+ },
587
+ "403": {
588
+ "$ref": "#/components/responses/Forbidden"
589
+ },
590
+ "409": {
591
+ "$ref": "#/components/responses/Conflict"
592
+ },
593
+ "413": {
594
+ "$ref": "#/components/responses/TooLarge"
595
+ },
596
+ "422": {
597
+ "$ref": "#/components/responses/Unprocessable"
598
+ },
599
+ "429": {
600
+ "$ref": "#/components/responses/RateLimited"
601
+ },
602
+ "500": {
603
+ "$ref": "#/components/responses/InternalError"
604
+ },
605
+ "503": {
606
+ "$ref": "#/components/responses/Unavailable"
607
+ }
608
+ }
609
+ }
610
+ },
611
+ "/creator_video": {
612
+ "post": {
613
+ "operationId": "creator_video",
614
+ "tags": [
615
+ "Make"
616
+ ],
617
+ "summary": "Make a video of a creator saying a script",
618
+ "description": "A talking video from a creator in GET /creators. Gated preview.\n\nNeeds the `generate` scope.\n\nPrice list: outcome. Add `dry_run: true` to see the price without spending.",
619
+ "x-tariff": "outcome",
620
+ "parameters": [
621
+ {
622
+ "name": "Idempotency-Key",
623
+ "in": "header",
624
+ "required": false,
625
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
626
+ "schema": {
627
+ "type": "string",
628
+ "minLength": 1,
629
+ "maxLength": 255,
630
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
631
+ }
632
+ }
633
+ ],
634
+ "requestBody": {
635
+ "required": true,
636
+ "content": {
637
+ "application/json": {
638
+ "schema": {
639
+ "type": "object",
640
+ "properties": {
641
+ "creator_id": {
642
+ "type": "string",
643
+ "minLength": 1,
644
+ "description": "From list_creators."
645
+ },
646
+ "script": {
647
+ "type": "string",
648
+ "maxLength": 2000,
649
+ "description": "What the creator says to camera, word for word. Length of the video follows the script."
650
+ },
651
+ "resolution": {
652
+ "type": "string",
653
+ "enum": [
654
+ "480p",
655
+ "720p"
656
+ ]
657
+ },
658
+ "dry_run": {
659
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
660
+ "type": "boolean"
661
+ },
662
+ "idempotency_key": {
663
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
664
+ "type": "string",
665
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
666
+ },
667
+ "callback_url": {
668
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
669
+ "type": "string",
670
+ "maxLength": 2048
671
+ }
672
+ },
673
+ "required": [
674
+ "creator_id",
675
+ "script"
676
+ ]
677
+ }
678
+ }
679
+ }
680
+ },
681
+ "responses": {
682
+ "200": {
683
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
684
+ "content": {
685
+ "application/json": {
686
+ "schema": {
687
+ "$ref": "#/components/schemas/ApiDryRun"
688
+ }
689
+ }
690
+ }
691
+ },
692
+ "202": {
693
+ "description": "The job started. Poll GET /results/{id}.",
694
+ "content": {
695
+ "application/json": {
696
+ "schema": {
697
+ "$ref": "#/components/schemas/ApiStarted"
698
+ }
699
+ }
700
+ }
701
+ },
702
+ "401": {
703
+ "$ref": "#/components/responses/Unauthorized"
704
+ },
705
+ "402": {
706
+ "$ref": "#/components/responses/PaymentRequired"
707
+ },
708
+ "403": {
709
+ "$ref": "#/components/responses/Forbidden"
710
+ },
711
+ "409": {
712
+ "$ref": "#/components/responses/Conflict"
713
+ },
714
+ "413": {
715
+ "$ref": "#/components/responses/TooLarge"
716
+ },
717
+ "422": {
718
+ "$ref": "#/components/responses/Unprocessable"
719
+ },
720
+ "429": {
721
+ "$ref": "#/components/responses/RateLimited"
722
+ },
723
+ "500": {
724
+ "$ref": "#/components/responses/InternalError"
725
+ },
726
+ "503": {
727
+ "$ref": "#/components/responses/Unavailable"
728
+ }
729
+ }
730
+ }
731
+ },
732
+ "/make_music": {
733
+ "post": {
734
+ "operationId": "make_music",
735
+ "tags": [
736
+ "Make"
737
+ ],
738
+ "summary": "Make a song from a prompt",
739
+ "description": "One song, about a minute, on Lyria.\n\nNeeds the `generate` scope.\n\nPrice list: direct. Add `dry_run: true` to see the price without spending.",
740
+ "x-tariff": "direct",
741
+ "parameters": [
742
+ {
743
+ "name": "Idempotency-Key",
744
+ "in": "header",
745
+ "required": false,
746
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
747
+ "schema": {
748
+ "type": "string",
749
+ "minLength": 1,
750
+ "maxLength": 255,
751
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
752
+ }
753
+ }
754
+ ],
755
+ "requestBody": {
756
+ "required": true,
757
+ "content": {
758
+ "application/json": {
759
+ "schema": {
760
+ "type": "object",
761
+ "properties": {
762
+ "prompt": {
763
+ "type": "string",
764
+ "maxLength": 10000,
765
+ "description": "The song: genre, mood, instruments, tempo, and what it is for. Add lyrics with [Verse] / [Chorus] tags, or say \"Instrumental only, no vocals.\" Lyria picks the length (about a minute); a length in words is only a hint."
766
+ },
767
+ "dry_run": {
768
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
769
+ "type": "boolean"
770
+ },
771
+ "idempotency_key": {
772
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
773
+ "type": "string",
774
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
775
+ },
776
+ "callback_url": {
777
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
778
+ "type": "string",
779
+ "maxLength": 2048
780
+ }
781
+ },
782
+ "required": [
783
+ "prompt"
784
+ ]
785
+ }
786
+ }
787
+ }
788
+ },
789
+ "responses": {
790
+ "200": {
791
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
792
+ "content": {
793
+ "application/json": {
794
+ "schema": {
795
+ "$ref": "#/components/schemas/ApiDryRun"
796
+ }
797
+ }
798
+ }
799
+ },
800
+ "202": {
801
+ "description": "The job started. Poll GET /results/{id}.",
802
+ "content": {
803
+ "application/json": {
804
+ "schema": {
805
+ "$ref": "#/components/schemas/ApiStarted"
806
+ }
807
+ }
808
+ }
809
+ },
810
+ "401": {
811
+ "$ref": "#/components/responses/Unauthorized"
812
+ },
813
+ "402": {
814
+ "$ref": "#/components/responses/PaymentRequired"
815
+ },
816
+ "403": {
817
+ "$ref": "#/components/responses/Forbidden"
818
+ },
819
+ "409": {
820
+ "$ref": "#/components/responses/Conflict"
821
+ },
822
+ "413": {
823
+ "$ref": "#/components/responses/TooLarge"
824
+ },
825
+ "422": {
826
+ "$ref": "#/components/responses/Unprocessable"
827
+ },
828
+ "429": {
829
+ "$ref": "#/components/responses/RateLimited"
830
+ },
831
+ "500": {
832
+ "$ref": "#/components/responses/InternalError"
833
+ },
834
+ "503": {
835
+ "$ref": "#/components/responses/Unavailable"
836
+ }
837
+ }
838
+ }
839
+ },
840
+ "/run_template": {
841
+ "post": {
842
+ "operationId": "run_template",
843
+ "tags": [
844
+ "Make"
845
+ ],
846
+ "summary": "Run a template",
847
+ "description": "Runs one of the ready-made recipes from GET /templates (product ad, video template, talking head, podcast) as one job. Use `dry_run: true` for the price.\n\nNeeds the `generate` scope.\n\nPrice list: outcome. Add `dry_run: true` to see the price without spending.",
848
+ "x-tariff": "outcome",
849
+ "parameters": [
850
+ {
851
+ "name": "Idempotency-Key",
852
+ "in": "header",
853
+ "required": false,
854
+ "description": "1-255 visible ASCII characters you make up for this request (a UUID is fine). Send the same key to retry safely: you get the first job back instead of paying twice. Reusing a key for a different request answers 409 IDEMPOTENCY_CONFLICT. Wins over `idempotency_key` in the body.",
855
+ "schema": {
856
+ "type": "string",
857
+ "minLength": 1,
858
+ "maxLength": 255,
859
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
860
+ }
861
+ }
862
+ ],
863
+ "requestBody": {
864
+ "required": true,
865
+ "content": {
866
+ "application/json": {
867
+ "schema": {
868
+ "type": "object",
869
+ "properties": {
870
+ "template": {
871
+ "type": "string",
872
+ "minLength": 1,
873
+ "description": "The template's id, from list_templates."
874
+ },
875
+ "mode": {
876
+ "description": "Video templates only. \"remix\" (default) = make a new video like the template, from your pictures and prompt. \"recast\" = keep the template's moves and swap who is in it for your image_urls.",
877
+ "type": "string",
878
+ "enum": [
879
+ "remix",
880
+ "recast"
881
+ ]
882
+ },
883
+ "prompt": {
884
+ "description": "Product ads: an optional change to the ad (\"make it a winter sale\"). Video templates: remix = your version of the template's prompt (leave out to use the template's own); recast = what to change.",
885
+ "type": "string",
886
+ "maxLength": 10000
887
+ },
888
+ "pictures": {
889
+ "description": "Video template remix: one picture per slot, keyed by the slot name from list_templates (e.g. {\"him\": \"https://…\"}).",
890
+ "type": "object",
891
+ "propertyNames": {
892
+ "type": "string",
893
+ "minLength": 1
894
+ },
895
+ "additionalProperties": {
896
+ "type": "string",
897
+ "minLength": 1
898
+ }
899
+ },
900
+ "image_urls": {
901
+ "description": "Video template recast: photos of who should appear in the clip.",
902
+ "maxItems": 10,
903
+ "type": "array",
904
+ "items": {
905
+ "type": "string",
906
+ "minLength": 1
907
+ }
908
+ },
909
+ "product_image_url": {
910
+ "description": "Product ads: a photo of your product, uploaded with upload_asset. Talking head: optional, shows the product on camera.",
911
+ "type": "string",
912
+ "minLength": 1
913
+ },
914
+ "script": {
915
+ "description": "Talking head: what the person says, word for word. Podcast: one line per turn, written \"Name: what they say\", the names exactly as in people. Everything must fit one 30 s take.",
916
+ "type": "string",
917
+ "maxLength": 4000
918
+ },
919
+ "place": {
920
+ "description": "Talking head: where they are, in a few words, e.g. \"a small Paris hotel room with a tall window\".",
921
+ "type": "string",
922
+ "maxLength": 300
923
+ },
924
+ "people": {
925
+ "description": "Talking head: one person. Podcast: two hosts, the first sits on the left.",
926
+ "maxItems": 2,
927
+ "type": "array",
928
+ "items": {
929
+ "type": "object",
930
+ "properties": {
931
+ "name": {
932
+ "type": "string",
933
+ "minLength": 1,
934
+ "maxLength": 40,
935
+ "description": "What the script calls them, e.g. \"Mia\". Plain first names work best."
936
+ },
937
+ "image_url": {
938
+ "type": "string",
939
+ "minLength": 1,
940
+ "description": "A clear photo of their face. A public link — upload_asset gives one for a local file."
941
+ },
942
+ "look": {
943
+ "description": "Optional. Age, hair and outfit in a few words, e.g. \"30s, short dark hair, green jacket\". Leave out to keep what the photo shows.",
944
+ "type": "string",
945
+ "maxLength": 300
946
+ }
947
+ },
948
+ "required": [
949
+ "name",
950
+ "image_url"
951
+ ]
952
+ }
953
+ },
954
+ "setup": {
955
+ "description": "Talking head on the plain template: how it is filmed — \"selfie\" (default), \"propped\" or \"friend\".",
956
+ "type": "string",
957
+ "enum": [
958
+ "selfie",
959
+ "propped",
960
+ "friend"
961
+ ]
962
+ },
963
+ "resolution": {
964
+ "description": "Leave out for the template's own default. 480p costs less.",
965
+ "type": "string",
966
+ "enum": [
967
+ "480p",
968
+ "720p"
969
+ ]
970
+ },
971
+ "dry_run": {
972
+ "description": "true = only check the request and return the price in credits. Nothing is made, nothing is spent.",
973
+ "type": "boolean"
974
+ },
975
+ "idempotency_key": {
976
+ "description": "A unique string you make up for this request. Retry with the same key and you get the first result back instead of paying again.",
977
+ "type": "string",
978
+ "pattern": "^[\\x21-\\x7e]{1,255}$"
979
+ },
980
+ "callback_url": {
981
+ "description": "Optional. A public https:// link. When the job finishes (done, failed or canceled) we POST the finished result here, signed. See the docs for checking the signature. Polling get_result still works.",
982
+ "type": "string",
983
+ "maxLength": 2048
984
+ }
985
+ },
986
+ "required": [
987
+ "template"
988
+ ]
989
+ }
990
+ }
991
+ }
992
+ },
993
+ "responses": {
994
+ "200": {
995
+ "description": "dry_run was true: the price, nothing made, nothing spent.",
996
+ "content": {
997
+ "application/json": {
998
+ "schema": {
999
+ "$ref": "#/components/schemas/ApiDryRun"
1000
+ }
1001
+ }
1002
+ }
1003
+ },
1004
+ "202": {
1005
+ "description": "The job started. Poll GET /results/{id}.",
1006
+ "content": {
1007
+ "application/json": {
1008
+ "schema": {
1009
+ "$ref": "#/components/schemas/ApiStarted"
1010
+ }
1011
+ }
1012
+ }
1013
+ },
1014
+ "401": {
1015
+ "$ref": "#/components/responses/Unauthorized"
1016
+ },
1017
+ "402": {
1018
+ "$ref": "#/components/responses/PaymentRequired"
1019
+ },
1020
+ "403": {
1021
+ "$ref": "#/components/responses/Forbidden"
1022
+ },
1023
+ "409": {
1024
+ "$ref": "#/components/responses/Conflict"
1025
+ },
1026
+ "413": {
1027
+ "$ref": "#/components/responses/TooLarge"
1028
+ },
1029
+ "422": {
1030
+ "$ref": "#/components/responses/Unprocessable"
1031
+ },
1032
+ "429": {
1033
+ "$ref": "#/components/responses/RateLimited"
1034
+ },
1035
+ "500": {
1036
+ "$ref": "#/components/responses/InternalError"
1037
+ },
1038
+ "503": {
1039
+ "$ref": "#/components/responses/Unavailable"
1040
+ }
1041
+ }
1042
+ }
1043
+ },
1044
+ "/uploads": {
1045
+ "post": {
1046
+ "operationId": "upload_asset",
1047
+ "tags": [
1048
+ "Uploads"
1049
+ ],
1050
+ "summary": "Upload a file to use as a reference",
1051
+ "description": "Two ways in. Pass `source_url` (a public link) and we copy it. Or pass `content_type` + `size_bytes` for a local file: you get an `upload_url` to PUT the bytes to, then use `file_url` in a tool.\n\nNeeds the `uploads` scope.",
1052
+ "requestBody": {
1053
+ "required": true,
1054
+ "content": {
1055
+ "application/json": {
1056
+ "schema": {
1057
+ "type": "object",
1058
+ "properties": {
1059
+ "source_url": {
1060
+ "description": "A public http(s) URL to copy in. Use this OR the three fields below.",
1061
+ "type": "string",
1062
+ "minLength": 1
1063
+ },
1064
+ "content_type": {
1065
+ "description": "For a LOCAL file: its MIME type, e.g. \"video/mp4\", \"image/jpeg\".",
1066
+ "type": "string",
1067
+ "minLength": 1
1068
+ },
1069
+ "size_bytes": {
1070
+ "description": "For a LOCAL file: its exact size in bytes.",
1071
+ "type": "integer",
1072
+ "exclusiveMinimum": 0,
1073
+ "maximum": 9007199254740991
1074
+ }
1075
+ }
1076
+ }
1077
+ }
1078
+ }
1079
+ },
1080
+ "responses": {
1081
+ "201": {
1082
+ "description": "A file_url (URL copied in), or an upload_url to PUT the bytes to.",
1083
+ "content": {
1084
+ "application/json": {
1085
+ "schema": {
1086
+ "$ref": "#/components/schemas/ApiUpload"
1087
+ }
1088
+ }
1089
+ }
1090
+ },
1091
+ "401": {
1092
+ "$ref": "#/components/responses/Unauthorized"
1093
+ },
1094
+ "403": {
1095
+ "$ref": "#/components/responses/Forbidden"
1096
+ },
1097
+ "422": {
1098
+ "$ref": "#/components/responses/Unprocessable"
1099
+ },
1100
+ "429": {
1101
+ "$ref": "#/components/responses/RateLimited"
1102
+ },
1103
+ "500": {
1104
+ "$ref": "#/components/responses/InternalError"
1105
+ },
1106
+ "503": {
1107
+ "$ref": "#/components/responses/Unavailable"
1108
+ }
1109
+ }
1110
+ }
1111
+ },
1112
+ "/results": {
1113
+ "get": {
1114
+ "operationId": "list_results",
1115
+ "tags": [
1116
+ "Results"
1117
+ ],
1118
+ "summary": "List your recent jobs",
1119
+ "description": "Needs the `results:read` scope.",
1120
+ "parameters": [
1121
+ {
1122
+ "name": "limit",
1123
+ "in": "query",
1124
+ "required": false,
1125
+ "description": "Default 20.",
1126
+ "schema": {
1127
+ "type": "integer",
1128
+ "minimum": 1,
1129
+ "maximum": 50
1130
+ }
1131
+ }
1132
+ ],
1133
+ "responses": {
1134
+ "200": {
1135
+ "description": "Your latest jobs, newest first.",
1136
+ "content": {
1137
+ "application/json": {
1138
+ "schema": {
1139
+ "$ref": "#/components/schemas/ApiResultList"
1140
+ }
1141
+ }
1142
+ }
1143
+ },
1144
+ "401": {
1145
+ "$ref": "#/components/responses/Unauthorized"
1146
+ },
1147
+ "403": {
1148
+ "$ref": "#/components/responses/Forbidden"
1149
+ },
1150
+ "422": {
1151
+ "$ref": "#/components/responses/Unprocessable"
1152
+ },
1153
+ "429": {
1154
+ "$ref": "#/components/responses/RateLimited"
1155
+ },
1156
+ "500": {
1157
+ "$ref": "#/components/responses/InternalError"
1158
+ },
1159
+ "503": {
1160
+ "$ref": "#/components/responses/Unavailable"
1161
+ }
1162
+ }
1163
+ }
1164
+ },
1165
+ "/results/{id}": {
1166
+ "get": {
1167
+ "operationId": "get_result",
1168
+ "tags": [
1169
+ "Results"
1170
+ ],
1171
+ "summary": "Get one job",
1172
+ "description": "Status, output once it is done, and what it charged. Keep calling every 15-30 seconds until status is SUCCEEDED, FAILED or CANCELED. An id from the other key mode (test vs live) answers 404.\n\nNeeds the `results:read` scope.",
1173
+ "parameters": [
1174
+ {
1175
+ "name": "id",
1176
+ "in": "path",
1177
+ "required": true,
1178
+ "description": "The job id from a make call.",
1179
+ "schema": {
1180
+ "type": "string"
1181
+ }
1182
+ }
1183
+ ],
1184
+ "responses": {
1185
+ "200": {
1186
+ "description": "The job.",
1187
+ "content": {
1188
+ "application/json": {
1189
+ "schema": {
1190
+ "$ref": "#/components/schemas/ApiResult"
1191
+ }
1192
+ }
1193
+ }
1194
+ },
1195
+ "401": {
1196
+ "$ref": "#/components/responses/Unauthorized"
1197
+ },
1198
+ "403": {
1199
+ "$ref": "#/components/responses/Forbidden"
1200
+ },
1201
+ "404": {
1202
+ "$ref": "#/components/responses/NotFound"
1203
+ },
1204
+ "429": {
1205
+ "$ref": "#/components/responses/RateLimited"
1206
+ },
1207
+ "500": {
1208
+ "$ref": "#/components/responses/InternalError"
1209
+ },
1210
+ "503": {
1211
+ "$ref": "#/components/responses/Unavailable"
1212
+ }
1213
+ }
1214
+ }
1215
+ },
1216
+ "/results/{id}/cancel": {
1217
+ "post": {
1218
+ "operationId": "cancel_result",
1219
+ "tags": [
1220
+ "Results"
1221
+ ],
1222
+ "summary": "Stop a job that has not finished",
1223
+ "description": "`charge` on the answer says what was charged. Work that was not delivered is not charged.\n\nNeeds the `generate` scope.",
1224
+ "parameters": [
1225
+ {
1226
+ "name": "id",
1227
+ "in": "path",
1228
+ "required": true,
1229
+ "description": "The job id from a make call.",
1230
+ "schema": {
1231
+ "type": "string"
1232
+ }
1233
+ }
1234
+ ],
1235
+ "responses": {
1236
+ "200": {
1237
+ "description": "The job after the cancel. A job that already finished comes back unchanged.",
1238
+ "content": {
1239
+ "application/json": {
1240
+ "schema": {
1241
+ "$ref": "#/components/schemas/ApiResult"
1242
+ }
1243
+ }
1244
+ }
1245
+ },
1246
+ "401": {
1247
+ "$ref": "#/components/responses/Unauthorized"
1248
+ },
1249
+ "403": {
1250
+ "$ref": "#/components/responses/Forbidden"
1251
+ },
1252
+ "404": {
1253
+ "$ref": "#/components/responses/NotFound"
1254
+ },
1255
+ "422": {
1256
+ "$ref": "#/components/responses/Unprocessable"
1257
+ },
1258
+ "429": {
1259
+ "$ref": "#/components/responses/RateLimited"
1260
+ },
1261
+ "500": {
1262
+ "$ref": "#/components/responses/InternalError"
1263
+ },
1264
+ "503": {
1265
+ "$ref": "#/components/responses/Unavailable"
1266
+ }
1267
+ }
1268
+ }
1269
+ },
1270
+ "/models": {
1271
+ "get": {
1272
+ "operationId": "list_models",
1273
+ "tags": [
1274
+ "Models"
1275
+ ],
1276
+ "summary": "List models and their prices",
1277
+ "description": "Public: works without a key. With a key it counts toward your price-check limit.",
1278
+ "security": [
1279
+ {},
1280
+ {
1281
+ "bearerAuth": []
1282
+ }
1283
+ ],
1284
+ "parameters": [
1285
+ {
1286
+ "name": "kind",
1287
+ "in": "query",
1288
+ "required": false,
1289
+ "schema": {
1290
+ "type": "string",
1291
+ "enum": [
1292
+ "video",
1293
+ "image"
1294
+ ]
1295
+ }
1296
+ }
1297
+ ],
1298
+ "responses": {
1299
+ "200": {
1300
+ "description": "The models you can pass as `model`, with prices.",
1301
+ "content": {
1302
+ "application/json": {
1303
+ "schema": {
1304
+ "$ref": "#/components/schemas/ApiModelList"
1305
+ }
1306
+ }
1307
+ }
1308
+ },
1309
+ "422": {
1310
+ "$ref": "#/components/responses/Unprocessable"
1311
+ },
1312
+ "429": {
1313
+ "$ref": "#/components/responses/RateLimited"
1314
+ },
1315
+ "500": {
1316
+ "$ref": "#/components/responses/InternalError"
1317
+ },
1318
+ "503": {
1319
+ "$ref": "#/components/responses/Unavailable"
1320
+ }
1321
+ }
1322
+ }
1323
+ },
1324
+ "/creators": {
1325
+ "get": {
1326
+ "operationId": "list_creators",
1327
+ "tags": [
1328
+ "Creators"
1329
+ ],
1330
+ "summary": "List creators for creator_video",
1331
+ "description": "Gated preview: accounts not on the list get the 404 a bad URL gets.\n\nNeeds the `generate` scope.",
1332
+ "responses": {
1333
+ "200": {
1334
+ "description": "Creators you can use in creator_video.",
1335
+ "content": {
1336
+ "application/json": {
1337
+ "schema": {
1338
+ "$ref": "#/components/schemas/ApiCreatorList"
1339
+ }
1340
+ }
1341
+ }
1342
+ },
1343
+ "401": {
1344
+ "$ref": "#/components/responses/Unauthorized"
1345
+ },
1346
+ "403": {
1347
+ "$ref": "#/components/responses/Forbidden"
1348
+ },
1349
+ "404": {
1350
+ "$ref": "#/components/responses/NotFound"
1351
+ },
1352
+ "429": {
1353
+ "$ref": "#/components/responses/RateLimited"
1354
+ },
1355
+ "500": {
1356
+ "$ref": "#/components/responses/InternalError"
1357
+ },
1358
+ "503": {
1359
+ "$ref": "#/components/responses/Unavailable"
1360
+ }
1361
+ }
1362
+ }
1363
+ },
1364
+ "/templates": {
1365
+ "get": {
1366
+ "operationId": "list_templates",
1367
+ "tags": [
1368
+ "Templates"
1369
+ ],
1370
+ "summary": "List the templates run_template can run",
1371
+ "description": "Each template says what inputs it needs (name, type, required) and a rough price. Pass `dry_run: true` to run_template for the exact price.\n\nNeeds the `generate` scope.",
1372
+ "responses": {
1373
+ "200": {
1374
+ "description": "Templates run_template can run, with the inputs each needs.",
1375
+ "content": {
1376
+ "application/json": {
1377
+ "schema": {
1378
+ "$ref": "#/components/schemas/ApiTemplateList"
1379
+ }
1380
+ }
1381
+ }
1382
+ },
1383
+ "401": {
1384
+ "$ref": "#/components/responses/Unauthorized"
1385
+ },
1386
+ "403": {
1387
+ "$ref": "#/components/responses/Forbidden"
1388
+ },
1389
+ "429": {
1390
+ "$ref": "#/components/responses/RateLimited"
1391
+ },
1392
+ "500": {
1393
+ "$ref": "#/components/responses/InternalError"
1394
+ },
1395
+ "503": {
1396
+ "$ref": "#/components/responses/Unavailable"
1397
+ }
1398
+ }
1399
+ }
1400
+ },
1401
+ "/callbacks": {
1402
+ "get": {
1403
+ "operationId": "list_callbacks",
1404
+ "tags": [
1405
+ "Callbacks"
1406
+ ],
1407
+ "summary": "List callback deliveries",
1408
+ "description": "Needs the `results:read` scope.",
1409
+ "parameters": [
1410
+ {
1411
+ "name": "limit",
1412
+ "in": "query",
1413
+ "required": false,
1414
+ "description": "Default 20.",
1415
+ "schema": {
1416
+ "type": "integer",
1417
+ "minimum": 1,
1418
+ "maximum": 100
1419
+ }
1420
+ },
1421
+ {
1422
+ "name": "cursor",
1423
+ "in": "query",
1424
+ "required": false,
1425
+ "description": "The next_cursor of the last page.",
1426
+ "schema": {
1427
+ "type": "string",
1428
+ "minLength": 1,
1429
+ "maxLength": 200
1430
+ }
1431
+ }
1432
+ ],
1433
+ "responses": {
1434
+ "200": {
1435
+ "description": "Your callback delivery log, newest first.",
1436
+ "content": {
1437
+ "application/json": {
1438
+ "schema": {
1439
+ "$ref": "#/components/schemas/ApiCallbackDeliveryList"
1440
+ }
1441
+ }
1442
+ }
1443
+ },
1444
+ "401": {
1445
+ "$ref": "#/components/responses/Unauthorized"
1446
+ },
1447
+ "403": {
1448
+ "$ref": "#/components/responses/Forbidden"
1449
+ },
1450
+ "422": {
1451
+ "$ref": "#/components/responses/Unprocessable"
1452
+ },
1453
+ "429": {
1454
+ "$ref": "#/components/responses/RateLimited"
1455
+ },
1456
+ "500": {
1457
+ "$ref": "#/components/responses/InternalError"
1458
+ },
1459
+ "503": {
1460
+ "$ref": "#/components/responses/Unavailable"
1461
+ }
1462
+ }
1463
+ }
1464
+ },
1465
+ "/callbacks/{event_id}/retry": {
1466
+ "post": {
1467
+ "operationId": "retry_callback",
1468
+ "tags": [
1469
+ "Callbacks"
1470
+ ],
1471
+ "summary": "Retry a failed callback by hand",
1472
+ "description": "Only for a FAILED event; at most 3 manual retries per event (else CALLBACK_NOT_RETRYABLE).\n\nNeeds the `results:read` scope.",
1473
+ "parameters": [
1474
+ {
1475
+ "name": "event_id",
1476
+ "in": "path",
1477
+ "required": true,
1478
+ "description": "The callback event id (\"evt_…\").",
1479
+ "schema": {
1480
+ "type": "string"
1481
+ }
1482
+ }
1483
+ ],
1484
+ "responses": {
1485
+ "202": {
1486
+ "description": "The event, queued for another try.",
1487
+ "content": {
1488
+ "application/json": {
1489
+ "schema": {
1490
+ "$ref": "#/components/schemas/ApiCallbackDeliveryItem"
1491
+ }
1492
+ }
1493
+ }
1494
+ },
1495
+ "401": {
1496
+ "$ref": "#/components/responses/Unauthorized"
1497
+ },
1498
+ "403": {
1499
+ "$ref": "#/components/responses/Forbidden"
1500
+ },
1501
+ "404": {
1502
+ "$ref": "#/components/responses/NotFound"
1503
+ },
1504
+ "409": {
1505
+ "$ref": "#/components/responses/Conflict"
1506
+ },
1507
+ "422": {
1508
+ "$ref": "#/components/responses/Unprocessable"
1509
+ },
1510
+ "429": {
1511
+ "$ref": "#/components/responses/RateLimited"
1512
+ },
1513
+ "500": {
1514
+ "$ref": "#/components/responses/InternalError"
1515
+ },
1516
+ "503": {
1517
+ "$ref": "#/components/responses/Unavailable"
1518
+ }
1519
+ }
1520
+ }
1521
+ },
1522
+ "/callbacks/secret": {
1523
+ "get": {
1524
+ "operationId": "get_callback_secret",
1525
+ "tags": [
1526
+ "Callbacks"
1527
+ ],
1528
+ "summary": "Get your callback signing secret",
1529
+ "description": "Needs the `results:read` scope.",
1530
+ "responses": {
1531
+ "200": {
1532
+ "description": "Your signing secret (made on the first ask).",
1533
+ "content": {
1534
+ "application/json": {
1535
+ "schema": {
1536
+ "$ref": "#/components/schemas/ApiCallbackSecretView"
1537
+ }
1538
+ }
1539
+ }
1540
+ },
1541
+ "401": {
1542
+ "$ref": "#/components/responses/Unauthorized"
1543
+ },
1544
+ "403": {
1545
+ "$ref": "#/components/responses/Forbidden"
1546
+ },
1547
+ "429": {
1548
+ "$ref": "#/components/responses/RateLimited"
1549
+ },
1550
+ "500": {
1551
+ "$ref": "#/components/responses/InternalError"
1552
+ },
1553
+ "503": {
1554
+ "$ref": "#/components/responses/Unavailable"
1555
+ }
1556
+ }
1557
+ }
1558
+ },
1559
+ "/callbacks/secret/rotate": {
1560
+ "post": {
1561
+ "operationId": "rotate_callback_secret",
1562
+ "tags": [
1563
+ "Callbacks"
1564
+ ],
1565
+ "summary": "Make a new callback signing secret",
1566
+ "description": "Needs the `results:read` scope.",
1567
+ "responses": {
1568
+ "200": {
1569
+ "description": "The new secret. The old one keeps signing for 24 hours.",
1570
+ "content": {
1571
+ "application/json": {
1572
+ "schema": {
1573
+ "$ref": "#/components/schemas/ApiCallbackSecretView"
1574
+ }
1575
+ }
1576
+ }
1577
+ },
1578
+ "401": {
1579
+ "$ref": "#/components/responses/Unauthorized"
1580
+ },
1581
+ "403": {
1582
+ "$ref": "#/components/responses/Forbidden"
1583
+ },
1584
+ "422": {
1585
+ "$ref": "#/components/responses/Unprocessable"
1586
+ },
1587
+ "429": {
1588
+ "$ref": "#/components/responses/RateLimited"
1589
+ },
1590
+ "500": {
1591
+ "$ref": "#/components/responses/InternalError"
1592
+ },
1593
+ "503": {
1594
+ "$ref": "#/components/responses/Unavailable"
1595
+ }
1596
+ }
1597
+ }
1598
+ },
1599
+ "/ads/accounts": {
1600
+ "get": {
1601
+ "operationId": "ads_list_accounts",
1602
+ "tags": [
1603
+ "Ads"
1604
+ ],
1605
+ "summary": "List connected ad accounts",
1606
+ "description": "Gated: accounts without ads get the 404 a bad URL gets.\n\nNeeds the `ads:read` scope.",
1607
+ "responses": {
1608
+ "200": {
1609
+ "description": "Connected ad accounts and whether each is ready.",
1610
+ "content": {
1611
+ "application/json": {
1612
+ "schema": {
1613
+ "$ref": "#/components/schemas/ApiAdsAccountList"
1614
+ }
1615
+ }
1616
+ }
1617
+ },
1618
+ "401": {
1619
+ "$ref": "#/components/responses/Unauthorized"
1620
+ },
1621
+ "403": {
1622
+ "$ref": "#/components/responses/Forbidden"
1623
+ },
1624
+ "404": {
1625
+ "$ref": "#/components/responses/NotFound"
1626
+ },
1627
+ "429": {
1628
+ "$ref": "#/components/responses/RateLimited"
1629
+ },
1630
+ "500": {
1631
+ "$ref": "#/components/responses/InternalError"
1632
+ },
1633
+ "503": {
1634
+ "$ref": "#/components/responses/Unavailable"
1635
+ }
1636
+ }
1637
+ }
1638
+ },
1639
+ "/ads/creatives": {
1640
+ "get": {
1641
+ "operationId": "ads_list_creatives",
1642
+ "tags": [
1643
+ "Ads"
1644
+ ],
1645
+ "summary": "List creatives you can advertise",
1646
+ "description": "Needs the `ads:read` scope.",
1647
+ "parameters": [
1648
+ {
1649
+ "name": "kind",
1650
+ "in": "query",
1651
+ "required": false,
1652
+ "description": "Leave out for both. TikTok takes videos only.",
1653
+ "schema": {
1654
+ "type": "string",
1655
+ "enum": [
1656
+ "video",
1657
+ "image"
1658
+ ]
1659
+ }
1660
+ },
1661
+ {
1662
+ "name": "limit",
1663
+ "in": "query",
1664
+ "required": false,
1665
+ "description": "Default 40, newest first.",
1666
+ "schema": {
1667
+ "type": "integer",
1668
+ "minimum": 1,
1669
+ "maximum": 100
1670
+ }
1671
+ }
1672
+ ],
1673
+ "responses": {
1674
+ "200": {
1675
+ "description": "Videos and pictures you can put in an ad.",
1676
+ "content": {
1677
+ "application/json": {
1678
+ "schema": {
1679
+ "$ref": "#/components/schemas/ApiAdsCreativeList"
1680
+ }
1681
+ }
1682
+ }
1683
+ },
1684
+ "401": {
1685
+ "$ref": "#/components/responses/Unauthorized"
1686
+ },
1687
+ "403": {
1688
+ "$ref": "#/components/responses/Forbidden"
1689
+ },
1690
+ "404": {
1691
+ "$ref": "#/components/responses/NotFound"
1692
+ },
1693
+ "422": {
1694
+ "$ref": "#/components/responses/Unprocessable"
1695
+ },
1696
+ "429": {
1697
+ "$ref": "#/components/responses/RateLimited"
1698
+ },
1699
+ "500": {
1700
+ "$ref": "#/components/responses/InternalError"
1701
+ },
1702
+ "503": {
1703
+ "$ref": "#/components/responses/Unavailable"
1704
+ }
1705
+ }
1706
+ }
1707
+ },
1708
+ "/ads/campaigns": {
1709
+ "get": {
1710
+ "operationId": "ads_list_campaigns",
1711
+ "tags": [
1712
+ "Ads"
1713
+ ],
1714
+ "summary": "List campaigns with stats",
1715
+ "description": "Needs the `ads:read` scope.",
1716
+ "parameters": [
1717
+ {
1718
+ "name": "days",
1719
+ "in": "query",
1720
+ "required": false,
1721
+ "description": "How many days of stats, counting today. Default 7.",
1722
+ "schema": {
1723
+ "type": "integer",
1724
+ "minimum": 1,
1725
+ "maximum": 30
1726
+ }
1727
+ }
1728
+ ],
1729
+ "responses": {
1730
+ "200": {
1731
+ "description": "Campaigns with stats.",
1732
+ "content": {
1733
+ "application/json": {
1734
+ "schema": {
1735
+ "$ref": "#/components/schemas/ApiAdsCampaigns"
1736
+ }
1737
+ }
1738
+ }
1739
+ },
1740
+ "401": {
1741
+ "$ref": "#/components/responses/Unauthorized"
1742
+ },
1743
+ "403": {
1744
+ "$ref": "#/components/responses/Forbidden"
1745
+ },
1746
+ "404": {
1747
+ "$ref": "#/components/responses/NotFound"
1748
+ },
1749
+ "422": {
1750
+ "$ref": "#/components/responses/Unprocessable"
1751
+ },
1752
+ "429": {
1753
+ "$ref": "#/components/responses/RateLimited"
1754
+ },
1755
+ "500": {
1756
+ "$ref": "#/components/responses/InternalError"
1757
+ },
1758
+ "503": {
1759
+ "$ref": "#/components/responses/Unavailable"
1760
+ }
1761
+ }
1762
+ }
1763
+ },
1764
+ "/ads/launches": {
1765
+ "post": {
1766
+ "operationId": "ads_draft_launch",
1767
+ "tags": [
1768
+ "Ads"
1769
+ ],
1770
+ "summary": "Draft an ad launch",
1771
+ "description": "Makes a DRAFT only. Nothing launches or spends until a person opens review_url and presses Launch.\n\nNeeds the `ads:write` scope.",
1772
+ "requestBody": {
1773
+ "required": true,
1774
+ "content": {
1775
+ "application/json": {
1776
+ "schema": {
1777
+ "type": "object",
1778
+ "properties": {
1779
+ "ad_account_id": {
1780
+ "type": "string",
1781
+ "minLength": 1,
1782
+ "description": "An id from ads_list_accounts. Its platform (Meta or TikTok) and currency come with it."
1783
+ },
1784
+ "name": {
1785
+ "description": "The campaign's name. Leave out for \"<account> · <date>\".",
1786
+ "type": "string",
1787
+ "minLength": 1,
1788
+ "maxLength": 120
1789
+ },
1790
+ "goal": {
1791
+ "type": "string",
1792
+ "enum": [
1793
+ "traffic",
1794
+ "sales"
1795
+ ],
1796
+ "description": "\"traffic\" = visits to a site; \"sales\" = purchases, needs pixel_id."
1797
+ },
1798
+ "pixel_id": {
1799
+ "description": "Sales only: the Meta pixel / TikTok pixel code to count purchases with.",
1800
+ "type": "string",
1801
+ "minLength": 1
1802
+ },
1803
+ "daily_budget": {
1804
+ "type": "number",
1805
+ "exclusiveMinimum": 0,
1806
+ "description": "What the whole launch may spend a day, in the account's currency as people say it: 20 = $20 a day."
1807
+ },
1808
+ "start_at": {
1809
+ "description": "Leave out to start as soon as it's approved.",
1810
+ "type": "string",
1811
+ "format": "date-time",
1812
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
1813
+ },
1814
+ "end_at": {
1815
+ "description": "Leave out to run until paused.",
1816
+ "type": "string",
1817
+ "format": "date-time",
1818
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
1819
+ },
1820
+ "countries": {
1821
+ "minItems": 1,
1822
+ "maxItems": 25,
1823
+ "type": "array",
1824
+ "items": {
1825
+ "type": "string"
1826
+ },
1827
+ "description": "Two-letter country codes, like [\"US\", \"CA\"]."
1828
+ },
1829
+ "age_min": {
1830
+ "description": "Default 18.",
1831
+ "type": "integer",
1832
+ "minimum": 18,
1833
+ "maximum": 65
1834
+ },
1835
+ "age_max": {
1836
+ "description": "Default 65.",
1837
+ "type": "integer",
1838
+ "minimum": 18,
1839
+ "maximum": 65
1840
+ },
1841
+ "gender": {
1842
+ "description": "Default \"all\".",
1843
+ "type": "string",
1844
+ "enum": [
1845
+ "all",
1846
+ "female",
1847
+ "male"
1848
+ ]
1849
+ },
1850
+ "ads": {
1851
+ "minItems": 1,
1852
+ "maxItems": 10,
1853
+ "type": "array",
1854
+ "items": {
1855
+ "type": "object",
1856
+ "properties": {
1857
+ "creative_id": {
1858
+ "type": "string",
1859
+ "pattern": "^(asset|take|captionVideo):.+$",
1860
+ "description": "An id from ads_list_creatives."
1861
+ },
1862
+ "text": {
1863
+ "type": "string",
1864
+ "minLength": 1,
1865
+ "maxLength": 2200,
1866
+ "description": "The ad's words over the video. TikTok allows 100 characters, Meta far more (first ~125 show)."
1867
+ },
1868
+ "headline": {
1869
+ "description": "Meta only, optional: the bold line under the video.",
1870
+ "type": "string",
1871
+ "maxLength": 255
1872
+ },
1873
+ "cta": {
1874
+ "type": "string",
1875
+ "enum": [
1876
+ "learn_more",
1877
+ "shop_now",
1878
+ "sign_up",
1879
+ "download",
1880
+ "contact_us",
1881
+ "book_now"
1882
+ ],
1883
+ "description": "The button."
1884
+ },
1885
+ "url": {
1886
+ "type": "string",
1887
+ "minLength": 1,
1888
+ "description": "Where the button goes. Must start with https://."
1889
+ }
1890
+ },
1891
+ "required": [
1892
+ "creative_id",
1893
+ "text",
1894
+ "cta",
1895
+ "url"
1896
+ ]
1897
+ },
1898
+ "description": "One ad per video or picture, each with its own words."
1899
+ }
1900
+ },
1901
+ "required": [
1902
+ "ad_account_id",
1903
+ "goal",
1904
+ "daily_budget",
1905
+ "countries",
1906
+ "ads"
1907
+ ]
1908
+ }
1909
+ }
1910
+ }
1911
+ },
1912
+ "responses": {
1913
+ "201": {
1914
+ "description": "A DRAFT with a review_url.",
1915
+ "content": {
1916
+ "application/json": {
1917
+ "schema": {
1918
+ "$ref": "#/components/schemas/ApiAdsLaunch"
1919
+ }
1920
+ }
1921
+ }
1922
+ },
1923
+ "401": {
1924
+ "$ref": "#/components/responses/Unauthorized"
1925
+ },
1926
+ "403": {
1927
+ "$ref": "#/components/responses/Forbidden"
1928
+ },
1929
+ "404": {
1930
+ "$ref": "#/components/responses/NotFound"
1931
+ },
1932
+ "422": {
1933
+ "$ref": "#/components/responses/Unprocessable"
1934
+ },
1935
+ "429": {
1936
+ "$ref": "#/components/responses/RateLimited"
1937
+ },
1938
+ "500": {
1939
+ "$ref": "#/components/responses/InternalError"
1940
+ },
1941
+ "503": {
1942
+ "$ref": "#/components/responses/Unavailable"
1943
+ }
1944
+ }
1945
+ }
1946
+ },
1947
+ "/ads/launches/{id}": {
1948
+ "get": {
1949
+ "operationId": "ads_get_launch",
1950
+ "tags": [
1951
+ "Ads"
1952
+ ],
1953
+ "summary": "Get one ad launch",
1954
+ "description": "Needs the `ads:read` scope.",
1955
+ "parameters": [
1956
+ {
1957
+ "name": "id",
1958
+ "in": "path",
1959
+ "required": true,
1960
+ "description": "The job id from a make call.",
1961
+ "schema": {
1962
+ "type": "string"
1963
+ }
1964
+ }
1965
+ ],
1966
+ "responses": {
1967
+ "200": {
1968
+ "description": "The launch and where it stands.",
1969
+ "content": {
1970
+ "application/json": {
1971
+ "schema": {
1972
+ "$ref": "#/components/schemas/ApiAdsLaunch"
1973
+ }
1974
+ }
1975
+ }
1976
+ },
1977
+ "401": {
1978
+ "$ref": "#/components/responses/Unauthorized"
1979
+ },
1980
+ "403": {
1981
+ "$ref": "#/components/responses/Forbidden"
1982
+ },
1983
+ "404": {
1984
+ "$ref": "#/components/responses/NotFound"
1985
+ },
1986
+ "429": {
1987
+ "$ref": "#/components/responses/RateLimited"
1988
+ },
1989
+ "500": {
1990
+ "$ref": "#/components/responses/InternalError"
1991
+ },
1992
+ "503": {
1993
+ "$ref": "#/components/responses/Unavailable"
1994
+ }
1995
+ }
1996
+ }
1997
+ },
1998
+ "/me": {
1999
+ "get": {
2000
+ "operationId": "get_me",
2001
+ "tags": [
2002
+ "Account"
2003
+ ],
2004
+ "summary": "Who am I",
2005
+ "description": "Any working key may call it. `diffusr whoami` on the command line.",
2006
+ "responses": {
2007
+ "200": {
2008
+ "description": "Who you are, the key this call used and what you have left to spend.",
2009
+ "content": {
2010
+ "application/json": {
2011
+ "schema": {
2012
+ "$ref": "#/components/schemas/ApiMe"
2013
+ }
2014
+ }
2015
+ }
2016
+ },
2017
+ "401": {
2018
+ "$ref": "#/components/responses/Unauthorized"
2019
+ },
2020
+ "403": {
2021
+ "$ref": "#/components/responses/Forbidden"
2022
+ },
2023
+ "429": {
2024
+ "$ref": "#/components/responses/RateLimited"
2025
+ },
2026
+ "500": {
2027
+ "$ref": "#/components/responses/InternalError"
2028
+ },
2029
+ "503": {
2030
+ "$ref": "#/components/responses/Unavailable"
2031
+ }
2032
+ }
2033
+ }
2034
+ },
2035
+ "/cli/logins": {
2036
+ "post": {
2037
+ "operationId": "start_cli_login",
2038
+ "tags": [
2039
+ "Login"
2040
+ ],
2041
+ "summary": "Start a browser login for a command line or agent",
2042
+ "description": "How `npx diffusr login` gets a key without anyone copying one. Show `code` and `verify_url`; the person opens the link signed in, checks the code matches and presses Yes, connect. Then poll_cli_login hands over a new key once. The login expires after 10 minutes.",
2043
+ "security": [],
2044
+ "requestBody": {
2045
+ "required": true,
2046
+ "content": {
2047
+ "application/json": {
2048
+ "schema": {
2049
+ "type": "object",
2050
+ "properties": {
2051
+ "device_name": {
2052
+ "description": "What to call this computer, e.g. its hostname. The key is named \"CLI on <device_name>\".",
2053
+ "type": "string"
2054
+ },
2055
+ "mode": {
2056
+ "description": "The key the browser page offers first: live (default) or test (free, fake results).",
2057
+ "type": "string",
2058
+ "enum": [
2059
+ "live",
2060
+ "test"
2061
+ ]
2062
+ }
2063
+ }
2064
+ }
2065
+ }
2066
+ }
2067
+ },
2068
+ "responses": {
2069
+ "201": {
2070
+ "description": "A code to show, a link to open, and a secret to poll with.",
2071
+ "content": {
2072
+ "application/json": {
2073
+ "schema": {
2074
+ "$ref": "#/components/schemas/ApiCliLogin"
2075
+ }
2076
+ }
2077
+ }
2078
+ },
2079
+ "422": {
2080
+ "$ref": "#/components/responses/Unprocessable"
2081
+ },
2082
+ "429": {
2083
+ "$ref": "#/components/responses/RateLimited"
2084
+ },
2085
+ "500": {
2086
+ "$ref": "#/components/responses/InternalError"
2087
+ },
2088
+ "503": {
2089
+ "$ref": "#/components/responses/Unavailable"
2090
+ }
2091
+ }
2092
+ }
2093
+ },
2094
+ "/cli/logins/{login_id}/token": {
2095
+ "post": {
2096
+ "operationId": "poll_cli_login",
2097
+ "tags": [
2098
+ "Login"
2099
+ ],
2100
+ "summary": "Check a browser login and collect the key",
2101
+ "description": "Call every `interval` seconds with the `poll_token`. `pending`: keep waiting. `approved`: save `key` (it is never sent again). `denied`, `expired` or `failed`: stop and start over.",
2102
+ "security": [],
2103
+ "parameters": [
2104
+ {
2105
+ "name": "login_id",
2106
+ "in": "path",
2107
+ "required": true,
2108
+ "description": "",
2109
+ "schema": {
2110
+ "type": "string"
2111
+ }
2112
+ }
2113
+ ],
2114
+ "requestBody": {
2115
+ "required": true,
2116
+ "content": {
2117
+ "application/json": {
2118
+ "schema": {
2119
+ "type": "object",
2120
+ "properties": {
2121
+ "poll_token": {
2122
+ "type": "string",
2123
+ "minLength": 16,
2124
+ "maxLength": 200
2125
+ }
2126
+ },
2127
+ "required": [
2128
+ "poll_token"
2129
+ ]
2130
+ }
2131
+ }
2132
+ }
2133
+ },
2134
+ "responses": {
2135
+ "200": {
2136
+ "description": "`status` says where the login stands; `approved` carries the key, sent this once.",
2137
+ "content": {
2138
+ "application/json": {
2139
+ "schema": {
2140
+ "$ref": "#/components/schemas/ApiCliLoginPoll"
2141
+ }
2142
+ }
2143
+ }
2144
+ },
2145
+ "404": {
2146
+ "$ref": "#/components/responses/NotFound"
2147
+ },
2148
+ "422": {
2149
+ "$ref": "#/components/responses/Unprocessable"
2150
+ },
2151
+ "429": {
2152
+ "$ref": "#/components/responses/RateLimited"
2153
+ },
2154
+ "500": {
2155
+ "$ref": "#/components/responses/InternalError"
2156
+ },
2157
+ "503": {
2158
+ "$ref": "#/components/responses/Unavailable"
2159
+ }
2160
+ }
2161
+ }
2162
+ },
2163
+ "/cli/logout": {
2164
+ "post": {
2165
+ "operationId": "cli_logout",
2166
+ "tags": [
2167
+ "Login"
2168
+ ],
2169
+ "summary": "Revoke the key this call uses",
2170
+ "description": "What `diffusr logout` calls. Anything else using the same key stops working at once.",
2171
+ "responses": {
2172
+ "200": {
2173
+ "description": "The key that made this call is revoked.",
2174
+ "content": {
2175
+ "application/json": {
2176
+ "schema": {
2177
+ "$ref": "#/components/schemas/ApiCliLogout"
2178
+ }
2179
+ }
2180
+ }
2181
+ },
2182
+ "401": {
2183
+ "$ref": "#/components/responses/Unauthorized"
2184
+ },
2185
+ "403": {
2186
+ "$ref": "#/components/responses/Forbidden"
2187
+ },
2188
+ "422": {
2189
+ "$ref": "#/components/responses/Unprocessable"
2190
+ },
2191
+ "429": {
2192
+ "$ref": "#/components/responses/RateLimited"
2193
+ },
2194
+ "500": {
2195
+ "$ref": "#/components/responses/InternalError"
2196
+ },
2197
+ "503": {
2198
+ "$ref": "#/components/responses/Unavailable"
2199
+ }
2200
+ }
2201
+ }
2202
+ }
2203
+ },
2204
+ "webhooks": {
2205
+ "result.finished": {
2206
+ "post": {
2207
+ "operationId": "callback_result_finished",
2208
+ "summary": "A job you started with callback_url has finished",
2209
+ "description": "We POST this once when the job is done, failed or canceled. Signed with Standard Webhooks (https://www.standardwebhooks.com): check `webhook-signature` (`v1,<base64 HMAC-SHA256 of \"{webhook-id}.{webhook-timestamp}.{raw body}\">`, key = the base64 part of your `whsec_…` secret from GET /callbacks/secret) and reject a `webhook-timestamp` more than 5 minutes old. Answer any 2xx. Other answers are retried; `webhook-id` stays the same across retries, so use it to ignore repeats. During a secret rotation the header carries two signatures; accept either.",
2210
+ "parameters": [
2211
+ {
2212
+ "name": "webhook-id",
2213
+ "in": "header",
2214
+ "required": true,
2215
+ "schema": {
2216
+ "type": "string"
2217
+ },
2218
+ "description": "The event id (\"evt_…\")."
2219
+ },
2220
+ {
2221
+ "name": "webhook-timestamp",
2222
+ "in": "header",
2223
+ "required": true,
2224
+ "schema": {
2225
+ "type": "string"
2226
+ },
2227
+ "description": "Unix seconds when this attempt was signed."
2228
+ },
2229
+ {
2230
+ "name": "webhook-signature",
2231
+ "in": "header",
2232
+ "required": true,
2233
+ "schema": {
2234
+ "type": "string"
2235
+ },
2236
+ "description": "Space-separated signatures, each `v1,<base64>`."
2237
+ }
2238
+ ],
2239
+ "requestBody": {
2240
+ "required": true,
2241
+ "content": {
2242
+ "application/json": {
2243
+ "schema": {
2244
+ "$ref": "#/components/schemas/ApiCallbackEvent"
2245
+ }
2246
+ }
2247
+ }
2248
+ },
2249
+ "responses": {
2250
+ "2XX": {
2251
+ "description": "Received."
2252
+ }
2253
+ }
2254
+ }
2255
+ }
2256
+ },
2257
+ "components": {
2258
+ "securitySchemes": {
2259
+ "bearerAuth": {
2260
+ "type": "http",
2261
+ "scheme": "bearer",
2262
+ "description": "Your API key: `dfsr_live_…` for real runs, `dfsr_test_…` for free fake runs that return real prices."
2263
+ }
2264
+ },
2265
+ "headers": {
2266
+ "RequestId": {
2267
+ "description": "Id of this request. Send your own `X-Request-Id` to choose it.",
2268
+ "schema": {
2269
+ "type": "string"
2270
+ }
2271
+ },
2272
+ "RetryAfter": {
2273
+ "description": "Seconds to wait before trying again.",
2274
+ "schema": {
2275
+ "type": "integer"
2276
+ }
2277
+ }
2278
+ },
2279
+ "schemas": {
2280
+ "Error": {
2281
+ "type": "object",
2282
+ "properties": {
2283
+ "error": {
2284
+ "type": "string",
2285
+ "description": "What went wrong, in plain words."
2286
+ },
2287
+ "code": {
2288
+ "type": "string",
2289
+ "description": "A stable machine code; see API_ERROR_CODES."
2290
+ },
2291
+ "request_id": {
2292
+ "type": "string",
2293
+ "description": "Quote this to support. Also in the X-Request-Id header."
2294
+ },
2295
+ "issues": {
2296
+ "description": "VALIDATION_FAILED and PREFLIGHT_FAILED: each problem.",
2297
+ "type": "array",
2298
+ "items": {
2299
+ "type": "object",
2300
+ "properties": {
2301
+ "path": {
2302
+ "type": "string"
2303
+ },
2304
+ "code": {
2305
+ "type": "string"
2306
+ },
2307
+ "message": {
2308
+ "type": "string"
2309
+ }
2310
+ },
2311
+ "required": [
2312
+ "message"
2313
+ ],
2314
+ "additionalProperties": {}
2315
+ }
2316
+ }
2317
+ },
2318
+ "required": [
2319
+ "error",
2320
+ "code",
2321
+ "request_id"
2322
+ ],
2323
+ "additionalProperties": {},
2324
+ "description": "Every error. `code` is stable and machine-readable; a client must accept a code it does not know. Quote `request_id` to support."
2325
+ },
2326
+ "ApiPrice": {
2327
+ "type": "object",
2328
+ "properties": {
2329
+ "credits": {
2330
+ "type": "number",
2331
+ "description": "The most this call costs, in whole credits (1 credit = $0.01)."
2332
+ },
2333
+ "usd": {
2334
+ "type": "string",
2335
+ "description": "The same price in US dollars, e.g. \"0.0336\"."
2336
+ },
2337
+ "tariff": {
2338
+ "type": "string",
2339
+ "enum": [
2340
+ "direct",
2341
+ "outcome"
2342
+ ],
2343
+ "description": "\"direct\" = your prompt goes to the model as sent; \"outcome\" = a result we shape (Recast, creator video)."
2344
+ },
2345
+ "tariff_version": {
2346
+ "type": "string"
2347
+ },
2348
+ "expires_at": {
2349
+ "type": "string",
2350
+ "description": "The quoted price holds until then (ISO time)."
2351
+ }
2352
+ },
2353
+ "required": [
2354
+ "credits",
2355
+ "usd",
2356
+ "tariff",
2357
+ "tariff_version",
2358
+ "expires_at"
2359
+ ],
2360
+ "additionalProperties": false
2361
+ },
2362
+ "ApiCallbackEvent": {
2363
+ "type": "object",
2364
+ "properties": {
2365
+ "id": {
2366
+ "type": "string",
2367
+ "description": "Unique per event (\"evt_…\"). Also the webhook-id header. Retries of one event keep it, so use it to ignore repeats."
2368
+ },
2369
+ "type": {
2370
+ "type": "string",
2371
+ "enum": [
2372
+ "result.finished"
2373
+ ]
2374
+ },
2375
+ "created_at": {
2376
+ "type": "string",
2377
+ "description": "When the event was made (ISO time)."
2378
+ },
2379
+ "data": {
2380
+ "type": "object",
2381
+ "properties": {
2382
+ "id": {
2383
+ "type": "string"
2384
+ },
2385
+ "status": {
2386
+ "type": "string",
2387
+ "enum": [
2388
+ "PENDING",
2389
+ "RUNNING",
2390
+ "SUCCEEDED",
2391
+ "FAILED",
2392
+ "CANCELED"
2393
+ ]
2394
+ }
2395
+ },
2396
+ "required": [
2397
+ "id",
2398
+ "status"
2399
+ ],
2400
+ "additionalProperties": {},
2401
+ "description": "The finished result, exactly as get_result returns it."
2402
+ }
2403
+ },
2404
+ "required": [
2405
+ "id",
2406
+ "type",
2407
+ "created_at",
2408
+ "data"
2409
+ ],
2410
+ "additionalProperties": false
2411
+ },
2412
+ "ApiStarted": {
2413
+ "type": "object",
2414
+ "properties": {
2415
+ "id": {
2416
+ "type": "string",
2417
+ "description": "The job id. Poll GET /results/{id} with it, or wait for the callback."
2418
+ },
2419
+ "status": {
2420
+ "type": "string",
2421
+ "description": "\"PENDING\" on a new start; the run's current status when a retried Idempotency-Key replays the first job."
2422
+ },
2423
+ "credits_estimated": {
2424
+ "type": "number",
2425
+ "description": "The most this job can cost, in credits."
2426
+ },
2427
+ "idempotent_replay": {
2428
+ "description": "true when this is the FIRST job again, answering a retried Idempotency-Key.",
2429
+ "type": "boolean",
2430
+ "const": true
2431
+ },
2432
+ "test": {
2433
+ "description": "true when a test key made the call: the price is real, nothing real ran. Absent for live keys.",
2434
+ "type": "boolean",
2435
+ "const": true
2436
+ },
2437
+ "price": {
2438
+ "description": "The price, locked in at start.",
2439
+ "type": "object",
2440
+ "properties": {
2441
+ "credits": {
2442
+ "type": "number",
2443
+ "description": "The most this call costs, in whole credits (1 credit = $0.01)."
2444
+ },
2445
+ "usd": {
2446
+ "type": "string",
2447
+ "description": "The same price in US dollars, e.g. \"0.0336\"."
2448
+ },
2449
+ "tariff": {
2450
+ "type": "string",
2451
+ "enum": [
2452
+ "direct",
2453
+ "outcome"
2454
+ ],
2455
+ "description": "\"direct\" = your prompt goes to the model as sent; \"outcome\" = a result we shape (Recast, creator video)."
2456
+ },
2457
+ "tariff_version": {
2458
+ "type": "string"
2459
+ },
2460
+ "expires_at": {
2461
+ "type": "string",
2462
+ "description": "The quoted price holds until then (ISO time)."
2463
+ }
2464
+ },
2465
+ "required": [
2466
+ "credits",
2467
+ "usd",
2468
+ "tariff",
2469
+ "tariff_version",
2470
+ "expires_at"
2471
+ ],
2472
+ "additionalProperties": false
2473
+ },
2474
+ "duration_sec": {
2475
+ "type": "number"
2476
+ },
2477
+ "warnings": {
2478
+ "description": "Heads-ups that did not stop the call.",
2479
+ "type": "array",
2480
+ "items": {
2481
+ "type": "string"
2482
+ }
2483
+ },
2484
+ "next": {
2485
+ "type": "string",
2486
+ "description": "What to do next, in words."
2487
+ }
2488
+ },
2489
+ "required": [
2490
+ "id",
2491
+ "status",
2492
+ "credits_estimated",
2493
+ "next"
2494
+ ],
2495
+ "additionalProperties": false
2496
+ },
2497
+ "ApiDryRun": {
2498
+ "type": "object",
2499
+ "properties": {
2500
+ "dry_run": {
2501
+ "type": "boolean",
2502
+ "const": true
2503
+ },
2504
+ "test": {
2505
+ "description": "true when a test key made the call: the price is real, nothing real ran. Absent for live keys.",
2506
+ "type": "boolean",
2507
+ "const": true
2508
+ },
2509
+ "credits_estimated": {
2510
+ "type": "number"
2511
+ },
2512
+ "price": {
2513
+ "type": "object",
2514
+ "properties": {
2515
+ "credits": {
2516
+ "type": "number",
2517
+ "description": "The most this call costs, in whole credits (1 credit = $0.01)."
2518
+ },
2519
+ "usd": {
2520
+ "type": "string",
2521
+ "description": "The same price in US dollars, e.g. \"0.0336\"."
2522
+ },
2523
+ "tariff": {
2524
+ "type": "string",
2525
+ "enum": [
2526
+ "direct",
2527
+ "outcome"
2528
+ ],
2529
+ "description": "\"direct\" = your prompt goes to the model as sent; \"outcome\" = a result we shape (Recast, creator video)."
2530
+ },
2531
+ "tariff_version": {
2532
+ "type": "string"
2533
+ },
2534
+ "expires_at": {
2535
+ "type": "string",
2536
+ "description": "The quoted price holds until then (ISO time)."
2537
+ }
2538
+ },
2539
+ "required": [
2540
+ "credits",
2541
+ "usd",
2542
+ "tariff",
2543
+ "tariff_version",
2544
+ "expires_at"
2545
+ ],
2546
+ "additionalProperties": false
2547
+ },
2548
+ "duration_sec": {
2549
+ "type": "number"
2550
+ },
2551
+ "warnings": {
2552
+ "type": "array",
2553
+ "items": {
2554
+ "type": "string"
2555
+ }
2556
+ },
2557
+ "note": {
2558
+ "type": "string"
2559
+ }
2560
+ },
2561
+ "required": [
2562
+ "dry_run",
2563
+ "credits_estimated",
2564
+ "note"
2565
+ ],
2566
+ "additionalProperties": false
2567
+ },
2568
+ "ApiUpload": {
2569
+ "anyOf": [
2570
+ {
2571
+ "type": "object",
2572
+ "properties": {
2573
+ "file_url": {
2574
+ "type": "string",
2575
+ "description": "Pass this to a tool (image_urls / video_url / audio_urls)."
2576
+ },
2577
+ "kind": {
2578
+ "type": "string"
2579
+ },
2580
+ "next": {
2581
+ "type": "string"
2582
+ }
2583
+ },
2584
+ "required": [
2585
+ "file_url",
2586
+ "kind",
2587
+ "next"
2588
+ ],
2589
+ "additionalProperties": false
2590
+ },
2591
+ {
2592
+ "type": "object",
2593
+ "properties": {
2594
+ "upload_url": {
2595
+ "type": "string",
2596
+ "description": "PUT the file's bytes here."
2597
+ },
2598
+ "method": {
2599
+ "type": "string",
2600
+ "const": "PUT"
2601
+ },
2602
+ "headers": {
2603
+ "type": "object",
2604
+ "properties": {
2605
+ "Content-Type": {
2606
+ "type": "string"
2607
+ }
2608
+ },
2609
+ "required": [
2610
+ "Content-Type"
2611
+ ],
2612
+ "additionalProperties": false,
2613
+ "description": "Send these headers with the PUT."
2614
+ },
2615
+ "file_url": {
2616
+ "type": "string",
2617
+ "description": "Works only after the PUT succeeds."
2618
+ },
2619
+ "kind": {
2620
+ "type": "string"
2621
+ },
2622
+ "expires_in_sec": {
2623
+ "type": "number"
2624
+ },
2625
+ "curl": {
2626
+ "type": "string",
2627
+ "description": "The same PUT as a ready curl line."
2628
+ },
2629
+ "next": {
2630
+ "type": "string"
2631
+ }
2632
+ },
2633
+ "required": [
2634
+ "upload_url",
2635
+ "method",
2636
+ "headers",
2637
+ "file_url",
2638
+ "kind",
2639
+ "expires_in_sec",
2640
+ "curl",
2641
+ "next"
2642
+ ],
2643
+ "additionalProperties": false
2644
+ }
2645
+ ]
2646
+ },
2647
+ "ApiResultList": {
2648
+ "type": "object",
2649
+ "properties": {
2650
+ "results": {
2651
+ "type": "array",
2652
+ "items": {
2653
+ "type": "object",
2654
+ "properties": {
2655
+ "id": {
2656
+ "type": "string"
2657
+ },
2658
+ "status": {
2659
+ "type": "string",
2660
+ "enum": [
2661
+ "PENDING",
2662
+ "RUNNING",
2663
+ "SUCCEEDED",
2664
+ "FAILED",
2665
+ "CANCELED"
2666
+ ],
2667
+ "description": "PENDING and RUNNING = keep waiting. SUCCEEDED, FAILED and CANCELED are final."
2668
+ },
2669
+ "model": {
2670
+ "type": "string"
2671
+ },
2672
+ "credits_estimated": {
2673
+ "type": "number"
2674
+ },
2675
+ "created_at": {
2676
+ "type": "string"
2677
+ },
2678
+ "finished_at": {
2679
+ "type": "string"
2680
+ },
2681
+ "output": {
2682
+ "description": "Present once SUCCEEDED.",
2683
+ "type": "object",
2684
+ "properties": {
2685
+ "kind": {
2686
+ "type": "string",
2687
+ "enum": [
2688
+ "IMAGE",
2689
+ "VIDEO",
2690
+ "AUDIO"
2691
+ ]
2692
+ },
2693
+ "url": {
2694
+ "type": "string",
2695
+ "description": "Public link to the file."
2696
+ },
2697
+ "thumbnail_url": {
2698
+ "type": "string"
2699
+ },
2700
+ "width": {
2701
+ "type": "number"
2702
+ },
2703
+ "height": {
2704
+ "type": "number"
2705
+ },
2706
+ "duration_sec": {
2707
+ "type": "number"
2708
+ }
2709
+ },
2710
+ "required": [
2711
+ "kind",
2712
+ "url"
2713
+ ],
2714
+ "additionalProperties": false
2715
+ },
2716
+ "error": {
2717
+ "description": "Present when FAILED.",
2718
+ "type": "object",
2719
+ "properties": {
2720
+ "code": {
2721
+ "type": "string"
2722
+ },
2723
+ "message": {
2724
+ "type": "string"
2725
+ }
2726
+ },
2727
+ "required": [
2728
+ "code",
2729
+ "message"
2730
+ ],
2731
+ "additionalProperties": false
2732
+ },
2733
+ "request_id": {
2734
+ "description": "The X-Request-Id of the request that started the job.",
2735
+ "type": "string"
2736
+ },
2737
+ "test": {
2738
+ "description": "true when a test key made the call: the price is real, nothing real ran. Absent for live keys.",
2739
+ "type": "boolean",
2740
+ "const": true
2741
+ },
2742
+ "charge": {
2743
+ "type": "object",
2744
+ "properties": {
2745
+ "quoted_credits": {
2746
+ "anyOf": [
2747
+ {
2748
+ "type": "number"
2749
+ },
2750
+ {
2751
+ "type": "null"
2752
+ }
2753
+ ],
2754
+ "description": "The most the call could charge (null for a run with no API quote)."
2755
+ },
2756
+ "charged_credits": {
2757
+ "type": "number",
2758
+ "description": "What the call has charged so far. Work that was never delivered is not counted. A test run is always 0."
2759
+ },
2760
+ "final": {
2761
+ "type": "boolean",
2762
+ "description": "true once the run is over: the number can no longer change."
2763
+ }
2764
+ },
2765
+ "required": [
2766
+ "quoted_credits",
2767
+ "charged_credits",
2768
+ "final"
2769
+ ],
2770
+ "additionalProperties": false
2771
+ },
2772
+ "price": {
2773
+ "type": "object",
2774
+ "properties": {
2775
+ "credits": {
2776
+ "type": "number",
2777
+ "description": "The most this call costs, in whole credits (1 credit = $0.01)."
2778
+ },
2779
+ "usd": {
2780
+ "type": "string",
2781
+ "description": "The same price in US dollars, e.g. \"0.0336\"."
2782
+ },
2783
+ "tariff": {
2784
+ "type": "string",
2785
+ "enum": [
2786
+ "direct",
2787
+ "outcome"
2788
+ ],
2789
+ "description": "\"direct\" = your prompt goes to the model as sent; \"outcome\" = a result we shape (Recast, creator video)."
2790
+ },
2791
+ "tariff_version": {
2792
+ "type": "string"
2793
+ },
2794
+ "expires_at": {
2795
+ "type": "string",
2796
+ "description": "The quoted price holds until then (ISO time)."
2797
+ }
2798
+ },
2799
+ "required": [
2800
+ "credits",
2801
+ "usd",
2802
+ "tariff",
2803
+ "tariff_version",
2804
+ "expires_at"
2805
+ ],
2806
+ "additionalProperties": false
2807
+ },
2808
+ "next": {
2809
+ "description": "Present while the job is not finished.",
2810
+ "type": "string"
2811
+ }
2812
+ },
2813
+ "required": [
2814
+ "id",
2815
+ "status",
2816
+ "model",
2817
+ "created_at",
2818
+ "charge"
2819
+ ],
2820
+ "additionalProperties": false
2821
+ },
2822
+ "description": "Newest first."
2823
+ }
2824
+ },
2825
+ "required": [
2826
+ "results"
2827
+ ],
2828
+ "additionalProperties": false
2829
+ },
2830
+ "ApiResult": {
2831
+ "type": "object",
2832
+ "properties": {
2833
+ "id": {
2834
+ "type": "string"
2835
+ },
2836
+ "status": {
2837
+ "type": "string",
2838
+ "enum": [
2839
+ "PENDING",
2840
+ "RUNNING",
2841
+ "SUCCEEDED",
2842
+ "FAILED",
2843
+ "CANCELED"
2844
+ ],
2845
+ "description": "PENDING and RUNNING = keep waiting. SUCCEEDED, FAILED and CANCELED are final."
2846
+ },
2847
+ "model": {
2848
+ "type": "string"
2849
+ },
2850
+ "credits_estimated": {
2851
+ "type": "number"
2852
+ },
2853
+ "created_at": {
2854
+ "type": "string"
2855
+ },
2856
+ "finished_at": {
2857
+ "type": "string"
2858
+ },
2859
+ "output": {
2860
+ "description": "Present once SUCCEEDED.",
2861
+ "type": "object",
2862
+ "properties": {
2863
+ "kind": {
2864
+ "type": "string",
2865
+ "enum": [
2866
+ "IMAGE",
2867
+ "VIDEO",
2868
+ "AUDIO"
2869
+ ]
2870
+ },
2871
+ "url": {
2872
+ "type": "string",
2873
+ "description": "Public link to the file."
2874
+ },
2875
+ "thumbnail_url": {
2876
+ "type": "string"
2877
+ },
2878
+ "width": {
2879
+ "type": "number"
2880
+ },
2881
+ "height": {
2882
+ "type": "number"
2883
+ },
2884
+ "duration_sec": {
2885
+ "type": "number"
2886
+ }
2887
+ },
2888
+ "required": [
2889
+ "kind",
2890
+ "url"
2891
+ ],
2892
+ "additionalProperties": false
2893
+ },
2894
+ "error": {
2895
+ "description": "Present when FAILED.",
2896
+ "type": "object",
2897
+ "properties": {
2898
+ "code": {
2899
+ "type": "string"
2900
+ },
2901
+ "message": {
2902
+ "type": "string"
2903
+ }
2904
+ },
2905
+ "required": [
2906
+ "code",
2907
+ "message"
2908
+ ],
2909
+ "additionalProperties": false
2910
+ },
2911
+ "request_id": {
2912
+ "description": "The X-Request-Id of the request that started the job.",
2913
+ "type": "string"
2914
+ },
2915
+ "test": {
2916
+ "description": "true when a test key made the call: the price is real, nothing real ran. Absent for live keys.",
2917
+ "type": "boolean",
2918
+ "const": true
2919
+ },
2920
+ "charge": {
2921
+ "type": "object",
2922
+ "properties": {
2923
+ "quoted_credits": {
2924
+ "anyOf": [
2925
+ {
2926
+ "type": "number"
2927
+ },
2928
+ {
2929
+ "type": "null"
2930
+ }
2931
+ ],
2932
+ "description": "The most the call could charge (null for a run with no API quote)."
2933
+ },
2934
+ "charged_credits": {
2935
+ "type": "number",
2936
+ "description": "What the call has charged so far. Work that was never delivered is not counted. A test run is always 0."
2937
+ },
2938
+ "final": {
2939
+ "type": "boolean",
2940
+ "description": "true once the run is over: the number can no longer change."
2941
+ }
2942
+ },
2943
+ "required": [
2944
+ "quoted_credits",
2945
+ "charged_credits",
2946
+ "final"
2947
+ ],
2948
+ "additionalProperties": false
2949
+ },
2950
+ "price": {
2951
+ "type": "object",
2952
+ "properties": {
2953
+ "credits": {
2954
+ "type": "number",
2955
+ "description": "The most this call costs, in whole credits (1 credit = $0.01)."
2956
+ },
2957
+ "usd": {
2958
+ "type": "string",
2959
+ "description": "The same price in US dollars, e.g. \"0.0336\"."
2960
+ },
2961
+ "tariff": {
2962
+ "type": "string",
2963
+ "enum": [
2964
+ "direct",
2965
+ "outcome"
2966
+ ],
2967
+ "description": "\"direct\" = your prompt goes to the model as sent; \"outcome\" = a result we shape (Recast, creator video)."
2968
+ },
2969
+ "tariff_version": {
2970
+ "type": "string"
2971
+ },
2972
+ "expires_at": {
2973
+ "type": "string",
2974
+ "description": "The quoted price holds until then (ISO time)."
2975
+ }
2976
+ },
2977
+ "required": [
2978
+ "credits",
2979
+ "usd",
2980
+ "tariff",
2981
+ "tariff_version",
2982
+ "expires_at"
2983
+ ],
2984
+ "additionalProperties": false
2985
+ },
2986
+ "next": {
2987
+ "description": "Present while the job is not finished.",
2988
+ "type": "string"
2989
+ }
2990
+ },
2991
+ "required": [
2992
+ "id",
2993
+ "status",
2994
+ "model",
2995
+ "created_at",
2996
+ "charge"
2997
+ ],
2998
+ "additionalProperties": false
2999
+ },
3000
+ "ApiModelList": {
3001
+ "type": "object",
3002
+ "properties": {
3003
+ "models": {
3004
+ "type": "array",
3005
+ "items": {
3006
+ "type": "object",
3007
+ "properties": {
3008
+ "id": {
3009
+ "type": "string",
3010
+ "description": "Pass this as `model`."
3011
+ },
3012
+ "name": {
3013
+ "type": "string"
3014
+ },
3015
+ "kind": {
3016
+ "type": "string",
3017
+ "enum": [
3018
+ "video",
3019
+ "image"
3020
+ ]
3021
+ },
3022
+ "aspect_ratios": {
3023
+ "type": "array",
3024
+ "items": {
3025
+ "type": "string"
3026
+ }
3027
+ },
3028
+ "resolutions": {
3029
+ "type": "array",
3030
+ "items": {
3031
+ "type": "string"
3032
+ }
3033
+ },
3034
+ "duration_sec": {
3035
+ "type": "object",
3036
+ "properties": {
3037
+ "min": {
3038
+ "type": "number"
3039
+ },
3040
+ "max": {
3041
+ "type": "number"
3042
+ },
3043
+ "default": {
3044
+ "type": "number"
3045
+ }
3046
+ },
3047
+ "required": [
3048
+ "min",
3049
+ "max",
3050
+ "default"
3051
+ ],
3052
+ "additionalProperties": false
3053
+ },
3054
+ "max_reference_images": {
3055
+ "type": "number"
3056
+ },
3057
+ "takes_video": {
3058
+ "type": "boolean"
3059
+ },
3060
+ "takes_audio": {
3061
+ "type": "boolean",
3062
+ "description": "Takes voice or sound clips in audio_urls."
3063
+ },
3064
+ "reference_labels": {
3065
+ "type": "object",
3066
+ "properties": {
3067
+ "image": {
3068
+ "type": "string"
3069
+ },
3070
+ "video": {
3071
+ "type": "string"
3072
+ },
3073
+ "audio": {
3074
+ "type": "string"
3075
+ }
3076
+ },
3077
+ "additionalProperties": false
3078
+ },
3079
+ "cost": {
3080
+ "anyOf": [
3081
+ {
3082
+ "type": "object",
3083
+ "properties": {
3084
+ "kind": {
3085
+ "type": "string",
3086
+ "const": "perImage"
3087
+ },
3088
+ "creditsPerImage": {
3089
+ "type": "number"
3090
+ },
3091
+ "approximate": {
3092
+ "type": "boolean"
3093
+ }
3094
+ },
3095
+ "required": [
3096
+ "kind",
3097
+ "creditsPerImage"
3098
+ ],
3099
+ "additionalProperties": false
3100
+ },
3101
+ {
3102
+ "type": "object",
3103
+ "properties": {
3104
+ "kind": {
3105
+ "type": "string",
3106
+ "const": "perSecond"
3107
+ },
3108
+ "creditsPerSecond": {
3109
+ "type": "number"
3110
+ },
3111
+ "approximate": {
3112
+ "type": "boolean"
3113
+ }
3114
+ },
3115
+ "required": [
3116
+ "kind",
3117
+ "creditsPerSecond"
3118
+ ],
3119
+ "additionalProperties": false
3120
+ },
3121
+ {
3122
+ "type": "object",
3123
+ "properties": {
3124
+ "kind": {
3125
+ "type": "string",
3126
+ "const": "perCall"
3127
+ },
3128
+ "creditsPerCall": {
3129
+ "type": "number"
3130
+ },
3131
+ "approximate": {
3132
+ "type": "boolean"
3133
+ }
3134
+ },
3135
+ "required": [
3136
+ "kind",
3137
+ "creditsPerCall"
3138
+ ],
3139
+ "additionalProperties": false
3140
+ },
3141
+ {
3142
+ "type": "object",
3143
+ "properties": {
3144
+ "kind": {
3145
+ "type": "string",
3146
+ "const": "perCharacter"
3147
+ },
3148
+ "creditsPer100Chars": {
3149
+ "type": "number"
3150
+ },
3151
+ "approximate": {
3152
+ "type": "boolean"
3153
+ }
3154
+ },
3155
+ "required": [
3156
+ "kind",
3157
+ "creditsPer100Chars"
3158
+ ],
3159
+ "additionalProperties": false
3160
+ }
3161
+ ],
3162
+ "description": "The price as a simple number, at the API direct tariff."
3163
+ },
3164
+ "price": {
3165
+ "type": "object",
3166
+ "properties": {
3167
+ "unit": {
3168
+ "type": "string",
3169
+ "enum": [
3170
+ "second",
3171
+ "image"
3172
+ ]
3173
+ },
3174
+ "credits": {
3175
+ "type": "number",
3176
+ "description": "Credits per second of video, or per image, at the settings in `at`."
3177
+ },
3178
+ "at": {
3179
+ "type": "object",
3180
+ "properties": {
3181
+ "aspect_ratio": {
3182
+ "type": "string"
3183
+ },
3184
+ "resolution": {
3185
+ "type": "string"
3186
+ },
3187
+ "duration_sec": {
3188
+ "type": "number"
3189
+ }
3190
+ },
3191
+ "required": [
3192
+ "aspect_ratio"
3193
+ ],
3194
+ "additionalProperties": false
3195
+ },
3196
+ "by_resolution": {
3197
+ "description": "The same price at each resolution, when the model has several.",
3198
+ "type": "object",
3199
+ "propertyNames": {
3200
+ "type": "string"
3201
+ },
3202
+ "additionalProperties": {
3203
+ "type": "number"
3204
+ }
3205
+ },
3206
+ "tariff": {
3207
+ "type": "string",
3208
+ "const": "direct"
3209
+ },
3210
+ "tariff_version": {
3211
+ "type": "string"
3212
+ }
3213
+ },
3214
+ "required": [
3215
+ "unit",
3216
+ "credits",
3217
+ "at",
3218
+ "tariff",
3219
+ "tariff_version"
3220
+ ],
3221
+ "additionalProperties": false
3222
+ },
3223
+ "about": {
3224
+ "type": "string"
3225
+ },
3226
+ "caveat": {
3227
+ "type": "string"
3228
+ }
3229
+ },
3230
+ "required": [
3231
+ "id",
3232
+ "name",
3233
+ "kind",
3234
+ "aspect_ratios",
3235
+ "max_reference_images",
3236
+ "takes_video",
3237
+ "takes_audio",
3238
+ "cost",
3239
+ "price"
3240
+ ],
3241
+ "additionalProperties": false
3242
+ }
3243
+ }
3244
+ },
3245
+ "required": [
3246
+ "models"
3247
+ ],
3248
+ "additionalProperties": false
3249
+ },
3250
+ "ApiCreatorList": {
3251
+ "type": "object",
3252
+ "properties": {
3253
+ "creators": {
3254
+ "type": "array",
3255
+ "items": {
3256
+ "type": "object",
3257
+ "properties": {
3258
+ "id": {
3259
+ "type": "string",
3260
+ "description": "Pass this as creator_id to creator_video."
3261
+ },
3262
+ "name": {
3263
+ "type": "string"
3264
+ },
3265
+ "blurb": {
3266
+ "type": "string"
3267
+ },
3268
+ "poster_url": {
3269
+ "type": "string"
3270
+ }
3271
+ },
3272
+ "required": [
3273
+ "id",
3274
+ "name",
3275
+ "blurb",
3276
+ "poster_url"
3277
+ ],
3278
+ "additionalProperties": false
3279
+ }
3280
+ }
3281
+ },
3282
+ "required": [
3283
+ "creators"
3284
+ ],
3285
+ "additionalProperties": false
3286
+ },
3287
+ "ApiTemplateList": {
3288
+ "type": "object",
3289
+ "properties": {
3290
+ "templates": {
3291
+ "type": "array",
3292
+ "items": {
3293
+ "type": "object",
3294
+ "properties": {
3295
+ "id": {
3296
+ "type": "string",
3297
+ "description": "Pass this as `template` to run_template."
3298
+ },
3299
+ "name": {
3300
+ "type": "string"
3301
+ },
3302
+ "kind": {
3303
+ "type": "string",
3304
+ "enum": [
3305
+ "product_ad",
3306
+ "video_template",
3307
+ "talking_head",
3308
+ "podcast"
3309
+ ]
3310
+ },
3311
+ "about": {
3312
+ "type": "string"
3313
+ },
3314
+ "inputs": {
3315
+ "type": "array",
3316
+ "items": {
3317
+ "type": "object",
3318
+ "properties": {
3319
+ "name": {
3320
+ "type": "string",
3321
+ "description": "The run_template field this fills (a dotted name like `pictures.<slot>` is a key inside that field)."
3322
+ },
3323
+ "type": {
3324
+ "type": "string",
3325
+ "description": "What it takes, e.g. \"text\", \"image_url\", \"video_url\", \"image_urls\"."
3326
+ },
3327
+ "required": {
3328
+ "type": "boolean"
3329
+ },
3330
+ "about": {
3331
+ "type": "string"
3332
+ }
3333
+ },
3334
+ "required": [
3335
+ "name",
3336
+ "type",
3337
+ "required",
3338
+ "about"
3339
+ ],
3340
+ "additionalProperties": false
3341
+ }
3342
+ },
3343
+ "price_hint": {
3344
+ "description": "A rough price. The exact one comes from run_template with dry_run: true.",
3345
+ "type": "object",
3346
+ "properties": {
3347
+ "credits": {
3348
+ "type": "number"
3349
+ },
3350
+ "approximate": {
3351
+ "type": "boolean",
3352
+ "const": true
3353
+ }
3354
+ },
3355
+ "required": [
3356
+ "credits",
3357
+ "approximate"
3358
+ ],
3359
+ "additionalProperties": false
3360
+ }
3361
+ },
3362
+ "required": [
3363
+ "id",
3364
+ "name",
3365
+ "kind",
3366
+ "about",
3367
+ "inputs"
3368
+ ],
3369
+ "additionalProperties": false
3370
+ }
3371
+ }
3372
+ },
3373
+ "required": [
3374
+ "templates"
3375
+ ],
3376
+ "additionalProperties": false
3377
+ },
3378
+ "ApiCallbackDeliveryList": {
3379
+ "type": "object",
3380
+ "properties": {
3381
+ "deliveries": {
3382
+ "type": "array",
3383
+ "items": {
3384
+ "type": "object",
3385
+ "properties": {
3386
+ "event_id": {
3387
+ "type": "string"
3388
+ },
3389
+ "type": {
3390
+ "type": "string",
3391
+ "enum": [
3392
+ "result.finished"
3393
+ ]
3394
+ },
3395
+ "result_id": {
3396
+ "type": "string",
3397
+ "description": "The job this event is about."
3398
+ },
3399
+ "url": {
3400
+ "type": "string"
3401
+ },
3402
+ "status": {
3403
+ "type": "string",
3404
+ "enum": [
3405
+ "PENDING",
3406
+ "DELIVERED",
3407
+ "FAILED"
3408
+ ],
3409
+ "description": "PENDING = will be tried (again); DELIVERED = your server answered 2xx; FAILED = we gave up."
3410
+ },
3411
+ "attempts": {
3412
+ "type": "integer",
3413
+ "minimum": -9007199254740991,
3414
+ "maximum": 9007199254740991
3415
+ },
3416
+ "last_status_code": {
3417
+ "type": "integer",
3418
+ "minimum": -9007199254740991,
3419
+ "maximum": 9007199254740991
3420
+ },
3421
+ "last_error": {
3422
+ "type": "string"
3423
+ },
3424
+ "last_attempt_at": {
3425
+ "type": "string"
3426
+ },
3427
+ "next_attempt_at": {
3428
+ "type": "string"
3429
+ },
3430
+ "delivered_at": {
3431
+ "type": "string"
3432
+ },
3433
+ "created_at": {
3434
+ "type": "string"
3435
+ },
3436
+ "test": {
3437
+ "type": "boolean",
3438
+ "const": true
3439
+ }
3440
+ },
3441
+ "required": [
3442
+ "event_id",
3443
+ "type",
3444
+ "result_id",
3445
+ "url",
3446
+ "status",
3447
+ "attempts",
3448
+ "created_at"
3449
+ ],
3450
+ "additionalProperties": false
3451
+ },
3452
+ "description": "Newest first."
3453
+ },
3454
+ "next_cursor": {
3455
+ "description": "Pass as `cursor` for the next page. Absent on the last page.",
3456
+ "type": "string"
3457
+ }
3458
+ },
3459
+ "required": [
3460
+ "deliveries"
3461
+ ],
3462
+ "additionalProperties": false
3463
+ },
3464
+ "ApiCallbackDeliveryItem": {
3465
+ "type": "object",
3466
+ "properties": {
3467
+ "event_id": {
3468
+ "type": "string"
3469
+ },
3470
+ "type": {
3471
+ "type": "string",
3472
+ "enum": [
3473
+ "result.finished"
3474
+ ]
3475
+ },
3476
+ "result_id": {
3477
+ "type": "string",
3478
+ "description": "The job this event is about."
3479
+ },
3480
+ "url": {
3481
+ "type": "string"
3482
+ },
3483
+ "status": {
3484
+ "type": "string",
3485
+ "enum": [
3486
+ "PENDING",
3487
+ "DELIVERED",
3488
+ "FAILED"
3489
+ ],
3490
+ "description": "PENDING = will be tried (again); DELIVERED = your server answered 2xx; FAILED = we gave up."
3491
+ },
3492
+ "attempts": {
3493
+ "type": "integer",
3494
+ "minimum": -9007199254740991,
3495
+ "maximum": 9007199254740991
3496
+ },
3497
+ "last_status_code": {
3498
+ "type": "integer",
3499
+ "minimum": -9007199254740991,
3500
+ "maximum": 9007199254740991
3501
+ },
3502
+ "last_error": {
3503
+ "type": "string"
3504
+ },
3505
+ "last_attempt_at": {
3506
+ "type": "string"
3507
+ },
3508
+ "next_attempt_at": {
3509
+ "type": "string"
3510
+ },
3511
+ "delivered_at": {
3512
+ "type": "string"
3513
+ },
3514
+ "created_at": {
3515
+ "type": "string"
3516
+ },
3517
+ "test": {
3518
+ "type": "boolean",
3519
+ "const": true
3520
+ }
3521
+ },
3522
+ "required": [
3523
+ "event_id",
3524
+ "type",
3525
+ "result_id",
3526
+ "url",
3527
+ "status",
3528
+ "attempts",
3529
+ "created_at"
3530
+ ],
3531
+ "additionalProperties": false
3532
+ },
3533
+ "ApiCallbackSecretView": {
3534
+ "type": "object",
3535
+ "properties": {
3536
+ "secret": {
3537
+ "type": "string",
3538
+ "description": "Starts with \"whsec_\". Use it to check the webhook-signature header."
3539
+ },
3540
+ "previous_valid_until": {
3541
+ "description": "After a rotation, the old secret still signs (a second signature) until this time.",
3542
+ "type": "string"
3543
+ }
3544
+ },
3545
+ "required": [
3546
+ "secret"
3547
+ ],
3548
+ "additionalProperties": false
3549
+ },
3550
+ "ApiAdsAccountList": {
3551
+ "type": "object",
3552
+ "properties": {
3553
+ "accounts": {
3554
+ "type": "array",
3555
+ "items": {
3556
+ "type": "object",
3557
+ "properties": {
3558
+ "id": {
3559
+ "type": "string"
3560
+ },
3561
+ "platform": {
3562
+ "type": "string"
3563
+ },
3564
+ "name": {
3565
+ "type": "string"
3566
+ },
3567
+ "currency": {
3568
+ "type": "string"
3569
+ },
3570
+ "ready": {
3571
+ "type": "boolean"
3572
+ },
3573
+ "needs": {
3574
+ "anyOf": [
3575
+ {
3576
+ "type": "string"
3577
+ },
3578
+ {
3579
+ "type": "null"
3580
+ }
3581
+ ]
3582
+ },
3583
+ "runs_as": {
3584
+ "anyOf": [
3585
+ {
3586
+ "type": "string"
3587
+ },
3588
+ {
3589
+ "type": "null"
3590
+ }
3591
+ ]
3592
+ }
3593
+ },
3594
+ "required": [
3595
+ "id",
3596
+ "platform",
3597
+ "name",
3598
+ "currency",
3599
+ "ready",
3600
+ "needs",
3601
+ "runs_as"
3602
+ ],
3603
+ "additionalProperties": false
3604
+ }
3605
+ },
3606
+ "settings_url": {
3607
+ "type": "string"
3608
+ },
3609
+ "next": {
3610
+ "type": "string"
3611
+ }
3612
+ },
3613
+ "required": [
3614
+ "accounts",
3615
+ "settings_url",
3616
+ "next"
3617
+ ],
3618
+ "additionalProperties": false
3619
+ },
3620
+ "ApiAdsCreativeList": {
3621
+ "type": "object",
3622
+ "properties": {
3623
+ "creatives": {
3624
+ "type": "array",
3625
+ "items": {
3626
+ "type": "object",
3627
+ "properties": {
3628
+ "id": {
3629
+ "type": "string"
3630
+ },
3631
+ "kind": {
3632
+ "type": "string",
3633
+ "enum": [
3634
+ "image",
3635
+ "video"
3636
+ ]
3637
+ },
3638
+ "url": {
3639
+ "type": "string"
3640
+ },
3641
+ "thumbnail_url": {
3642
+ "anyOf": [
3643
+ {
3644
+ "type": "string"
3645
+ },
3646
+ {
3647
+ "type": "null"
3648
+ }
3649
+ ]
3650
+ },
3651
+ "width": {
3652
+ "anyOf": [
3653
+ {
3654
+ "type": "number"
3655
+ },
3656
+ {
3657
+ "type": "null"
3658
+ }
3659
+ ]
3660
+ },
3661
+ "height": {
3662
+ "anyOf": [
3663
+ {
3664
+ "type": "number"
3665
+ },
3666
+ {
3667
+ "type": "null"
3668
+ }
3669
+ ]
3670
+ },
3671
+ "duration_sec": {
3672
+ "anyOf": [
3673
+ {
3674
+ "type": "number"
3675
+ },
3676
+ {
3677
+ "type": "null"
3678
+ }
3679
+ ]
3680
+ },
3681
+ "created_at": {
3682
+ "type": "string"
3683
+ },
3684
+ "fits": {
3685
+ "type": "object",
3686
+ "propertyNames": {
3687
+ "type": "string"
3688
+ },
3689
+ "additionalProperties": {}
3690
+ }
3691
+ },
3692
+ "required": [
3693
+ "id",
3694
+ "kind",
3695
+ "url",
3696
+ "thumbnail_url",
3697
+ "width",
3698
+ "height",
3699
+ "duration_sec",
3700
+ "created_at",
3701
+ "fits"
3702
+ ],
3703
+ "additionalProperties": false
3704
+ }
3705
+ }
3706
+ },
3707
+ "required": [
3708
+ "creatives"
3709
+ ],
3710
+ "additionalProperties": false
3711
+ },
3712
+ "ApiAdsCampaigns": {
3713
+ "type": "object",
3714
+ "properties": {},
3715
+ "additionalProperties": {},
3716
+ "description": "Campaigns with their stats for the days asked."
3717
+ },
3718
+ "ApiAdsLaunch": {
3719
+ "type": "object",
3720
+ "properties": {
3721
+ "id": {
3722
+ "type": "string"
3723
+ },
3724
+ "status": {
3725
+ "type": "string"
3726
+ },
3727
+ "step": {
3728
+ "anyOf": [
3729
+ {
3730
+ "type": "string"
3731
+ },
3732
+ {
3733
+ "type": "null"
3734
+ }
3735
+ ]
3736
+ },
3737
+ "error": {
3738
+ "anyOf": [
3739
+ {
3740
+ "type": "string"
3741
+ },
3742
+ {
3743
+ "type": "null"
3744
+ }
3745
+ ]
3746
+ },
3747
+ "platform": {
3748
+ "type": "string"
3749
+ },
3750
+ "account": {
3751
+ "type": "string"
3752
+ },
3753
+ "name": {
3754
+ "type": "string"
3755
+ },
3756
+ "daily_budget": {
3757
+ "type": "number"
3758
+ },
3759
+ "currency": {
3760
+ "type": "string"
3761
+ },
3762
+ "review_url": {
3763
+ "anyOf": [
3764
+ {
3765
+ "type": "string"
3766
+ },
3767
+ {
3768
+ "type": "null"
3769
+ }
3770
+ ]
3771
+ },
3772
+ "open_url": {
3773
+ "anyOf": [
3774
+ {
3775
+ "type": "string"
3776
+ },
3777
+ {
3778
+ "type": "null"
3779
+ }
3780
+ ]
3781
+ },
3782
+ "live_at": {
3783
+ "anyOf": [
3784
+ {
3785
+ "type": "string"
3786
+ },
3787
+ {
3788
+ "type": "null"
3789
+ }
3790
+ ]
3791
+ },
3792
+ "next": {
3793
+ "type": "string"
3794
+ }
3795
+ },
3796
+ "required": [
3797
+ "id",
3798
+ "status",
3799
+ "step",
3800
+ "error",
3801
+ "platform",
3802
+ "account",
3803
+ "name",
3804
+ "daily_budget",
3805
+ "currency",
3806
+ "review_url",
3807
+ "open_url",
3808
+ "live_at",
3809
+ "next"
3810
+ ],
3811
+ "additionalProperties": false
3812
+ },
3813
+ "ApiMe": {
3814
+ "type": "object",
3815
+ "properties": {
3816
+ "email": {
3817
+ "type": "string"
3818
+ },
3819
+ "key": {
3820
+ "anyOf": [
3821
+ {
3822
+ "type": "object",
3823
+ "properties": {
3824
+ "id": {
3825
+ "type": "string"
3826
+ },
3827
+ "name": {
3828
+ "type": "string"
3829
+ },
3830
+ "mode": {
3831
+ "type": "string",
3832
+ "enum": [
3833
+ "live",
3834
+ "test"
3835
+ ]
3836
+ },
3837
+ "daily_limit_credits": {
3838
+ "anyOf": [
3839
+ {
3840
+ "type": "number"
3841
+ },
3842
+ {
3843
+ "type": "null"
3844
+ }
3845
+ ]
3846
+ },
3847
+ "monthly_limit_credits": {
3848
+ "anyOf": [
3849
+ {
3850
+ "type": "number"
3851
+ },
3852
+ {
3853
+ "type": "null"
3854
+ }
3855
+ ]
3856
+ }
3857
+ },
3858
+ "required": [
3859
+ "id",
3860
+ "name",
3861
+ "mode",
3862
+ "daily_limit_credits",
3863
+ "monthly_limit_credits"
3864
+ ],
3865
+ "additionalProperties": false
3866
+ },
3867
+ {
3868
+ "type": "null"
3869
+ }
3870
+ ],
3871
+ "description": "The key this request used; null for a signed-in browser or an OAuth app."
3872
+ },
3873
+ "balance_credits": {
3874
+ "type": "number",
3875
+ "description": "What the wallet has left to spend, two decimals."
3876
+ },
3877
+ "wallet": {
3878
+ "type": "string",
3879
+ "enum": [
3880
+ "personal",
3881
+ "team"
3882
+ ]
3883
+ }
3884
+ },
3885
+ "required": [
3886
+ "email",
3887
+ "key",
3888
+ "balance_credits",
3889
+ "wallet"
3890
+ ],
3891
+ "additionalProperties": false
3892
+ },
3893
+ "ApiCliLogin": {
3894
+ "type": "object",
3895
+ "properties": {
3896
+ "login_id": {
3897
+ "type": "string"
3898
+ },
3899
+ "code": {
3900
+ "type": "string",
3901
+ "description": "6 digits. Show it; the person checks the browser page shows the same."
3902
+ },
3903
+ "verify_url": {
3904
+ "type": "string",
3905
+ "description": "Open this in a browser that is signed in to diffusr."
3906
+ },
3907
+ "poll_token": {
3908
+ "type": "string",
3909
+ "description": "Secret: send it to poll_cli_login. Never show it."
3910
+ },
3911
+ "expires_in": {
3912
+ "type": "integer",
3913
+ "minimum": -9007199254740991,
3914
+ "maximum": 9007199254740991
3915
+ },
3916
+ "interval": {
3917
+ "type": "integer",
3918
+ "minimum": -9007199254740991,
3919
+ "maximum": 9007199254740991,
3920
+ "description": "Seconds to wait between polls."
3921
+ }
3922
+ },
3923
+ "required": [
3924
+ "login_id",
3925
+ "code",
3926
+ "verify_url",
3927
+ "poll_token",
3928
+ "expires_in",
3929
+ "interval"
3930
+ ],
3931
+ "additionalProperties": false
3932
+ },
3933
+ "ApiCliLoginPoll": {
3934
+ "type": "object",
3935
+ "properties": {
3936
+ "status": {
3937
+ "type": "string",
3938
+ "enum": [
3939
+ "pending",
3940
+ "approved",
3941
+ "denied",
3942
+ "expired",
3943
+ "failed"
3944
+ ]
3945
+ },
3946
+ "key": {
3947
+ "type": "string"
3948
+ },
3949
+ "key_id": {
3950
+ "type": "string"
3951
+ },
3952
+ "key_name": {
3953
+ "type": "string"
3954
+ },
3955
+ "mode": {
3956
+ "type": "string",
3957
+ "enum": [
3958
+ "live",
3959
+ "test"
3960
+ ]
3961
+ },
3962
+ "email": {
3963
+ "type": "string"
3964
+ },
3965
+ "daily_limit_credits": {
3966
+ "anyOf": [
3967
+ {
3968
+ "type": "number"
3969
+ },
3970
+ {
3971
+ "type": "null"
3972
+ }
3973
+ ]
3974
+ },
3975
+ "monthly_limit_credits": {
3976
+ "anyOf": [
3977
+ {
3978
+ "type": "number"
3979
+ },
3980
+ {
3981
+ "type": "null"
3982
+ }
3983
+ ]
3984
+ },
3985
+ "error": {
3986
+ "type": "string"
3987
+ }
3988
+ },
3989
+ "required": [
3990
+ "status"
3991
+ ],
3992
+ "additionalProperties": false
3993
+ },
3994
+ "ApiCliLogout": {
3995
+ "type": "object",
3996
+ "properties": {
3997
+ "revoked": {
3998
+ "type": "boolean"
3999
+ }
4000
+ },
4001
+ "required": [
4002
+ "revoked"
4003
+ ],
4004
+ "additionalProperties": false
4005
+ }
4006
+ },
4007
+ "responses": {
4008
+ "Unauthorized": {
4009
+ "description": "Missing, wrong, revoked or expired API key (code UNAUTHORIZED, KEY_REVOKED, KEY_EXPIRED).",
4010
+ "headers": {
4011
+ "X-Request-Id": {
4012
+ "$ref": "#/components/headers/RequestId"
4013
+ }
4014
+ },
4015
+ "content": {
4016
+ "application/json": {
4017
+ "schema": {
4018
+ "$ref": "#/components/schemas/Error"
4019
+ }
4020
+ }
4021
+ }
4022
+ },
4023
+ "PaymentRequired": {
4024
+ "description": "Not enough credits, or an API budget would be passed (INSUFFICIENT_CREDITS, BUDGET_EXCEEDED).",
4025
+ "headers": {
4026
+ "X-Request-Id": {
4027
+ "$ref": "#/components/headers/RequestId"
4028
+ }
4029
+ },
4030
+ "content": {
4031
+ "application/json": {
4032
+ "schema": {
4033
+ "$ref": "#/components/schemas/Error"
4034
+ }
4035
+ }
4036
+ }
4037
+ },
4038
+ "Forbidden": {
4039
+ "description": "The key may not do this (SCOPE_DENIED, MODEL_NOT_ALLOWED, TEST_MODE_UNSUPPORTED, ACCOUNT_BLOCKED, allowance_exceeded).",
4040
+ "headers": {
4041
+ "X-Request-Id": {
4042
+ "$ref": "#/components/headers/RequestId"
4043
+ }
4044
+ },
4045
+ "content": {
4046
+ "application/json": {
4047
+ "schema": {
4048
+ "$ref": "#/components/schemas/Error"
4049
+ }
4050
+ }
4051
+ }
4052
+ },
4053
+ "NotFound": {
4054
+ "description": "No such id, or it is not yours, or it belongs to the other key mode (NOT_FOUND).",
4055
+ "headers": {
4056
+ "X-Request-Id": {
4057
+ "$ref": "#/components/headers/RequestId"
4058
+ }
4059
+ },
4060
+ "content": {
4061
+ "application/json": {
4062
+ "schema": {
4063
+ "$ref": "#/components/schemas/Error"
4064
+ }
4065
+ }
4066
+ }
4067
+ },
4068
+ "Conflict": {
4069
+ "description": "IDEMPOTENCY_CONFLICT or CALLBACK_NOT_RETRYABLE.",
4070
+ "headers": {
4071
+ "X-Request-Id": {
4072
+ "$ref": "#/components/headers/RequestId"
4073
+ }
4074
+ },
4075
+ "content": {
4076
+ "application/json": {
4077
+ "schema": {
4078
+ "$ref": "#/components/schemas/Error"
4079
+ }
4080
+ }
4081
+ }
4082
+ },
4083
+ "TooLarge": {
4084
+ "description": "The request or file is too large (TOO_LARGE, REFERENCE_TOO_LARGE).",
4085
+ "headers": {
4086
+ "X-Request-Id": {
4087
+ "$ref": "#/components/headers/RequestId"
4088
+ }
4089
+ },
4090
+ "content": {
4091
+ "application/json": {
4092
+ "schema": {
4093
+ "$ref": "#/components/schemas/Error"
4094
+ }
4095
+ }
4096
+ }
4097
+ },
4098
+ "Unprocessable": {
4099
+ "description": "The request is not valid (VALIDATION_FAILED, INVALID_JSON, PREFLIGHT_FAILED, CALLBACK_URL_INVALID, REFERENCE_*). `issues` lists each problem. Nothing was charged.",
4100
+ "headers": {
4101
+ "X-Request-Id": {
4102
+ "$ref": "#/components/headers/RequestId"
4103
+ }
4104
+ },
4105
+ "content": {
4106
+ "application/json": {
4107
+ "schema": {
4108
+ "$ref": "#/components/schemas/Error"
4109
+ }
4110
+ }
4111
+ }
4112
+ },
4113
+ "RateLimited": {
4114
+ "description": "Too many requests or jobs (RATE_LIMITED, CONCURRENCY_LIMIT, UPLOAD_QUOTA, …). Wait Retry-After seconds, then retry.",
4115
+ "headers": {
4116
+ "X-Request-Id": {
4117
+ "$ref": "#/components/headers/RequestId"
4118
+ },
4119
+ "Retry-After": {
4120
+ "$ref": "#/components/headers/RetryAfter"
4121
+ }
4122
+ },
4123
+ "content": {
4124
+ "application/json": {
4125
+ "schema": {
4126
+ "$ref": "#/components/schemas/Error"
4127
+ }
4128
+ }
4129
+ }
4130
+ },
4131
+ "InternalError": {
4132
+ "description": "Our fault (INTERNAL_ERROR). Quote request_id to support.",
4133
+ "headers": {
4134
+ "X-Request-Id": {
4135
+ "$ref": "#/components/headers/RequestId"
4136
+ }
4137
+ },
4138
+ "content": {
4139
+ "application/json": {
4140
+ "schema": {
4141
+ "$ref": "#/components/schemas/Error"
4142
+ }
4143
+ }
4144
+ }
4145
+ },
4146
+ "Unavailable": {
4147
+ "description": "Paused or busy (API_PAUSED, MODEL_PAUSED, PROVIDER_PAUSED, PROVIDER_BUSY, UNAVAILABLE). Wait Retry-After seconds, then retry.",
4148
+ "headers": {
4149
+ "X-Request-Id": {
4150
+ "$ref": "#/components/headers/RequestId"
4151
+ },
4152
+ "Retry-After": {
4153
+ "$ref": "#/components/headers/RetryAfter"
4154
+ }
4155
+ },
4156
+ "content": {
4157
+ "application/json": {
4158
+ "schema": {
4159
+ "$ref": "#/components/schemas/Error"
4160
+ }
4161
+ }
4162
+ }
4163
+ }
4164
+ }
4165
+ },
4166
+ "x-error-codes": {
4167
+ "UNAUTHORIZED": "Missing, malformed or unknown API key.",
4168
+ "KEY_REVOKED": "This key was revoked. Make a new one on the Developers page.",
4169
+ "KEY_EXPIRED": "This key passed its expiry date. Make a new one.",
4170
+ "SCOPE_DENIED": "The key does not have the scope this call needs.",
4171
+ "MODEL_NOT_ALLOWED": "The key is limited to other models.",
4172
+ "TEST_MODE_UNSUPPORTED": "This call is not available with a test key.",
4173
+ "ACCOUNT_BLOCKED": "The account is blocked. Contact support.",
4174
+ "FORBIDDEN": "Not allowed (a refusal that has no more specific code).",
4175
+ "VALIDATION_FAILED": "The input did not match the schema; `issues` lists each field and why. Nothing was made, nothing charged.",
4176
+ "INVALID_JSON": "The body was not a JSON object.",
4177
+ "INVALID_REQUEST": "The request was understood but cannot be done as sent (a refusal that has no more specific code).",
4178
+ "PREFLIGHT_FAILED": "The job cannot run as described (for example a missing input); `issues` lists why. Nothing was charged.",
4179
+ "CALLBACK_URL_INVALID": "callback_url is not usable: it must be a public https address with no password.",
4180
+ "CALLBACK_NOT_RETRYABLE": "That callback event can't be retried now: it was delivered, is still being tried, or is out of manual retries.",
4181
+ "REFERENCE_UNREACHABLE": "A reference file could not be fetched.",
4182
+ "REFERENCE_TOO_LARGE": "A reference file is over the model's size or length limit.",
4183
+ "REFERENCE_UNSUPPORTED": "A reference file is the wrong kind for this model.",
4184
+ "REFERENCE_FORBIDDEN": "A reference points at a file the caller may not use.",
4185
+ "NOT_FOUND": "No such id, or it belongs to someone else (or to the other key mode: test vs live).",
4186
+ "IDEMPOTENCY_CONFLICT": "This Idempotency-Key was already used for a different request.",
4187
+ "CONFLICT": "The request conflicts with the current state (a refusal that has no more specific code).",
4188
+ "INSUFFICIENT_CREDITS": "Not enough free credits; `needed` and `balance` say by how much.",
4189
+ "allowance_exceeded": "A team member's limit or the team pot is used up (legacy lowercase code, kept for existing clients).",
4190
+ "BUDGET_EXCEEDED": "The key's or account's daily or monthly API budget would be passed; `budget` has the window and when it frees up.",
4191
+ "RATE_LIMITED": "Too many requests of this kind this minute.",
4192
+ "CONCURRENCY_LIMIT": "Too many jobs queued or running for this key or account.",
4193
+ "PROVIDER_BUSY": "Our capacity at the model's supplier is full. Not the caller's fault; try again.",
4194
+ "AUTH_RATE_LIMITED": "Too many failed sign-in attempts from this address.",
4195
+ "KEY_LIMIT": "The key hit its own limit (for example how many keys an account may hold).",
4196
+ "TEST_LIMIT": "A test key hit its own cap (per minute or per day). Wait, or use a live key.",
4197
+ "UPLOAD_QUOTA": "Too many uploads in the last 24 hours.",
4198
+ "STORAGE_QUOTA": "The account's stored upload bytes are at the cap; uploads clear on their own.",
4199
+ "TOO_LARGE": "The request or file is too large (a refusal that has no more specific code).",
4200
+ "WALLET_BUSY": "The wallet was locked by another request. Retry at once.",
4201
+ "API_PAUSED": "New API starts are paused for everyone. Runs already started finish.",
4202
+ "MODEL_PAUSED": "This model is paused for new API starts.",
4203
+ "PROVIDER_PAUSED": "This model's supplier is paused for new API starts.",
4204
+ "UNAVAILABLE": "A service we depend on is not available right now (a refusal that has no more specific code). Retry later.",
4205
+ "INTERNAL_ERROR": "Something went wrong on our side. Quote the request_id to support."
4206
+ }
4207
+ }