ads_dev 1.0.0__py3-none-any.whl

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.
ads_dev/types.py ADDED
@@ -0,0 +1,2126 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: openapi.json
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Any, Literal
7
+ from uuid import UUID
8
+
9
+ from pydantic import (
10
+ AnyUrl,
11
+ BaseModel,
12
+ ConfigDict,
13
+ Field,
14
+ RootModel,
15
+ confloat,
16
+ conint,
17
+ constr,
18
+ )
19
+
20
+
21
+ class CreateNanoBananaProInput(BaseModel):
22
+ prompt: constr(min_length=3, max_length=50000) = Field(
23
+ ...,
24
+ description="What the image shows, as one paragraph; 150 to 350 words of concrete detail work best.",
25
+ )
26
+ aspect_ratio: (
27
+ Literal["1:1", "21:9", "16:9", "3:2", "4:3", "5:4", "4:5", "3:4", "2:3", "9:16"]
28
+ | None
29
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
30
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
31
+ "2K", description="Output resolution; 2K when left out."
32
+ )
33
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
34
+ "png", description="File format; png when left out."
35
+ )
36
+ name: constr(min_length=2, max_length=80) | None = Field(
37
+ None,
38
+ description="What the output is called in your library; made from the prompt when left out.",
39
+ )
40
+
41
+
42
+ class CreateNanoBananaPro(BaseModel):
43
+ model_config = ConfigDict(
44
+ extra="forbid",
45
+ )
46
+ model: Literal["nano-banana-pro"]
47
+ input: CreateNanoBananaProInput
48
+ webhook_url: AnyUrl | None = Field(
49
+ None,
50
+ description="An https URL to POST a signed generation event to when it finishes",
51
+ )
52
+
53
+
54
+ class CreateNanoBananaProEditInput(BaseModel):
55
+ prompt: constr(min_length=3, max_length=50000) = Field(
56
+ ...,
57
+ description="The change to make, or how the images come together, naming each image by its place in images.",
58
+ )
59
+ aspect_ratio: (
60
+ Literal[
61
+ "auto",
62
+ "1:1",
63
+ "21:9",
64
+ "16:9",
65
+ "3:2",
66
+ "4:3",
67
+ "5:4",
68
+ "4:5",
69
+ "3:4",
70
+ "2:3",
71
+ "9:16",
72
+ ]
73
+ | None
74
+ ) = Field("auto", description="Shape of the image as width:height, or auto to follow the images given; auto when left out.")
75
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
76
+ "2K", description="Output resolution; 2K when left out."
77
+ )
78
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
79
+ "png", description="File format; png when left out."
80
+ )
81
+ images: list[str] = Field(
82
+ ...,
83
+ description="The 1 to 14 images to edit or combine, in the order the prompt names them, each an asset id (asset_…) or an https URL.",
84
+ max_length=14,
85
+ min_length=1,
86
+ )
87
+ seed: conint(ge=-9007199254740991, le=9007199254740991) | None = Field(
88
+ None,
89
+ description="Integer seed for a more repeatable edit; random when left out.",
90
+ )
91
+ name: constr(min_length=2, max_length=80) | None = Field(
92
+ None,
93
+ description="What the output is called in your library; made from the prompt when left out.",
94
+ )
95
+
96
+
97
+ class CreateNanoBananaProEdit(BaseModel):
98
+ model_config = ConfigDict(
99
+ extra="forbid",
100
+ )
101
+ model: Literal["nano-banana-pro/edit"]
102
+ input: CreateNanoBananaProEditInput
103
+ webhook_url: AnyUrl | None = Field(
104
+ None,
105
+ description="An https URL to POST a signed generation event to when it finishes",
106
+ )
107
+
108
+
109
+ class CreateNanoBanana2Input(BaseModel):
110
+ prompt: constr(min_length=3, max_length=50000) = Field(
111
+ ...,
112
+ description="What the image shows, as one paragraph; 150 to 350 words of concrete detail work best.",
113
+ )
114
+ aspect_ratio: (
115
+ Literal[
116
+ "1:1",
117
+ "21:9",
118
+ "16:9",
119
+ "3:2",
120
+ "4:3",
121
+ "5:4",
122
+ "4:5",
123
+ "3:4",
124
+ "2:3",
125
+ "9:16",
126
+ "4:1",
127
+ "1:4",
128
+ "8:1",
129
+ "1:8",
130
+ ]
131
+ | None
132
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
133
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
134
+ "2K", description="Output resolution; 2K when left out."
135
+ )
136
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
137
+ "png", description="File format; png when left out."
138
+ )
139
+ name: constr(min_length=2, max_length=80) | None = Field(
140
+ None,
141
+ description="What the output is called in your library; made from the prompt when left out.",
142
+ )
143
+
144
+
145
+ class CreateNanoBanana2(BaseModel):
146
+ model_config = ConfigDict(
147
+ extra="forbid",
148
+ )
149
+ model: Literal["nano-banana-2"]
150
+ input: CreateNanoBanana2Input
151
+ webhook_url: AnyUrl | None = Field(
152
+ None,
153
+ description="An https URL to POST a signed generation event to when it finishes",
154
+ )
155
+
156
+
157
+ class CreateNanoBanana2EditInput(BaseModel):
158
+ prompt: constr(min_length=3, max_length=50000) = Field(
159
+ ...,
160
+ description="The change to make, or how the images come together, naming each image by its place in images.",
161
+ )
162
+ aspect_ratio: (
163
+ Literal[
164
+ "auto",
165
+ "1:1",
166
+ "21:9",
167
+ "16:9",
168
+ "3:2",
169
+ "4:3",
170
+ "5:4",
171
+ "4:5",
172
+ "3:4",
173
+ "2:3",
174
+ "9:16",
175
+ "4:1",
176
+ "1:4",
177
+ "8:1",
178
+ "1:8",
179
+ ]
180
+ | None
181
+ ) = Field("auto", description="Shape of the image as width:height, or auto to follow the images given; auto when left out.")
182
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
183
+ "2K", description="Output resolution; 2K when left out."
184
+ )
185
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
186
+ "png", description="File format; png when left out."
187
+ )
188
+ images: list[str] = Field(
189
+ ...,
190
+ description="The 1 to 14 images to edit or combine, in the order the prompt names them, each an asset id (asset_…) or an https URL.",
191
+ max_length=14,
192
+ min_length=1,
193
+ )
194
+ seed: conint(ge=-9007199254740991, le=9007199254740991) | None = Field(
195
+ None,
196
+ description="Integer seed for a more repeatable edit; random when left out.",
197
+ )
198
+ name: constr(min_length=2, max_length=80) | None = Field(
199
+ None,
200
+ description="What the output is called in your library; made from the prompt when left out.",
201
+ )
202
+
203
+
204
+ class CreateNanoBanana2Edit(BaseModel):
205
+ model_config = ConfigDict(
206
+ extra="forbid",
207
+ )
208
+ model: Literal["nano-banana-2/edit"]
209
+ input: CreateNanoBanana2EditInput
210
+ webhook_url: AnyUrl | None = Field(
211
+ None,
212
+ description="An https URL to POST a signed generation event to when it finishes",
213
+ )
214
+
215
+
216
+ class CreateNanoBanana2LiteInput(BaseModel):
217
+ prompt: constr(min_length=3, max_length=50000) = Field(
218
+ ...,
219
+ description="What the image shows, as one paragraph; 150 to 350 words of concrete detail work best.",
220
+ )
221
+ aspect_ratio: (
222
+ Literal[
223
+ "1:1",
224
+ "21:9",
225
+ "16:9",
226
+ "3:2",
227
+ "4:3",
228
+ "5:4",
229
+ "4:5",
230
+ "3:4",
231
+ "2:3",
232
+ "9:16",
233
+ "4:1",
234
+ "1:4",
235
+ "8:1",
236
+ "1:8",
237
+ ]
238
+ | None
239
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
240
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
241
+ "png", description="File format; png when left out."
242
+ )
243
+ name: constr(min_length=2, max_length=80) | None = Field(
244
+ None,
245
+ description="What the output is called in your library; made from the prompt when left out.",
246
+ )
247
+
248
+
249
+ class CreateNanoBanana2Lite(BaseModel):
250
+ model_config = ConfigDict(
251
+ extra="forbid",
252
+ )
253
+ model: Literal["nano-banana-2-lite"]
254
+ input: CreateNanoBanana2LiteInput
255
+ webhook_url: AnyUrl | None = Field(
256
+ None,
257
+ description="An https URL to POST a signed generation event to when it finishes",
258
+ )
259
+
260
+
261
+ class CreateNanoBanana2LiteEditInput(BaseModel):
262
+ prompt: constr(min_length=3, max_length=50000) = Field(
263
+ ...,
264
+ description="The change to make, or how the images come together, naming each image by its place in images.",
265
+ )
266
+ aspect_ratio: (
267
+ Literal[
268
+ "auto",
269
+ "1:1",
270
+ "21:9",
271
+ "16:9",
272
+ "3:2",
273
+ "4:3",
274
+ "5:4",
275
+ "4:5",
276
+ "3:4",
277
+ "2:3",
278
+ "9:16",
279
+ "4:1",
280
+ "1:4",
281
+ "8:1",
282
+ "1:8",
283
+ ]
284
+ | None
285
+ ) = Field("auto", description="Shape of the image as width:height, or auto to follow the images given; auto when left out.")
286
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
287
+ "png", description="File format; png when left out."
288
+ )
289
+ images: list[str] = Field(
290
+ ...,
291
+ description="The 1 to 14 images to edit or combine, in the order the prompt names them, each an asset id (asset_…) or an https URL.",
292
+ max_length=14,
293
+ min_length=1,
294
+ )
295
+ seed: conint(ge=-9007199254740991, le=9007199254740991) | None = Field(
296
+ None,
297
+ description="Integer seed for a more repeatable edit; random when left out.",
298
+ )
299
+ name: constr(min_length=2, max_length=80) | None = Field(
300
+ None,
301
+ description="What the output is called in your library; made from the prompt when left out.",
302
+ )
303
+
304
+
305
+ class CreateNanoBanana2LiteEdit(BaseModel):
306
+ model_config = ConfigDict(
307
+ extra="forbid",
308
+ )
309
+ model: Literal["nano-banana-2-lite/edit"]
310
+ input: CreateNanoBanana2LiteEditInput
311
+ webhook_url: AnyUrl | None = Field(
312
+ None,
313
+ description="An https URL to POST a signed generation event to when it finishes",
314
+ )
315
+
316
+
317
+ class CreateGptImage25FlareInput(BaseModel):
318
+ prompt: constr(min_length=1, max_length=32000) = Field(
319
+ ...,
320
+ description="Single-paragraph image prompt (150-350 words), with any words the image must show written out exactly.",
321
+ )
322
+ aspect_ratio: (
323
+ Literal["1:1", "21:9", "16:9", "3:2", "4:3", "5:4", "4:5", "3:4", "2:3", "9:16"]
324
+ | None
325
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
326
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
327
+ "2K", description="Output resolution; 2K when left out."
328
+ )
329
+ width: conint(le=9007199254740991, gt=0) | None = Field(
330
+ None,
331
+ description="Exact width in pixels for a fixed placement, passed with height in place of aspect_ratio and resolution, with both sides multiples of 16 up to 3840, at most 3:1 either way, and 655,360 to 8,294,400 pixels in all; none when left out.",
332
+ )
333
+ height: conint(le=9007199254740991, gt=0) | None = Field(
334
+ None,
335
+ description="Exact height in pixels, passed with width under the same rules; none when left out.",
336
+ )
337
+ background: Literal["auto", "transparent", "opaque"] | None = Field(
338
+ "auto",
339
+ description="transparent for a cutout with no background, opaque for a filled one, or auto to let the model choose; auto when left out.",
340
+ )
341
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
342
+ "png",
343
+ description="File format; png when left out, and a transparent background needs png or webp.",
344
+ )
345
+ name: constr(min_length=2, max_length=80) | None = Field(
346
+ None,
347
+ description="What the output is called in your library; made from the prompt when left out.",
348
+ )
349
+
350
+
351
+ class CreateGptImage25Flare(BaseModel):
352
+ model_config = ConfigDict(
353
+ extra="forbid",
354
+ )
355
+ model: Literal["gpt-image-2.5-flare"]
356
+ input: CreateGptImage25FlareInput
357
+ webhook_url: AnyUrl | None = Field(
358
+ None,
359
+ description="An https URL to POST a signed generation event to when it finishes",
360
+ )
361
+
362
+
363
+ class CreateGptImage25FlareEditInput(BaseModel):
364
+ prompt: constr(min_length=1, max_length=32000) = Field(
365
+ ...,
366
+ description="The change to make, or how the images come together, naming each image by its place in images and writing out exactly any words the image must show.",
367
+ )
368
+ aspect_ratio: (
369
+ Literal[
370
+ "auto",
371
+ "1:1",
372
+ "21:9",
373
+ "16:9",
374
+ "3:2",
375
+ "4:3",
376
+ "5:4",
377
+ "4:5",
378
+ "3:4",
379
+ "2:3",
380
+ "9:16",
381
+ ]
382
+ | None
383
+ ) = Field("auto", description="Shape of the image as width:height, or auto to let the model pick the size; auto when left out.")
384
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
385
+ "2K",
386
+ description="Output resolution, not used when aspect_ratio is auto; 2K when left out.",
387
+ )
388
+ width: conint(le=9007199254740991, gt=0) | None = Field(
389
+ None,
390
+ description="Exact width in pixels for a fixed placement, passed with height in place of aspect_ratio and resolution, with both sides multiples of 16 up to 3840, at most 3:1 either way, and 655,360 to 8,294,400 pixels in all; none when left out.",
391
+ )
392
+ height: conint(le=9007199254740991, gt=0) | None = Field(
393
+ None,
394
+ description="Exact height in pixels, passed with width under the same rules; none when left out.",
395
+ )
396
+ background: Literal["auto", "transparent", "opaque"] | None = Field(
397
+ "auto",
398
+ description="transparent for a cutout with no background, opaque for a filled one, or auto to let the model choose; auto when left out.",
399
+ )
400
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
401
+ "png",
402
+ description="File format; png when left out, and a transparent background needs png or webp.",
403
+ )
404
+ images: list[str] = Field(
405
+ ...,
406
+ description="The 1 to 16 images to edit or combine, in the order the prompt names them, each an asset id (asset_…) or an https URL.",
407
+ max_length=16,
408
+ min_length=1,
409
+ )
410
+ mask: str | None = Field(
411
+ None,
412
+ description="An image the size of the first of images, as an asset id (asset_…) or an https URL, with an alpha channel that is fully transparent where that image should change; the model takes it as guidance, so the rest can shift slightly. None when left out, so the prompt alone scopes the change.",
413
+ )
414
+ name: constr(min_length=2, max_length=80) | None = Field(
415
+ None,
416
+ description="What the output is called in your library; made from the prompt when left out.",
417
+ )
418
+
419
+
420
+ class CreateGptImage25FlareEdit(BaseModel):
421
+ model_config = ConfigDict(
422
+ extra="forbid",
423
+ )
424
+ model: Literal["gpt-image-2.5-flare/edit"]
425
+ input: CreateGptImage25FlareEditInput
426
+ webhook_url: AnyUrl | None = Field(
427
+ None,
428
+ description="An https URL to POST a signed generation event to when it finishes",
429
+ )
430
+
431
+
432
+ class CreateGptImage25SunburstInput(BaseModel):
433
+ prompt: constr(min_length=1, max_length=32000) = Field(
434
+ ...,
435
+ description="Single-paragraph image prompt (150-350 words), with any words the image must show written out exactly.",
436
+ )
437
+ aspect_ratio: (
438
+ Literal["1:1", "21:9", "16:9", "3:2", "4:3", "5:4", "4:5", "3:4", "2:3", "9:16"]
439
+ | None
440
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
441
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
442
+ "2K", description="Output resolution; 2K when left out."
443
+ )
444
+ width: conint(le=9007199254740991, gt=0) | None = Field(
445
+ None,
446
+ description="Exact width in pixels for a fixed placement, passed with height in place of aspect_ratio and resolution, with both sides multiples of 16 up to 3840, at most 3:1 either way, and 655,360 to 8,294,400 pixels in all; none when left out.",
447
+ )
448
+ height: conint(le=9007199254740991, gt=0) | None = Field(
449
+ None,
450
+ description="Exact height in pixels, passed with width under the same rules; none when left out.",
451
+ )
452
+ background: Literal["auto", "transparent", "opaque"] | None = Field(
453
+ "auto",
454
+ description="transparent for a cutout with no background, opaque for a filled one, or auto to let the model choose; auto when left out.",
455
+ )
456
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
457
+ "png",
458
+ description="File format; png when left out, and a transparent background needs png or webp.",
459
+ )
460
+ name: constr(min_length=2, max_length=80) | None = Field(
461
+ None,
462
+ description="What the output is called in your library; made from the prompt when left out.",
463
+ )
464
+
465
+
466
+ class CreateGptImage25Sunburst(BaseModel):
467
+ model_config = ConfigDict(
468
+ extra="forbid",
469
+ )
470
+ model: Literal["gpt-image-2.5-sunburst"]
471
+ input: CreateGptImage25SunburstInput
472
+ webhook_url: AnyUrl | None = Field(
473
+ None,
474
+ description="An https URL to POST a signed generation event to when it finishes",
475
+ )
476
+
477
+
478
+ class CreateGptImage25SunburstEditInput(BaseModel):
479
+ prompt: constr(min_length=1, max_length=32000) = Field(
480
+ ...,
481
+ description="The change to make, or how the images come together, naming each image by its place in images and writing out exactly any words the image must show.",
482
+ )
483
+ aspect_ratio: (
484
+ Literal[
485
+ "auto",
486
+ "1:1",
487
+ "21:9",
488
+ "16:9",
489
+ "3:2",
490
+ "4:3",
491
+ "5:4",
492
+ "4:5",
493
+ "3:4",
494
+ "2:3",
495
+ "9:16",
496
+ ]
497
+ | None
498
+ ) = Field("auto", description="Shape of the image as width:height, or auto to let the model pick the size; auto when left out.")
499
+ resolution: Literal["1K", "2K", "4K"] | None = Field(
500
+ "2K",
501
+ description="Output resolution, not used when aspect_ratio is auto; 2K when left out.",
502
+ )
503
+ width: conint(le=9007199254740991, gt=0) | None = Field(
504
+ None,
505
+ description="Exact width in pixels for a fixed placement, passed with height in place of aspect_ratio and resolution, with both sides multiples of 16 up to 3840, at most 3:1 either way, and 655,360 to 8,294,400 pixels in all; none when left out.",
506
+ )
507
+ height: conint(le=9007199254740991, gt=0) | None = Field(
508
+ None,
509
+ description="Exact height in pixels, passed with width under the same rules; none when left out.",
510
+ )
511
+ background: Literal["auto", "transparent", "opaque"] | None = Field(
512
+ "auto",
513
+ description="transparent for a cutout with no background, opaque for a filled one, or auto to let the model choose; auto when left out.",
514
+ )
515
+ output_format: Literal["png", "jpeg", "webp"] | None = Field(
516
+ "png",
517
+ description="File format; png when left out, and a transparent background needs png or webp.",
518
+ )
519
+ images: list[str] = Field(
520
+ ...,
521
+ description="The 1 to 16 images to edit or combine, in the order the prompt names them, each an asset id (asset_…) or an https URL.",
522
+ max_length=16,
523
+ min_length=1,
524
+ )
525
+ mask: str | None = Field(
526
+ None,
527
+ description="An image the size of the first of images, as an asset id (asset_…) or an https URL, with an alpha channel that is fully transparent where that image should change; the model takes it as guidance, so the rest can shift slightly. None when left out, so the prompt alone scopes the change.",
528
+ )
529
+ name: constr(min_length=2, max_length=80) | None = Field(
530
+ None,
531
+ description="What the output is called in your library; made from the prompt when left out.",
532
+ )
533
+
534
+
535
+ class CreateGptImage25SunburstEdit(BaseModel):
536
+ model_config = ConfigDict(
537
+ extra="forbid",
538
+ )
539
+ model: Literal["gpt-image-2.5-sunburst/edit"]
540
+ input: CreateGptImage25SunburstEditInput
541
+ webhook_url: AnyUrl | None = Field(
542
+ None,
543
+ description="An https URL to POST a signed generation event to when it finishes",
544
+ )
545
+
546
+
547
+ class CreateSeedream5ProInput(BaseModel):
548
+ prompt: constr(min_length=3) = Field(
549
+ ...,
550
+ description="Single-paragraph image prompt, at most 600 words, with the exact words the image must show written out.",
551
+ )
552
+ aspect_ratio: (
553
+ Literal["1:1", "21:9", "16:9", "3:2", "4:3", "5:4", "4:5", "3:4", "2:3", "9:16"]
554
+ | None
555
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
556
+ resolution: Literal["1.5K", "2K"] | None = Field(
557
+ "2K",
558
+ description="Output resolution, 1.5K for drafts at half the price and 2K for finals; 2K when left out.",
559
+ )
560
+ output_format: Literal["png", "jpeg"] | None = Field(
561
+ "png", description="File format; png when left out."
562
+ )
563
+ name: constr(min_length=2, max_length=80) | None = Field(
564
+ None,
565
+ description="What the output is called in your library; made from the prompt when left out.",
566
+ )
567
+
568
+
569
+ class CreateSeedream5Pro(BaseModel):
570
+ model_config = ConfigDict(
571
+ extra="forbid",
572
+ )
573
+ model: Literal["seedream-5-pro"]
574
+ input: CreateSeedream5ProInput
575
+ webhook_url: AnyUrl | None = Field(
576
+ None,
577
+ description="An https URL to POST a signed generation event to when it finishes",
578
+ )
579
+
580
+
581
+ class CreateSeedream5ProEditInput(BaseModel):
582
+ prompt: constr(min_length=3) = Field(
583
+ ...,
584
+ description="The change to make as one paragraph, at most 600 words, naming each image by its place in images (image 1, image 2), with the exact words the result must show written out.",
585
+ )
586
+ aspect_ratio: (
587
+ Literal[
588
+ "auto",
589
+ "1:1",
590
+ "21:9",
591
+ "16:9",
592
+ "3:2",
593
+ "4:3",
594
+ "5:4",
595
+ "4:5",
596
+ "3:4",
597
+ "2:3",
598
+ "9:16",
599
+ ]
600
+ | None
601
+ ) = Field("auto", description="Shape of the result as width:height, or auto to keep the shape the images suggest; auto when left out.")
602
+ resolution: Literal["1.5K", "2K"] | None = Field(
603
+ "2K",
604
+ description="Output resolution, 1.5K for drafts at half the price and 2K for finals; 2K when left out.",
605
+ )
606
+ output_format: Literal["png", "jpeg"] | None = Field(
607
+ "png", description="File format; png when left out."
608
+ )
609
+ images: list[str] = Field(
610
+ ...,
611
+ description="The images to edit or combine, in the order the prompt names them, at most 10, each an asset id (asset_…) or an https URL.",
612
+ max_length=10,
613
+ min_length=1,
614
+ )
615
+ name: constr(min_length=2, max_length=80) | None = Field(
616
+ None,
617
+ description="What the output is called in your library; made from the prompt when left out.",
618
+ )
619
+
620
+
621
+ class CreateSeedream5ProEdit(BaseModel):
622
+ model_config = ConfigDict(
623
+ extra="forbid",
624
+ )
625
+ model: Literal["seedream-5-pro/edit"]
626
+ input: CreateSeedream5ProEditInput
627
+ webhook_url: AnyUrl | None = Field(
628
+ None,
629
+ description="An https URL to POST a signed generation event to when it finishes",
630
+ )
631
+
632
+
633
+ class CreateSeedream5LiteInput(BaseModel):
634
+ prompt: constr(min_length=3) = Field(
635
+ ...,
636
+ description="Single-paragraph image prompt, at most 600 words, with the exact words the image must show written out.",
637
+ )
638
+ aspect_ratio: (
639
+ Literal["1:1", "21:9", "16:9", "3:2", "4:3", "5:4", "4:5", "3:4", "2:3", "9:16"]
640
+ | None
641
+ ) = Field("1:1", description="Shape of the image as width:height; 1:1 when left out.")
642
+ resolution: Literal["2K", "3K", "4K"] | None = Field(
643
+ "2K",
644
+ description="Output resolution, 2K, 3K or 4K, all at one price; 2K when left out.",
645
+ )
646
+ name: constr(min_length=2, max_length=80) | None = Field(
647
+ None,
648
+ description="What the output is called in your library; made from the prompt when left out.",
649
+ )
650
+
651
+
652
+ class CreateSeedream5Lite(BaseModel):
653
+ model_config = ConfigDict(
654
+ extra="forbid",
655
+ )
656
+ model: Literal["seedream-5-lite"]
657
+ input: CreateSeedream5LiteInput
658
+ webhook_url: AnyUrl | None = Field(
659
+ None,
660
+ description="An https URL to POST a signed generation event to when it finishes",
661
+ )
662
+
663
+
664
+ class CreateSeedream5LiteEditInput(BaseModel):
665
+ prompt: constr(min_length=3) = Field(
666
+ ...,
667
+ description="The change to make as one paragraph, at most 600 words, naming each image by its place in images (image 1, image 2), with the exact words the result must show written out.",
668
+ )
669
+ aspect_ratio: (
670
+ Literal[
671
+ "auto",
672
+ "1:1",
673
+ "21:9",
674
+ "16:9",
675
+ "3:2",
676
+ "4:3",
677
+ "5:4",
678
+ "4:5",
679
+ "3:4",
680
+ "2:3",
681
+ "9:16",
682
+ ]
683
+ | None
684
+ ) = Field("auto", description="Shape of the result as width:height, or auto to keep the shape the images suggest; auto when left out.")
685
+ resolution: Literal["2K", "3K", "4K"] | None = Field(
686
+ "2K",
687
+ description="Output resolution, 2K, 3K or 4K, all at one price; 2K when left out.",
688
+ )
689
+ images: list[str] = Field(
690
+ ...,
691
+ description="The images to edit or combine, in the order the prompt names them, at most 14, each an asset id (asset_…) or an https URL.",
692
+ max_length=14,
693
+ min_length=1,
694
+ )
695
+ name: constr(min_length=2, max_length=80) | None = Field(
696
+ None,
697
+ description="What the output is called in your library; made from the prompt when left out.",
698
+ )
699
+
700
+
701
+ class CreateSeedream5LiteEdit(BaseModel):
702
+ model_config = ConfigDict(
703
+ extra="forbid",
704
+ )
705
+ model: Literal["seedream-5-lite/edit"]
706
+ input: CreateSeedream5LiteEditInput
707
+ webhook_url: AnyUrl | None = Field(
708
+ None,
709
+ description="An https URL to POST a signed generation event to when it finishes",
710
+ )
711
+
712
+
713
+ class CreateSeedream5ProLayersInput(BaseModel):
714
+ image: str = Field(
715
+ ...,
716
+ description="The image to split into layers, as an asset id (asset_…) or an https URL.",
717
+ )
718
+ prompt: constr(min_length=3) | None = Field(
719
+ "Return name and description in english.",
720
+ description="One sentence on how to split, group or name the layers; asks for English names and descriptions when left out.",
721
+ )
722
+ resolution: Literal["1.5K", "2K"] | None = Field(
723
+ "2K",
724
+ description="Resolution of the layers, 1.5K for drafts and 2K for finals; 2K when left out.",
725
+ )
726
+ name: constr(min_length=2, max_length=80) | None = Field(
727
+ None,
728
+ description="What the output is called in your library; made from the prompt when left out.",
729
+ )
730
+
731
+
732
+ class CreateSeedream5ProLayers(BaseModel):
733
+ model_config = ConfigDict(
734
+ extra="forbid",
735
+ )
736
+ model: Literal["seedream-5-pro/layers"]
737
+ input: CreateSeedream5ProLayersInput
738
+ webhook_url: AnyUrl | None = Field(
739
+ None,
740
+ description="An https URL to POST a signed generation event to when it finishes",
741
+ )
742
+
743
+
744
+ class CreateTopazUpscaleInput(BaseModel):
745
+ image: str = Field(
746
+ ...,
747
+ description="The image to enlarge, as an asset id (asset_…) or an https URL.",
748
+ )
749
+ upscale_factor: confloat(ge=1.0, le=4.0) | None = Field(
750
+ 2,
751
+ description="How many times wider and taller the image comes out, from 1 to 4, so 2 makes four times the pixels; 2 when left out.",
752
+ )
753
+ preset: (
754
+ Literal["standard", "high_fidelity", "low_resolution", "cgi", "text"] | None
755
+ ) = Field("standard", description="standard suits most photos, high_fidelity keeps the fine detail of a professional shot, low_resolution recovers a small or compressed source, cgi suits renders and illustrations, and text keeps lettering and shapes crisp; standard when left out.")
756
+ face_enhancement: bool | None = Field(
757
+ True,
758
+ description="Whether faces get their detail recovered; true when left out, and false for a shot with no people in it.",
759
+ )
760
+ output_format: Literal["jpeg", "png"] | None = Field(
761
+ "jpeg",
762
+ description="jpeg is the smaller file and png keeps every pixel; jpeg when left out.",
763
+ )
764
+ name: constr(min_length=2, max_length=80) | None = Field(
765
+ None,
766
+ description="What the output is called in your library; made from the prompt when left out.",
767
+ )
768
+
769
+
770
+ class CreateTopazUpscale(BaseModel):
771
+ model_config = ConfigDict(
772
+ extra="forbid",
773
+ )
774
+ model: Literal["topaz/upscale"]
775
+ input: CreateTopazUpscaleInput
776
+ webhook_url: AnyUrl | None = Field(
777
+ None,
778
+ description="An https URL to POST a signed generation event to when it finishes",
779
+ )
780
+
781
+
782
+ class CreateSeedance25TextToVideoInput(BaseModel):
783
+ prompt: constr(min_length=3, max_length=50000) = Field(
784
+ ..., description="What happens in the clip."
785
+ )
786
+ aspect_ratio: (
787
+ Literal["auto", "21:9", "16:9", "4:3", "1:1", "3:4", "9:16"] | None
788
+ ) = Field("auto", description="Shape of the clip as width:height, or auto to let the model decide; auto when left out.")
789
+ draft: bool | None = Field(
790
+ False,
791
+ description="Whether to make a cheap 480p draft, whatever resolution says, that seedance-2.5/finish can finish at 1080p within 7 days; false when left out.",
792
+ )
793
+ duration: Literal["auto"] | conint(ge=4, le=30) | None = Field(
794
+ "auto",
795
+ description="Length in whole seconds from 4 to 30, or auto to let the model decide; auto when left out.",
796
+ )
797
+ resolution: Literal["480p", "720p", "1080p"] | None = Field(
798
+ "720p", description="Output resolution; 720p when left out."
799
+ )
800
+ generate_audio: bool | None = Field(
801
+ True,
802
+ description="Whether the clip gets sound, speech and music made for it; true when left out.",
803
+ )
804
+ codec: Literal["auto", "H264", "H265"] | None = Field(
805
+ "auto", description="Video codec; auto when left out."
806
+ )
807
+ bitrate_mode: Literal["standard", "high"] | None = Field(
808
+ "standard",
809
+ description="high asks for a larger, higher quality file; standard when left out.",
810
+ )
811
+ output_format: Literal["mp4", "mov"] | None = Field(
812
+ "mp4",
813
+ description="mp4 plays anywhere, mov keeps more color for grading; mp4 when left out.",
814
+ )
815
+ return_last_frame: bool | None = Field(
816
+ False,
817
+ description="Whether the last frame is also saved as an image, to start the next clip from; false when left out.",
818
+ )
819
+ name: constr(min_length=2, max_length=80) | None = Field(
820
+ None,
821
+ description="What the output is called in your library; made from the prompt when left out.",
822
+ )
823
+
824
+
825
+ class CreateSeedance25TextToVideo(BaseModel):
826
+ model_config = ConfigDict(
827
+ extra="forbid",
828
+ )
829
+ model: Literal["seedance-2.5/text-to-video"]
830
+ input: CreateSeedance25TextToVideoInput
831
+ webhook_url: AnyUrl | None = Field(
832
+ None,
833
+ description="An https URL to POST a signed generation event to when it finishes",
834
+ )
835
+
836
+
837
+ class CreateSeedance25ImageToVideoInput(BaseModel):
838
+ prompt: constr(min_length=3, max_length=50000) = Field(
839
+ ...,
840
+ description="What happens in the clip, from the start image to the end image when one is given.",
841
+ )
842
+ start_image: str = Field(
843
+ ...,
844
+ description="The image the clip opens on, as an asset id (asset_…) or an https URL; the clip takes its shape.",
845
+ )
846
+ end_image: str | None = Field(
847
+ None,
848
+ description="The image the clip ends on, as an asset id (asset_…) or an https URL; none when left out, so the model picks the ending.",
849
+ )
850
+ draft: bool | None = Field(
851
+ False,
852
+ description="Whether to make a cheap 480p draft, whatever resolution says, that seedance-2.5/finish can finish at 1080p within 7 days; false when left out.",
853
+ )
854
+ duration: Literal["auto"] | conint(ge=4, le=30) | None = Field(
855
+ "auto",
856
+ description="Length in whole seconds from 4 to 30, or auto to let the model decide; auto when left out.",
857
+ )
858
+ resolution: Literal["480p", "720p", "1080p"] | None = Field(
859
+ "720p", description="Output resolution; 720p when left out."
860
+ )
861
+ generate_audio: bool | None = Field(
862
+ True,
863
+ description="Whether the clip gets sound, speech and music made for it; true when left out.",
864
+ )
865
+ codec: Literal["auto", "H264", "H265"] | None = Field(
866
+ "auto", description="Video codec; auto when left out."
867
+ )
868
+ bitrate_mode: Literal["standard", "high"] | None = Field(
869
+ "standard",
870
+ description="high asks for a larger, higher quality file; standard when left out.",
871
+ )
872
+ output_format: Literal["mp4", "mov"] | None = Field(
873
+ "mp4",
874
+ description="mp4 plays anywhere, mov keeps more color for grading; mp4 when left out.",
875
+ )
876
+ return_last_frame: bool | None = Field(
877
+ False,
878
+ description="Whether the last frame is also saved as an image, to start the next clip from; false when left out.",
879
+ )
880
+ name: constr(min_length=2, max_length=80) | None = Field(
881
+ None,
882
+ description="What the output is called in your library; made from the prompt when left out.",
883
+ )
884
+
885
+
886
+ class CreateSeedance25ImageToVideo(BaseModel):
887
+ model_config = ConfigDict(
888
+ extra="forbid",
889
+ )
890
+ model: Literal["seedance-2.5/image-to-video"]
891
+ input: CreateSeedance25ImageToVideoInput
892
+ webhook_url: AnyUrl | None = Field(
893
+ None,
894
+ description="An https URL to POST a signed generation event to when it finishes",
895
+ )
896
+
897
+
898
+ class CreateSeedance25ReferenceToVideoInput(BaseModel):
899
+ prompt: constr(min_length=3, max_length=50000) = Field(
900
+ ...,
901
+ description="What happens in the clip, citing each image, video or audio by its place in its list as @Image1, @Video1 or @Audio1.",
902
+ )
903
+ task: Literal["auto", "reference", "editing", "extension"] | None = Field(
904
+ "auto",
905
+ description="reference makes a new clip from the references, editing changes the first of videos, extension continues it; auto when left out, which lets the model decide.",
906
+ )
907
+ images: list[str] | None = Field(
908
+ [],
909
+ description="Up to 30 images, each an asset id (asset_…) or an https URL; none when left out.",
910
+ max_length=30,
911
+ )
912
+ videos: list[str] | None = Field(
913
+ [],
914
+ description="Up to 10 videos, 30 seconds together at most, each an asset id (asset_…) or an https URL; none when left out.",
915
+ max_length=10,
916
+ )
917
+ audio: list[str] | None = Field(
918
+ [],
919
+ description="Up to 10 wav or mp3 files, 30 seconds together at most, each an asset id (asset_…) or an https URL; none when left out.",
920
+ max_length=10,
921
+ )
922
+ aspect_ratio: (
923
+ Literal["auto", "21:9", "16:9", "4:3", "1:1", "3:4", "9:16"] | None
924
+ ) = Field("auto", description="Shape of the clip as width:height, or auto to follow the references; auto when left out.")
925
+ seed: conint(ge=-9007199254740991, le=9007199254740991) | None = Field(
926
+ None,
927
+ description="Integer seed for a more repeatable take; random when left out.",
928
+ )
929
+ draft: bool | None = Field(
930
+ False,
931
+ description="Whether to make a cheap 480p draft, whatever resolution says, that seedance-2.5/finish can finish at 1080p within 7 days; false when left out.",
932
+ )
933
+ duration: Literal["auto"] | conint(ge=4, le=30) | None = Field(
934
+ "auto",
935
+ description="Length in whole seconds from 4 to 30, or auto to let the model decide; auto when left out.",
936
+ )
937
+ resolution: Literal["480p", "720p", "1080p"] | None = Field(
938
+ "720p", description="Output resolution; 720p when left out."
939
+ )
940
+ generate_audio: bool | None = Field(
941
+ True,
942
+ description="Whether the clip gets sound, speech and music made for it; true when left out.",
943
+ )
944
+ codec: Literal["auto", "H264", "H265"] | None = Field(
945
+ "auto", description="Video codec; auto when left out."
946
+ )
947
+ bitrate_mode: Literal["standard", "high"] | None = Field(
948
+ "standard",
949
+ description="high asks for a larger, higher quality file; standard when left out.",
950
+ )
951
+ output_format: Literal["mp4", "mov"] | None = Field(
952
+ "mp4",
953
+ description="mp4 plays anywhere, mov keeps more color for grading; mp4 when left out.",
954
+ )
955
+ return_last_frame: bool | None = Field(
956
+ False,
957
+ description="Whether the last frame is also saved as an image, to start the next clip from; false when left out.",
958
+ )
959
+ name: constr(min_length=2, max_length=80) | None = Field(
960
+ None,
961
+ description="What the output is called in your library; made from the prompt when left out.",
962
+ )
963
+
964
+
965
+ class CreateSeedance25ReferenceToVideo(BaseModel):
966
+ model_config = ConfigDict(
967
+ extra="forbid",
968
+ )
969
+ model: Literal["seedance-2.5/reference-to-video"]
970
+ input: CreateSeedance25ReferenceToVideoInput
971
+ webhook_url: AnyUrl | None = Field(
972
+ None,
973
+ description="An https URL to POST a signed generation event to when it finishes",
974
+ )
975
+
976
+
977
+ class CreateSeedance25FinishInput(BaseModel):
978
+ draft: constr(max_length=42) = Field(
979
+ ...,
980
+ description="The draft to finish: the asset id of a Seedance 2.5 clip made with draft set to true.",
981
+ )
982
+ name: constr(min_length=2, max_length=80) | None = Field(
983
+ None,
984
+ description="What the output is called in your library; made from the prompt when left out.",
985
+ )
986
+
987
+
988
+ class CreateSeedance25Finish(BaseModel):
989
+ model_config = ConfigDict(
990
+ extra="forbid",
991
+ )
992
+ model: Literal["seedance-2.5/finish"]
993
+ input: CreateSeedance25FinishInput
994
+ webhook_url: AnyUrl | None = Field(
995
+ None,
996
+ description="An https URL to POST a signed generation event to when it finishes",
997
+ )
998
+
999
+
1000
+ class CreateKling3ProImageToVideoInputMultiPromptItem(BaseModel):
1001
+ prompt: constr(min_length=3, max_length=2500) = Field(
1002
+ ..., description="What happens in this shot."
1003
+ )
1004
+ duration: conint(ge=1, le=15) | None = Field(
1005
+ 5,
1006
+ description="Length of this shot in whole seconds from 1 to 15; 5 when left out.",
1007
+ )
1008
+
1009
+
1010
+ class CreateKling3ProImageToVideoInput(BaseModel):
1011
+ prompt: constr(min_length=3, max_length=2500) | None = Field(
1012
+ None,
1013
+ description="What happens in the clip, up to 2500 characters; leave it out when multi_prompt gives the shots instead.",
1014
+ )
1015
+ multi_prompt: list[CreateKling3ProImageToVideoInputMultiPromptItem] | None = Field(
1016
+ None,
1017
+ description="Shots cut end to end in one clip, in order, which together run 3 to 15 seconds; in place of prompt and duration, and none when left out.",
1018
+ min_length=1,
1019
+ )
1020
+ start_image: str = Field(
1021
+ ...,
1022
+ description="The image the clip opens on, as an asset id (asset_…) or an https URL.",
1023
+ )
1024
+ end_image: str | None = Field(
1025
+ None,
1026
+ description="The image the clip ends on, as an asset id (asset_…) or an https URL; none when left out, so the model picks the ending.",
1027
+ )
1028
+ negative_prompt: constr(min_length=1, max_length=2500) | None = Field(
1029
+ None,
1030
+ description='What the clip must not show, such as "lens flare, morphing faces"; Kling\'s own "blur, distort, and low quality" when left out.',
1031
+ )
1032
+ cfg_scale: confloat(ge=0.0, le=1.0) | None = Field(
1033
+ 0.5,
1034
+ description="How closely the clip keeps to the prompt, from 0 to 1; 0.5 when left out.",
1035
+ )
1036
+ duration: conint(ge=3, le=15) | None = Field(
1037
+ None,
1038
+ description="Length in whole seconds from 3 to 15; 5 when left out, and left out with multi_prompt, whose shot lengths add up to the clip's.",
1039
+ )
1040
+ generate_audio: bool | None = Field(
1041
+ True,
1042
+ description="Whether the clip gets sound and speech made for it; true when left out.",
1043
+ )
1044
+ shot_type: Literal["customize", "intelligent"] | None = Field(
1045
+ "customize",
1046
+ description="customize cuts multi_prompt shots as written, intelligent lets Kling decide the shot structure; customize when left out.",
1047
+ )
1048
+ name: constr(min_length=2, max_length=80) | None = Field(
1049
+ None,
1050
+ description="What the output is called in your library; made from the prompt when left out.",
1051
+ )
1052
+
1053
+
1054
+ class CreateKling3ProImageToVideo(BaseModel):
1055
+ model_config = ConfigDict(
1056
+ extra="forbid",
1057
+ )
1058
+ model: Literal["kling-3-pro/image-to-video"]
1059
+ input: CreateKling3ProImageToVideoInput
1060
+ webhook_url: AnyUrl | None = Field(
1061
+ None,
1062
+ description="An https URL to POST a signed generation event to when it finishes",
1063
+ )
1064
+
1065
+
1066
+ class CreateKlingO3ProReferenceToVideoInputMultiPromptItem(BaseModel):
1067
+ prompt: constr(min_length=3, max_length=2500) = Field(
1068
+ ..., description="What happens in this shot."
1069
+ )
1070
+ duration: conint(ge=1, le=15) | None = Field(
1071
+ 5,
1072
+ description="Length of this shot in whole seconds from 1 to 15; 5 when left out.",
1073
+ )
1074
+
1075
+
1076
+ class CreateKlingO3ProReferenceToVideoInputElements(BaseModel):
1077
+ model_config = ConfigDict(
1078
+ extra="forbid",
1079
+ )
1080
+ frontal_image: str = Field(
1081
+ ...,
1082
+ description="A front view of the character or object, as an asset id (asset_…) or an https URL.",
1083
+ )
1084
+ reference_images: list[str] = Field(
1085
+ ...,
1086
+ description="1 to 3 more views of the same character or object, from other angles, each an asset id (asset_…) or an https URL.",
1087
+ max_length=3,
1088
+ min_length=1,
1089
+ )
1090
+
1091
+
1092
+ class CreateKlingO3ProReferenceToVideoInputElements1(BaseModel):
1093
+ model_config = ConfigDict(
1094
+ extra="forbid",
1095
+ )
1096
+ video: str = Field(
1097
+ ...,
1098
+ description="A clip of the character or object, 3 to 10 seconds at 720 to 2160 px a side, as an asset id (asset_…) or an https URL, in place of images.",
1099
+ )
1100
+
1101
+
1102
+ class CreateKlingO3ProReferenceToVideoInput(BaseModel):
1103
+ prompt: constr(min_length=3, max_length=2500) | None = Field(
1104
+ None,
1105
+ description="What happens in the clip, up to 2500 characters; leave it out when multi_prompt gives the shots instead.",
1106
+ )
1107
+ multi_prompt: list[CreateKlingO3ProReferenceToVideoInputMultiPromptItem] | None = (
1108
+ Field(
1109
+ None,
1110
+ description="Shots cut end to end in one clip, in order, which together run 3 to 15 seconds; in place of prompt and duration, and none when left out.",
1111
+ min_length=1,
1112
+ )
1113
+ )
1114
+ start_image: str | None = Field(
1115
+ None,
1116
+ description="The image the clip opens on, as an asset id (asset_…) or an https URL; none when left out, so the model composes the opening from the prompt and the references.",
1117
+ )
1118
+ end_image: str | None = Field(
1119
+ None,
1120
+ description="The image the clip ends on, as an asset id (asset_…) or an https URL; none when left out, so the model picks the ending.",
1121
+ )
1122
+ images: list[str] | None = Field(
1123
+ [],
1124
+ description="Up to 4 images whose subject or look the clip keeps, each an asset id (asset_…) or an https URL, cited in the prompt as @Image1, @Image2 in this order; none when left out.",
1125
+ max_length=4,
1126
+ )
1127
+ elements: (
1128
+ list[
1129
+ CreateKlingO3ProReferenceToVideoInputElements | CreateKlingO3ProReferenceToVideoInputElements1
1130
+ ]
1131
+ | None
1132
+ ) = Field([], description="Characters or objects held to one look across the clip, cited in the prompt as @Element1, @Element2 in this order; images and elements take 4 together at most, and none when left out.", max_length=4, validate_default=True)
1133
+ aspect_ratio: Literal["16:9", "9:16", "1:1"] | None = Field(
1134
+ "16:9", description="Shape of the clip as width:height; 16:9 when left out."
1135
+ )
1136
+ duration: conint(ge=3, le=15) | None = Field(
1137
+ None,
1138
+ description="Length in whole seconds from 3 to 15; 5 when left out, and left out with multi_prompt, whose shot lengths add up to the clip's.",
1139
+ )
1140
+ generate_audio: bool | None = Field(
1141
+ True,
1142
+ description="Whether the clip gets sound and speech made for it; true when left out.",
1143
+ )
1144
+ shot_type: Literal["customize", "intelligent"] | None = Field(
1145
+ "customize",
1146
+ description="customize cuts multi_prompt shots as written, intelligent lets Kling decide the shot structure; customize when left out.",
1147
+ )
1148
+ name: constr(min_length=2, max_length=80) | None = Field(
1149
+ None,
1150
+ description="What the output is called in your library; made from the prompt when left out.",
1151
+ )
1152
+
1153
+
1154
+ class CreateKlingO3ProReferenceToVideo(BaseModel):
1155
+ model_config = ConfigDict(
1156
+ extra="forbid",
1157
+ )
1158
+ model: Literal["kling-o3-pro/reference-to-video"]
1159
+ input: CreateKlingO3ProReferenceToVideoInput
1160
+ webhook_url: AnyUrl | None = Field(
1161
+ None,
1162
+ description="An https URL to POST a signed generation event to when it finishes",
1163
+ )
1164
+
1165
+
1166
+ class CreateGeminiOmniFlashTextToVideoInput(BaseModel):
1167
+ prompt: constr(min_length=3, max_length=20000) = Field(
1168
+ ...,
1169
+ description="What happens in the clip, with any spoken line in double quotes.",
1170
+ )
1171
+ aspect_ratio: Literal["9:16", "16:9"] | None = Field(
1172
+ "9:16",
1173
+ description="Shape of the clip, portrait 9:16 or landscape 16:9; 9:16 when left out.",
1174
+ )
1175
+ duration: conint(ge=3, le=10) | None = Field(
1176
+ 8, description="Length in whole seconds from 3 to 10; 8 when left out."
1177
+ )
1178
+ resolution: Literal["360p", "720p", "1080p", "4k"] | None = Field(
1179
+ "720p",
1180
+ description="Output resolution, 360p for a cheap draft up to 4k, and the price per second rises with it; 720p when left out.",
1181
+ )
1182
+ name: constr(min_length=2, max_length=80) | None = Field(
1183
+ None,
1184
+ description="What the output is called in your library; made from the prompt when left out.",
1185
+ )
1186
+
1187
+
1188
+ class CreateGeminiOmniFlashTextToVideo(BaseModel):
1189
+ model_config = ConfigDict(
1190
+ extra="forbid",
1191
+ )
1192
+ model: Literal["gemini-omni-flash/text-to-video"]
1193
+ input: CreateGeminiOmniFlashTextToVideoInput
1194
+ webhook_url: AnyUrl | None = Field(
1195
+ None,
1196
+ description="An https URL to POST a signed generation event to when it finishes",
1197
+ )
1198
+
1199
+
1200
+ class CreateGeminiOmniFlashImageToVideoInput(BaseModel):
1201
+ prompt: constr(min_length=3, max_length=20000) = Field(
1202
+ ...,
1203
+ description="How the image comes to life, up to the end image when one is given, with any spoken line in double quotes.",
1204
+ )
1205
+ start_image: str = Field(
1206
+ ...,
1207
+ description="The image the clip opens on, as an asset id (asset_…) or an https URL.",
1208
+ )
1209
+ end_image: str | None = Field(
1210
+ None,
1211
+ description="The image the clip ends on, as an asset id (asset_…) or an https URL; none when left out, so the model picks the ending.",
1212
+ )
1213
+ aspect_ratio: Literal["9:16", "16:9"] | None = Field(
1214
+ "9:16",
1215
+ description="Shape of the clip, portrait 9:16 or landscape 16:9; 9:16 when left out.",
1216
+ )
1217
+ duration: conint(ge=3, le=10) | None = Field(
1218
+ 8, description="Length in whole seconds from 3 to 10; 8 when left out."
1219
+ )
1220
+ resolution: Literal["360p", "720p", "1080p", "4k"] | None = Field(
1221
+ "720p",
1222
+ description="Output resolution, 360p for a cheap draft up to 4k, and the price per second rises with it; 720p when left out.",
1223
+ )
1224
+ name: constr(min_length=2, max_length=80) | None = Field(
1225
+ None,
1226
+ description="What the output is called in your library; made from the prompt when left out.",
1227
+ )
1228
+
1229
+
1230
+ class CreateGeminiOmniFlashImageToVideo(BaseModel):
1231
+ model_config = ConfigDict(
1232
+ extra="forbid",
1233
+ )
1234
+ model: Literal["gemini-omni-flash/image-to-video"]
1235
+ input: CreateGeminiOmniFlashImageToVideoInput
1236
+ webhook_url: AnyUrl | None = Field(
1237
+ None,
1238
+ description="An https URL to POST a signed generation event to when it finishes",
1239
+ )
1240
+
1241
+
1242
+ class CreateGeminiOmniFlashReferenceToVideoInput(BaseModel):
1243
+ prompt: constr(min_length=3, max_length=20000) = Field(
1244
+ ...,
1245
+ description="What happens in the clip, citing each image or video inline by its place in its list from 0, as <IMAGE_REF_0> or <VIDEO_REF_0>, with any spoken line in double quotes.",
1246
+ )
1247
+ images: list[str] | None = Field(
1248
+ [],
1249
+ description="Up to 10 images of the faces, products or places to keep, each an asset id (asset_…) or an https URL; none when left out.",
1250
+ max_length=10,
1251
+ )
1252
+ videos: list[str] | None = Field(
1253
+ [],
1254
+ description="Up to 3 videos, each shorter than 3 seconds, for a likeness or a motion to copy, whose sound is ignored, each an asset id (asset_…) or an https URL; none when left out.",
1255
+ max_length=3,
1256
+ )
1257
+ aspect_ratio: Literal["9:16", "16:9"] | None = Field(
1258
+ "9:16",
1259
+ description="Shape of the clip, portrait 9:16 or landscape 16:9; 9:16 when left out.",
1260
+ )
1261
+ duration: conint(ge=3, le=10) | None = Field(
1262
+ 8, description="Length in whole seconds from 3 to 10; 8 when left out."
1263
+ )
1264
+ resolution: Literal["360p", "720p", "1080p", "4k"] | None = Field(
1265
+ "720p",
1266
+ description="Output resolution, 360p for a cheap draft up to 4k, and the price per second rises with it; 720p when left out.",
1267
+ )
1268
+ name: constr(min_length=2, max_length=80) | None = Field(
1269
+ None,
1270
+ description="What the output is called in your library; made from the prompt when left out.",
1271
+ )
1272
+
1273
+
1274
+ class CreateGeminiOmniFlashReferenceToVideo(BaseModel):
1275
+ model_config = ConfigDict(
1276
+ extra="forbid",
1277
+ )
1278
+ model: Literal["gemini-omni-flash/reference-to-video"]
1279
+ input: CreateGeminiOmniFlashReferenceToVideoInput
1280
+ webhook_url: AnyUrl | None = Field(
1281
+ None,
1282
+ description="An https URL to POST a signed generation event to when it finishes",
1283
+ )
1284
+
1285
+
1286
+ class CreateGeminiOmniFlashEditInput(BaseModel):
1287
+ prompt: constr(min_length=3, max_length=20000) = Field(
1288
+ ...,
1289
+ description='One simple change to make, ending with "Keep everything else the same." to hold the rest of the scene.',
1290
+ )
1291
+ video: str = Field(
1292
+ ...,
1293
+ description="The video to edit, 10 seconds or shorter, as an asset id (asset_…) or an https URL.",
1294
+ )
1295
+ resolution: Literal["360p", "720p", "1080p", "4k"] | None = Field(
1296
+ None,
1297
+ description="Output resolution; the source video's own when left out, so set it only to step the clip up or down.",
1298
+ )
1299
+ name: constr(min_length=2, max_length=80) | None = Field(
1300
+ None,
1301
+ description="What the output is called in your library; made from the prompt when left out.",
1302
+ )
1303
+
1304
+
1305
+ class CreateGeminiOmniFlashEdit(BaseModel):
1306
+ model_config = ConfigDict(
1307
+ extra="forbid",
1308
+ )
1309
+ model: Literal["gemini-omni-flash/edit"]
1310
+ input: CreateGeminiOmniFlashEditInput
1311
+ webhook_url: AnyUrl | None = Field(
1312
+ None,
1313
+ description="An https URL to POST a signed generation event to when it finishes",
1314
+ )
1315
+
1316
+
1317
+ class CreateSync3LipsyncInput(BaseModel):
1318
+ video: str = Field(
1319
+ ...,
1320
+ description="The video to re-sync, as an asset id (asset_…) or an https URL, showing one clear, front-facing speaker.",
1321
+ )
1322
+ audio: str = Field(
1323
+ ...,
1324
+ description="The speech the lips follow, as an asset id (asset_…) or an https URL: a new voiceover, a dub, or the clip's own track saved as audio.",
1325
+ )
1326
+ sync_mode: Literal["cut_off", "loop", "bounce", "silence", "remap"] | None = Field(
1327
+ "cut_off",
1328
+ description="What happens when the audio and the video differ in length: cut_off ends the clip at the shorter one, loop and bounce replay the video, from the start or forward then back, until the audio ends, silence keeps the longer one with silence after the audio, and remap retimes the video to the audio; cut_off when left out.",
1329
+ )
1330
+ name: constr(min_length=2, max_length=80) | None = Field(
1331
+ None,
1332
+ description="What the output is called in your library; made from the prompt when left out.",
1333
+ )
1334
+
1335
+
1336
+ class CreateSync3Lipsync(BaseModel):
1337
+ model_config = ConfigDict(
1338
+ extra="forbid",
1339
+ )
1340
+ model: Literal["sync-3/lipsync"]
1341
+ input: CreateSync3LipsyncInput
1342
+ webhook_url: AnyUrl | None = Field(
1343
+ None,
1344
+ description="An https URL to POST a signed generation event to when it finishes",
1345
+ )
1346
+
1347
+
1348
+ class CreateElevenlabsVoiceoverInput(BaseModel):
1349
+ text: constr(min_length=1, max_length=5000) = Field(
1350
+ ...,
1351
+ description="The script to read aloud, up to 5000 characters, written as it should sound: inline audio tags in square brackets direct the delivery, such as [whispering], [laughs], [excited], [pause] or [door slams], and a word in IPA between slashes, such as /ˈnaɪki/, fixes its pronunciation.",
1352
+ )
1353
+ voice: constr(min_length=1, max_length=64) | None = Field(
1354
+ "Jessica",
1355
+ description="The voice that reads the script: a premade voice name, or a voice id from GET /v1/voices; Jessica when left out.",
1356
+ )
1357
+ stability: Literal["creative", "natural", "robust"] | None = Field(
1358
+ "natural",
1359
+ description="creative varies the delivery most and robust keeps it steadiest; natural when left out.",
1360
+ )
1361
+ similarity_boost: confloat(ge=0.0, le=1.0) | None = Field(
1362
+ 0.75,
1363
+ description="How closely the speech holds to the voice, from 0 to 1; high values can carry the quirks of its source recording, and 0.75 when left out.",
1364
+ )
1365
+ language_code: constr(pattern=r"^[a-z]{2}$") | None = Field(
1366
+ None,
1367
+ description="The language to speak in, as a two-letter ISO 639-1 code such as en, pt or es; read from the script when left out.",
1368
+ )
1369
+ name: constr(min_length=2, max_length=80) | None = Field(
1370
+ None,
1371
+ description="What the output is called in your library; made from the prompt when left out.",
1372
+ )
1373
+
1374
+
1375
+ class CreateElevenlabsVoiceover(BaseModel):
1376
+ model_config = ConfigDict(
1377
+ extra="forbid",
1378
+ )
1379
+ model: Literal["elevenlabs/voiceover"]
1380
+ input: CreateElevenlabsVoiceoverInput
1381
+ webhook_url: AnyUrl | None = Field(
1382
+ None,
1383
+ description="An https URL to POST a signed generation event to when it finishes",
1384
+ )
1385
+
1386
+
1387
+ class CreateElevenlabsMusicInput(BaseModel):
1388
+ prompt: constr(min_length=3, max_length=4100) = Field(
1389
+ ...,
1390
+ description="The track: genre, mood, instruments, tempo, and any lyrics or vocal style, up to 4100 characters.",
1391
+ )
1392
+ duration: Literal["auto"] | conint(ge=3, le=600) | None = Field(
1393
+ "auto",
1394
+ description="Length in whole seconds from 3 to 600, or auto to let the model decide; auto when left out.",
1395
+ )
1396
+ force_instrumental: bool | None = Field(
1397
+ False,
1398
+ description="true guarantees a track with no vocals; false when left out.",
1399
+ )
1400
+ name: constr(min_length=2, max_length=80) | None = Field(
1401
+ None,
1402
+ description="What the output is called in your library; made from the prompt when left out.",
1403
+ )
1404
+
1405
+
1406
+ class CreateElevenlabsMusic(BaseModel):
1407
+ model_config = ConfigDict(
1408
+ extra="forbid",
1409
+ )
1410
+ model: Literal["elevenlabs/music"]
1411
+ input: CreateElevenlabsMusicInput
1412
+ webhook_url: AnyUrl | None = Field(
1413
+ None,
1414
+ description="An https URL to POST a signed generation event to when it finishes",
1415
+ )
1416
+
1417
+
1418
+ class CreateElevenlabsSoundEffectsInput(BaseModel):
1419
+ prompt: constr(min_length=3, max_length=450) = Field(
1420
+ ...,
1421
+ description='The sound in plain words, such as "glass shattering on a tile floor", up to 450 characters.',
1422
+ )
1423
+ duration: Literal["auto"] | confloat(ge=0.5, le=22.0) | None = Field(
1424
+ "auto",
1425
+ description="Length in seconds from 0.5 to 22, or auto to fit the sound; auto when left out.",
1426
+ )
1427
+ prompt_influence: confloat(ge=0.0, le=1.0) | None = Field(
1428
+ 0.3,
1429
+ description="How closely the sound follows the prompt, from 0 to 1; 0.3 when left out.",
1430
+ )
1431
+ loop: bool | None = Field(
1432
+ False,
1433
+ description="Whether the sound loops seamlessly end to start; false when left out.",
1434
+ )
1435
+ name: constr(min_length=2, max_length=80) | None = Field(
1436
+ None,
1437
+ description="What the output is called in your library; made from the prompt when left out.",
1438
+ )
1439
+
1440
+
1441
+ class CreateElevenlabsSoundEffects(BaseModel):
1442
+ model_config = ConfigDict(
1443
+ extra="forbid",
1444
+ )
1445
+ model: Literal["elevenlabs/sound-effects"]
1446
+ input: CreateElevenlabsSoundEffectsInput
1447
+ webhook_url: AnyUrl | None = Field(
1448
+ None,
1449
+ description="An https URL to POST a signed generation event to when it finishes",
1450
+ )
1451
+
1452
+
1453
+ class CreateElevenlabsVoiceChangerInput(BaseModel):
1454
+ audio: str = Field(
1455
+ ...,
1456
+ description="The recording to re-voice, as an asset id (asset_…) or an https URL, at most 5 minutes; clean single-speaker audio works best.",
1457
+ )
1458
+ voice: constr(pattern=r"^[A-Za-z0-9]{20}$") = Field(
1459
+ ...,
1460
+ description="The voice id the recording is re-voiced into, from GET /v1/voices.",
1461
+ )
1462
+ remove_background_noise: bool | None = Field(
1463
+ False,
1464
+ description="Whether to strip background noise from the recording first; only for a noisy source, since it can hurt a clean one; false when left out.",
1465
+ )
1466
+ name: constr(min_length=2, max_length=80) | None = Field(
1467
+ None,
1468
+ description="What the output is called in your library; made from the prompt when left out.",
1469
+ )
1470
+
1471
+
1472
+ class CreateElevenlabsVoiceChanger(BaseModel):
1473
+ model_config = ConfigDict(
1474
+ extra="forbid",
1475
+ )
1476
+ model: Literal["elevenlabs/voice-changer"]
1477
+ input: CreateElevenlabsVoiceChangerInput
1478
+ webhook_url: AnyUrl | None = Field(
1479
+ None,
1480
+ description="An https URL to POST a signed generation event to when it finishes",
1481
+ )
1482
+
1483
+
1484
+ class CreateElevenlabsVoiceIsolatorInput(BaseModel):
1485
+ audio: str = Field(
1486
+ ...,
1487
+ description="The audio to isolate the voice in, as an asset id (asset_…) or an https URL.",
1488
+ )
1489
+ name: constr(min_length=2, max_length=80) | None = Field(
1490
+ None,
1491
+ description="What the output is called in your library; made from the prompt when left out.",
1492
+ )
1493
+
1494
+
1495
+ class CreateElevenlabsVoiceIsolator(BaseModel):
1496
+ model_config = ConfigDict(
1497
+ extra="forbid",
1498
+ )
1499
+ model: Literal["elevenlabs/voice-isolator"]
1500
+ input: CreateElevenlabsVoiceIsolatorInput
1501
+ webhook_url: AnyUrl | None = Field(
1502
+ None,
1503
+ description="An https URL to POST a signed generation event to when it finishes",
1504
+ )
1505
+
1506
+
1507
+ class CreateMinimaxMusicInput(BaseModel):
1508
+ prompt: constr(min_length=10, max_length=2000) = Field(
1509
+ ...,
1510
+ description="The style of the track: genre, mood, instruments, tempo and where it plays, from 10 to 2000 characters.",
1511
+ )
1512
+ lyrics: Literal["auto"] | constr(max_length=3500) | None = Field(
1513
+ None,
1514
+ description="The words to sing, a line per line with tags such as [Verse], [Chorus] and [Bridge], up to 3500 characters, or auto to have MiniMax write them from the prompt; none when left out or empty, which makes an instrumental.",
1515
+ )
1516
+ name: constr(min_length=2, max_length=80) | None = Field(
1517
+ None,
1518
+ description="What the output is called in your library; made from the prompt when left out.",
1519
+ )
1520
+
1521
+
1522
+ class CreateMinimaxMusic(BaseModel):
1523
+ model_config = ConfigDict(
1524
+ extra="forbid",
1525
+ )
1526
+ model: Literal["minimax/music"]
1527
+ input: CreateMinimaxMusicInput
1528
+ webhook_url: AnyUrl | None = Field(
1529
+ None,
1530
+ description="An https URL to POST a signed generation event to when it finishes",
1531
+ )
1532
+
1533
+
1534
+ class CreateSoniloMusicInput(BaseModel):
1535
+ prompt: constr(min_length=1) = Field(
1536
+ ...,
1537
+ description="The track: genre, mood, instruments, tempo and where it plays.",
1538
+ )
1539
+ duration: conint(ge=1, le=600) = Field(
1540
+ ...,
1541
+ description="Length in whole seconds from 1 to 600; the track runs exactly this long.",
1542
+ )
1543
+ name: constr(min_length=2, max_length=80) | None = Field(
1544
+ None,
1545
+ description="What the output is called in your library; made from the prompt when left out.",
1546
+ )
1547
+
1548
+
1549
+ class CreateSoniloMusic(BaseModel):
1550
+ model_config = ConfigDict(
1551
+ extra="forbid",
1552
+ )
1553
+ model: Literal["sonilo/music"]
1554
+ input: CreateSoniloMusicInput
1555
+ webhook_url: AnyUrl | None = Field(
1556
+ None,
1557
+ description="An https URL to POST a signed generation event to when it finishes",
1558
+ )
1559
+
1560
+
1561
+ class GenerationOutputItemLayer(BaseModel):
1562
+ name: str | None
1563
+ description: str | None
1564
+ x: float
1565
+ y: float
1566
+ width: float
1567
+ height: float
1568
+ z_index: float
1569
+
1570
+
1571
+ class GenerationOutputItem(BaseModel):
1572
+ id: str
1573
+ object: Literal["asset"]
1574
+ type: Literal["image", "video", "audio"]
1575
+ name: str | None
1576
+ url: str
1577
+ content_type: str
1578
+ width: float | None = None
1579
+ height: float | None = None
1580
+ duration: float | None = None
1581
+ role: Literal["main", "last_frame", "layer"]
1582
+ layer: GenerationOutputItemLayer | None = None
1583
+
1584
+
1585
+ class GenerationError(BaseModel):
1586
+ code: Literal["invalid_input", "insufficient_credits", "generation_failed"]
1587
+ message: str
1588
+
1589
+
1590
+ class Generation(BaseModel):
1591
+ id: str = Field(..., examples=["gen_6c1f0e9a7b2d4c55a1e3f08b9d2c4e71"])
1592
+ object: Literal["generation"]
1593
+ model: str
1594
+ status: Literal["queued", "running", "succeeded", "failed", "canceled"] = (
1595
+ Field(
1596
+ ..., description="queued, then running, then succeeded, failed or canceled"
1597
+ )
1598
+ )
1599
+ output: list[GenerationOutputItem] = Field(
1600
+ ...,
1601
+ description="What it made, saved to your library; the main file comes first",
1602
+ )
1603
+ error: GenerationError | None = Field(
1604
+ ..., description="Why it failed; failed generations are free"
1605
+ )
1606
+ credits: float | None = Field(
1607
+ ..., description="What it was charged, in credits of $0.05, once it finished"
1608
+ )
1609
+ created_at: str
1610
+ started_at: str | None
1611
+ completed_at: str | None
1612
+
1613
+
1614
+ class ModelPricingRate(BaseModel):
1615
+ unit: str = Field(
1616
+ ...,
1617
+ description="What one rate is for: an image, a second, a minute, a character, a request or a token",
1618
+ )
1619
+ usd: float
1620
+ when: dict[str, Any] = Field(
1621
+ ...,
1622
+ description="The input settings the rate applies to; empty when it applies to all",
1623
+ )
1624
+
1625
+
1626
+ class ModelPricing(BaseModel):
1627
+ rates: list[ModelPricingRate]
1628
+
1629
+
1630
+ class Model(BaseModel):
1631
+ id: str
1632
+ object: Literal["model"]
1633
+ name: str
1634
+ type: Literal["image", "video", "audio"]
1635
+ task: str
1636
+ summary: str
1637
+ pricing: ModelPricing = Field(
1638
+ ...,
1639
+ description="What a generation costs per unit, in USD. A generation is charged in credits of $0.05, rounded up, and only when it succeeds.",
1640
+ )
1641
+ input_schema: dict[str, Any] = Field(..., description="The JSON Schema of `input`")
1642
+
1643
+
1644
+ class ErrorError(BaseModel):
1645
+ type: Literal["invalid_request_error", "authentication_error", "permission_error", "not_found_error", "billing_error", "rate_limit_error", "api_error"]
1646
+ code: str = Field(
1647
+ ...,
1648
+ description="A stable code to branch on, such as invalid_input or insufficient_credits",
1649
+ )
1650
+ message: str = Field(..., description="What went wrong and how to fix it")
1651
+ param: str | None = Field(
1652
+ None, description="The part of the request at fault, such as input.prompt"
1653
+ )
1654
+ request_id: str
1655
+
1656
+
1657
+ class Error(BaseModel):
1658
+ error: ErrorError
1659
+
1660
+
1661
+ class GenerationList(BaseModel):
1662
+ object: Literal["list"]
1663
+ data: list[Generation]
1664
+ has_more: bool
1665
+ next_cursor: str | None = Field(
1666
+ ..., description="Pass as `cursor` for the next page"
1667
+ )
1668
+
1669
+
1670
+ class LibraryAsset(BaseModel):
1671
+ id: str
1672
+ object: Literal["asset"]
1673
+ type: Literal["image", "video", "audio", "file"]
1674
+ name: str | None
1675
+ url: str | None
1676
+ content_type: str | None
1677
+ width: float | None = None
1678
+ height: float | None = None
1679
+ duration: float | None = None
1680
+ caption: str | None = Field(
1681
+ ..., description="What the image shows, when it has been described"
1682
+ )
1683
+ liked: bool
1684
+ offer: str | None = Field(
1685
+ ..., description="The offer the file is a photo of, offer_…"
1686
+ )
1687
+ created_at: str
1688
+
1689
+
1690
+ class Asset(BaseModel):
1691
+ id: str
1692
+ object: Literal["asset"]
1693
+ type: Literal["image", "video", "audio", "file"]
1694
+ name: str | None
1695
+ url: str | None
1696
+ content_type: str | None
1697
+ width: float | None = None
1698
+ height: float | None = None
1699
+ duration: float | None = None
1700
+
1701
+
1702
+ class BrandRule(BaseModel):
1703
+ kind: Literal["preference", "taboo"]
1704
+ text: str
1705
+
1706
+
1707
+ class BrandColor(BaseModel):
1708
+ hex: str
1709
+ role: str | None
1710
+ name: str | None
1711
+
1712
+
1713
+ class BrandTypographyItem(BaseModel):
1714
+ role: str = Field(
1715
+ ..., description="heading1 to heading4, body, cta, link or overline"
1716
+ )
1717
+ font_family: str | None
1718
+ font_size: str | None
1719
+ font_weight: str | None
1720
+ letter_spacing: str | None
1721
+ text_transform: str | None
1722
+
1723
+
1724
+ class BrandButton(BaseModel):
1725
+ text: str
1726
+ color: str | None
1727
+ background_color: str | None
1728
+ border_radius: str | None
1729
+ font_family: str | None
1730
+ font_size: str | None
1731
+ font_weight: str | None
1732
+
1733
+
1734
+ class BrandFontFile(BaseModel):
1735
+ weight: str
1736
+ style: str
1737
+ url: str
1738
+
1739
+
1740
+ class BrandFont(BaseModel):
1741
+ family: str
1742
+ headings: bool
1743
+ body: bool
1744
+ files: list[BrandFontFile]
1745
+
1746
+
1747
+ class BrandLogo(BaseModel):
1748
+ id: str = Field(..., description="An asset id, usable as a media input")
1749
+ variant: Literal["icon", "light", "dark"] = Field(
1750
+ ...,
1751
+ description="icon for a small mark, light for dark backgrounds, dark for light ones",
1752
+ )
1753
+ format: str | None
1754
+ width: float | None
1755
+ height: float | None
1756
+ url: str | None
1757
+
1758
+
1759
+ class Brand(BaseModel):
1760
+ object: Literal["brand"]
1761
+ id: UUID = Field(
1762
+ ...,
1763
+ description="Send it as `Sandstorm-Brand` to work on this brand with a key made on another",
1764
+ )
1765
+ name: str
1766
+ summary: str | None
1767
+ voice: str | None = Field(..., description="How the brand sounds, by surface")
1768
+ audience: str | None
1769
+ positioning: str | None
1770
+ preferences: str | None = Field(
1771
+ ..., description="Taboos and preferences found in what the brand published"
1772
+ )
1773
+ rules: list[BrandRule] = Field(
1774
+ ...,
1775
+ description="Rules people at the brand stated, newest first. They outrank everything above.",
1776
+ )
1777
+ colors: list[BrandColor]
1778
+ typography: list[BrandTypographyItem]
1779
+ button: BrandButton | None = Field(
1780
+ ..., description="The site's primary call-to-action button"
1781
+ )
1782
+ fonts: list[BrandFont]
1783
+ logos: list[BrandLogo]
1784
+
1785
+
1786
+ class OfferSummary(BaseModel):
1787
+ id: str
1788
+ object: Literal["offer"]
1789
+ name: str
1790
+ kind: str = Field(..., description="product, service, bundle")
1791
+ priority: str = Field(..., description="hero, evergreen, seasonal")
1792
+ summary: str
1793
+ photo_count: int
1794
+ variant_count: int
1795
+
1796
+
1797
+ class OfferVariantPhoto(BaseModel):
1798
+ id: str = Field(..., description="An asset id, usable as a media input")
1799
+ url: str | None
1800
+ width: float | None
1801
+ height: float | None
1802
+ orientation: str | None
1803
+ shot_type: str | None
1804
+ caption: str | None
1805
+ liked: bool
1806
+
1807
+
1808
+ class OfferVariant(BaseModel):
1809
+ id: str
1810
+ name: str
1811
+ sku: str | None
1812
+ price: str | None
1813
+ compare_at_price: str | None
1814
+ sizes: list[str]
1815
+ photo_count: int
1816
+ photos: list[OfferVariantPhoto]
1817
+
1818
+
1819
+ class OfferPhoto(BaseModel):
1820
+ id: str = Field(..., description="An asset id, usable as a media input")
1821
+ url: str | None
1822
+ width: float | None
1823
+ height: float | None
1824
+ orientation: str | None
1825
+ shot_type: str | None
1826
+ caption: str | None
1827
+ liked: bool
1828
+
1829
+
1830
+ class Offer(BaseModel):
1831
+ id: str
1832
+ object: Literal["offer"]
1833
+ name: str
1834
+ kind: str = Field(..., description="product, service, bundle")
1835
+ priority: str = Field(..., description="hero, evergreen, seasonal")
1836
+ photo_count: int
1837
+ description: str | None
1838
+ context: str | None = Field(..., description="Notes on how to sell it")
1839
+ variants: list[OfferVariant]
1840
+ photos: list[OfferPhoto] = Field(
1841
+ ..., description="Photos of the offer that belong to no one variant"
1842
+ )
1843
+
1844
+
1845
+ class CharacterItem(BaseModel):
1846
+ asset: str = Field(..., description="An asset id, usable as a media input")
1847
+ type: Literal["image", "video", "audio"]
1848
+ role: str = Field(..., description="reference, first_frame, last_frame")
1849
+ angle: str | None
1850
+ usage: str | None
1851
+ url: str | None
1852
+
1853
+
1854
+ class Character(BaseModel):
1855
+ id: str
1856
+ object: Literal["character"]
1857
+ name: str
1858
+ kind: str = Field(..., description="subject, product, place, voice, style")
1859
+ description: str | None
1860
+ usage: str | None
1861
+ must_match: list[str] = Field(
1862
+ ..., description="What every image of it has to keep, such as Face or Wardrobe"
1863
+ )
1864
+ items: list[CharacterItem]
1865
+
1866
+
1867
+ class Voice(BaseModel):
1868
+ id: str = Field(..., description="Pass as `voice` to a voiceover or voice change")
1869
+ object: Literal["voice"]
1870
+ name: str
1871
+ gender: str
1872
+ age: str
1873
+ accent: str
1874
+ descriptive: str
1875
+ use_case: str
1876
+ description: str | None
1877
+ preview_url: str | None = Field(..., description="A public sample to play")
1878
+
1879
+
1880
+ class Advertiser(BaseModel):
1881
+ id: str
1882
+ object: Literal["advertiser"]
1883
+ name: str | None
1884
+ ads: int
1885
+ active_ads: int
1886
+ followed: bool = Field(..., description="Whether your organization follows it")
1887
+ sync: Literal["synced", "syncing", "failed", "never"]
1888
+ synced_at: str | None
1889
+
1890
+
1891
+ class AdSummary(BaseModel):
1892
+ id: str
1893
+ object: Literal["ad"]
1894
+ advertiser: str | None
1895
+ advertiser_name: str | None
1896
+ platform: str | None
1897
+ format: str | None
1898
+ status: str | None
1899
+ title: str | None
1900
+ body: str | None
1901
+ cta_text: str | None
1902
+ active_days: float | None
1903
+ started_at: str | None
1904
+ ad_library_url: str | None
1905
+
1906
+
1907
+ class Ad(BaseModel):
1908
+ id: str
1909
+ object: Literal["ad"]
1910
+ advertiser: str | None
1911
+ advertiser_name: str | None
1912
+ platform: str | None
1913
+ format: str | None
1914
+ status: str | None
1915
+ title: str | None
1916
+ body: str | None
1917
+ cta_text: str | None
1918
+ active_days: float | None
1919
+ started_at: str | None
1920
+ ad_library_url: str | None
1921
+ duration: float | None
1922
+ caption: str | None
1923
+ cta_type: str | None
1924
+ link_url: str | None
1925
+ link_description: str | None
1926
+ ended_at: str | None
1927
+ first_seen_at: str | None
1928
+ last_seen_at: str | None
1929
+ variants: float | None
1930
+ transcript: str | None
1931
+ media_url: str | None = Field(..., description="The ad's image or video")
1932
+
1933
+
1934
+ class PersonOrganization(BaseModel):
1935
+ id: str
1936
+ name: str | None
1937
+ current: bool = Field(
1938
+ ..., description="The organization Sandstorm opens for this person"
1939
+ )
1940
+ role: str | None
1941
+ brand: str | None = Field(
1942
+ ..., description="The brand this person last worked on there"
1943
+ )
1944
+
1945
+
1946
+ class Person(BaseModel):
1947
+ object: Literal["person"]
1948
+ id: str
1949
+ email: str | None
1950
+ organizations: list[PersonOrganization]
1951
+
1952
+
1953
+ class ApiKeyOrganization(BaseModel):
1954
+ id: str
1955
+ name: str | None
1956
+
1957
+
1958
+ class ApiKeyBrand(BaseModel):
1959
+ id: str
1960
+ name: str | None
1961
+
1962
+
1963
+ class ApiKey(BaseModel):
1964
+ object: Literal["api_key"]
1965
+ id: str
1966
+ name: str
1967
+ key: str = Field(..., description="The key itself, shown this once")
1968
+ prefix: str
1969
+ organization: ApiKeyOrganization
1970
+ brand: ApiKeyBrand | None
1971
+ created_at: str
1972
+
1973
+
1974
+ class WebhookSecret(BaseModel):
1975
+ object: Literal["webhook_secret"]
1976
+ secret: str
1977
+
1978
+
1979
+ class CreateGeneration(
1980
+ RootModel[
1981
+ CreateNanoBananaPro
1982
+ | CreateNanoBananaProEdit
1983
+ | CreateNanoBanana2
1984
+ | CreateNanoBanana2Edit
1985
+ | CreateNanoBanana2Lite
1986
+ | CreateNanoBanana2LiteEdit
1987
+ | CreateGptImage25Flare
1988
+ | CreateGptImage25FlareEdit
1989
+ | CreateGptImage25Sunburst
1990
+ | CreateGptImage25SunburstEdit
1991
+ | CreateSeedream5Pro
1992
+ | CreateSeedream5ProEdit
1993
+ | CreateSeedream5Lite
1994
+ | CreateSeedream5LiteEdit
1995
+ | CreateSeedream5ProLayers
1996
+ | CreateTopazUpscale
1997
+ | CreateSeedance25TextToVideo
1998
+ | CreateSeedance25ImageToVideo
1999
+ | CreateSeedance25ReferenceToVideo
2000
+ | CreateSeedance25Finish
2001
+ | CreateKling3ProImageToVideo
2002
+ | CreateKlingO3ProReferenceToVideo
2003
+ | CreateGeminiOmniFlashTextToVideo
2004
+ | CreateGeminiOmniFlashImageToVideo
2005
+ | CreateGeminiOmniFlashReferenceToVideo
2006
+ | CreateGeminiOmniFlashEdit
2007
+ | CreateSync3Lipsync
2008
+ | CreateElevenlabsVoiceover
2009
+ | CreateElevenlabsMusic
2010
+ | CreateElevenlabsSoundEffects
2011
+ | CreateElevenlabsVoiceChanger
2012
+ | CreateElevenlabsVoiceIsolator
2013
+ | CreateMinimaxMusic
2014
+ | CreateSoniloMusic
2015
+ ]
2016
+ ):
2017
+ root: (
2018
+ CreateNanoBananaPro
2019
+ | CreateNanoBananaProEdit
2020
+ | CreateNanoBanana2
2021
+ | CreateNanoBanana2Edit
2022
+ | CreateNanoBanana2Lite
2023
+ | CreateNanoBanana2LiteEdit
2024
+ | CreateGptImage25Flare
2025
+ | CreateGptImage25FlareEdit
2026
+ | CreateGptImage25Sunburst
2027
+ | CreateGptImage25SunburstEdit
2028
+ | CreateSeedream5Pro
2029
+ | CreateSeedream5ProEdit
2030
+ | CreateSeedream5Lite
2031
+ | CreateSeedream5LiteEdit
2032
+ | CreateSeedream5ProLayers
2033
+ | CreateTopazUpscale
2034
+ | CreateSeedance25TextToVideo
2035
+ | CreateSeedance25ImageToVideo
2036
+ | CreateSeedance25ReferenceToVideo
2037
+ | CreateSeedance25Finish
2038
+ | CreateKling3ProImageToVideo
2039
+ | CreateKlingO3ProReferenceToVideo
2040
+ | CreateGeminiOmniFlashTextToVideo
2041
+ | CreateGeminiOmniFlashImageToVideo
2042
+ | CreateGeminiOmniFlashReferenceToVideo
2043
+ | CreateGeminiOmniFlashEdit
2044
+ | CreateSync3Lipsync
2045
+ | CreateElevenlabsVoiceover
2046
+ | CreateElevenlabsMusic
2047
+ | CreateElevenlabsSoundEffects
2048
+ | CreateElevenlabsVoiceChanger
2049
+ | CreateElevenlabsVoiceIsolator
2050
+ | CreateMinimaxMusic
2051
+ | CreateSoniloMusic
2052
+ ) = Field(..., discriminator="model")
2053
+
2054
+
2055
+ class GenerationEvent(BaseModel):
2056
+ id: str = Field(
2057
+ ...,
2058
+ description="The same for every delivery of one event, so a retry can be told apart",
2059
+ )
2060
+ object: Literal["event"]
2061
+ type: Literal["generation.succeeded", "generation.failed", "generation.canceled"]
2062
+ created_at: str
2063
+ data: Generation
2064
+
2065
+
2066
+ class ModelList(BaseModel):
2067
+ object: Literal["list"]
2068
+ data: list[Model]
2069
+ has_more: bool
2070
+ next_cursor: str | None = Field(
2071
+ ..., description="Pass as `cursor` for the next page"
2072
+ )
2073
+
2074
+
2075
+ class LibraryAssetList(BaseModel):
2076
+ object: Literal["list"]
2077
+ data: list[LibraryAsset]
2078
+ has_more: bool
2079
+ next_cursor: str | None = Field(
2080
+ ..., description="Pass as `cursor` for the next page"
2081
+ )
2082
+
2083
+
2084
+ class OfferList(BaseModel):
2085
+ object: Literal["list"]
2086
+ data: list[OfferSummary]
2087
+ has_more: bool
2088
+ next_cursor: str | None = Field(
2089
+ ..., description="Pass as `cursor` for the next page"
2090
+ )
2091
+
2092
+
2093
+ class CharacterList(BaseModel):
2094
+ object: Literal["list"]
2095
+ data: list[Character]
2096
+ has_more: bool
2097
+ next_cursor: str | None = Field(
2098
+ ..., description="Pass as `cursor` for the next page"
2099
+ )
2100
+
2101
+
2102
+ class VoiceList(BaseModel):
2103
+ object: Literal["list"]
2104
+ data: list[Voice]
2105
+ has_more: bool
2106
+ next_cursor: str | None = Field(
2107
+ ..., description="Pass as `cursor` for the next page"
2108
+ )
2109
+
2110
+
2111
+ class AdvertiserList(BaseModel):
2112
+ object: Literal["list"]
2113
+ data: list[Advertiser]
2114
+ has_more: bool
2115
+ next_cursor: str | None = Field(
2116
+ ..., description="Pass as `cursor` for the next page"
2117
+ )
2118
+
2119
+
2120
+ class AdList(BaseModel):
2121
+ object: Literal["list"]
2122
+ data: list[AdSummary]
2123
+ has_more: bool
2124
+ next_cursor: str | None = Field(
2125
+ ..., description="Pass as `cursor` for the next page"
2126
+ )