instantclips-mcp 1.3.0 → 1.5.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.
@@ -7,10 +7,10 @@
7
7
  "serverInfo": {
8
8
  "name": "instantclips",
9
9
  "title": "InstantClips",
10
- "version": "0.4.0",
10
+ "version": "0.6.0",
11
11
  "websiteUrl": "https://instantclips.ai"
12
12
  },
13
- "instructions": "InstantClips turns a product into a short vertical marketing video.\n\nEvery video is drafted against a BRAND — a voice, a target market and a\nset of keywords. Getting the brand right matters more than anything else\nhere: a product drafted under the wrong company's voice renders perfectly\nand is still unusable. Never assume a product belongs to whatever brand\nthe account already has.\n\nStart by asking the user for their store's URL if you do not already know\nthe brand, and call `list_brands` to see what the account has. Unlike the\nwebsite, which takes a product link and gets out of the way, you can\nsimply ask — a short question here is cheaper than a wrongly branded\nvideo.\n\nThe workflow, in order:\n\n1. `import_product_from_url` with the product's page URL (or\n `create_product_from_images` with hosted image URLs). Both return\n immediately and import in the background.\n2. Poll `get_product` until `import_status` is \"imported\".\n - If it reports `brand_decision_required` with `drafting: false`, the\n brand could not be settled: the storefront does not match any brand\n on the account, or (photos) there was no page to detect one from.\n Stop and put the choice to the user: create a brand for it\n (`create_brand`) or attach it to one they already have\n (`set_product_brand`). Do not choose for them. For a photos product\n nothing was detected, so `create_brand` needs the name from the\n user, and the voice, target market and keywords they can give you.\n No direction is drafted until this is settled.\n - Otherwise the import also drafts a video direction — a six-section\n creative plan (Hook / Content Focus / Format / Suggesting Visual\n Aesthetic / Execution Guidelines /\n Strict Guidelines & Restrictions) — so keep polling until\n `video_direction.drafting` is false.\n3. Show the drafted direction to the user. Edit it with\n `update_video_direction`, or roll a completely different angle with\n `redraft_video_direction`. The direction is optional: an empty one is\n valid and generation still works.\n4. `generate_video`, passing `expected_credit_cost` — this SPENDS THE\n USER'S CREDITS. Get the user's explicit go-ahead first, and tell\n them the credit cost that `get_product` reports; the launch is\n refused, uncharged, if that number no longer matches.\n5. Poll `get_video` until status is \"done\", then give the user\n `output_url` (the finished MP4) and `share_url` (a public page).\n On a free account the MP4 carries the InstantClips watermark\n (`watermarked` is true); buying credits removes it from every video\n on the account.\n\nEvery get_product response carries `next_step`: what to do now and the\ntool to do it with. Read it before choosing a tool — it covers the\nstates this list does not: a failed import, a failed or stalled\ndirection draft, photos the video model will not take, a failed\nrender, a balance short of the cost.\n\nA product whose video has been generated is not finished with, but a\ngenerated video cannot be changed: its direction locks the moment\ngeneration starts, and re-importing the same URL returns the same\nproduct rather than a fresh one. Editing or redrafting such a product\nopens its next video's draft, seeded from the last one (the response\nsays `opened_new_video: true`), and `generate_video` with no draft\nrenders another take of the last plan as a new video. Continue from\nstep 3 either way.\n\nA render takes a few minutes. Poll every 20-30 seconds rather than in a\ntight loop, and tell the user what you are waiting on.\n",
13
+ "instructions": "InstantClips turns a product into a short vertical marketing video.\n\nEvery video is drafted against a BRAND — a voice, a target market and a\nset of keywords. Getting the brand right matters more than anything else\nhere: a product drafted under the wrong company's voice renders perfectly\nand is still unusable. Never assume a product belongs to whatever brand\nthe account already has.\n\nStart by asking the user for their store's URL if you do not already know\nthe brand, and call `list_brands` to see what the account has. Unlike the\nwebsite, which takes a product link and gets out of the way, you can\nsimply ask — a short question here is cheaper than a wrongly branded\nvideo.\n\nThe workflow, in order:\n\n1. `import_product_from_url` with the product's page URL, or\n `create_product_from_images` with the product's photos: hosted\n `image_urls`, or `image_files` when the client hands you the photos\n the user attached to the conversation (ChatGPT does). A URL import\n returns immediately and runs in the background; attached photos are\n imported before the call answers. If the user already made the\n product on the website — dropped photos on the workbench, pasted a\n link there — find it with `list_products` (newest first) and\n continue from step 2.\n2. Poll `get_product` until `import_status` is \"imported\".\n - If it reports `brand_decision_required` with `drafting: false`, the\n brand could not be settled: the storefront does not match any brand\n on the account, or (photos) there was no page to detect one from.\n Stop and put the choice to the user: create a brand for it\n (`create_brand`) or attach it to one they already have\n (`set_product_brand`). Do not choose for them. For a photos product\n nothing was detected, so `create_brand` needs the name from the\n user, and the voice, target market and keywords they can give you.\n No direction is drafted until this is settled.\n - Otherwise the import also drafts a video direction — a six-section\n creative plan (Hook / Content Focus / Format / Suggesting Visual\n Aesthetic / Execution Guidelines /\n Strict Guidelines & Restrictions) — so keep polling until\n `video_direction.drafting` is false.\n3. Show the drafted direction to the user. Edit it with\n `update_video_direction`, or roll a completely different angle with\n `redraft_video_direction`. The direction is optional: an empty one is\n valid and generation still works. The render settings — ratio,\n resolution, duration_seconds, enable_audio — are parameters of\n `update_video_direction` too, and are never read from the direction\n text. So are the photos: `images` in `get_product` lists every one\n with `usable` and `selected`, and `selected_image_ids` chooses which\n the render uses. `format` and `format_options` name the angle a\n redraft can pin. `update_product` corrects the facts a draft is\n written from (name, description, price, the posted link, the photos)\n and `update_brand` the identity (voice, market, keywords); both feed\n the next draft, so redraft after.\n4. `generate_video`, passing `expected_credit_cost` — this SPENDS THE\n USER'S CREDITS. Get the user's explicit go-ahead first, and tell\n them the credit cost that `get_product` reports; the launch is\n refused, uncharged, if that number no longer matches.\n5. Poll `get_video` until status is \"done\", then give the user\n `output_url` (the finished MP4) and `share_url` (a public page).\n On a free account the MP4 carries the InstantClips watermark\n (`watermarked` is true); buying credits removes it from every video\n on the account.\n\nEvery get_product response carries `next_step`: what to do now and the\ntool to do it with. Read it before choosing a tool — it covers the\nstates this list does not: a failed import, a failed or stalled\ndirection draft, photos the video model will not take, a failed\nrender, a balance short of the cost.\n\nA product whose video has been generated is not finished with, but a\ngenerated video cannot be changed: its direction locks the moment\ngeneration starts, and re-importing the same URL returns the same\nproduct rather than a fresh one. Editing or redrafting such a product\nopens its next video's draft, seeded from the last one (the response\nsays `opened_new_video: true`), and `generate_video` with no draft\nrenders another take of the last plan as a new video. Continue from\nstep 3 either way.\n\nA render takes a few minutes. Poll every 20-30 seconds rather than in a\ntight loop, and tell the user what you are waiting on.\n",
14
14
  "tools": [
15
15
  {
16
16
  "name": "list_brands",
@@ -22,6 +22,196 @@
22
22
  "required": [],
23
23
  "$schema": "https://json-schema.org/draft/2020-12/schema"
24
24
  },
25
+ "outputSchema": {
26
+ "type": "object",
27
+ "properties": {
28
+ "brands": {
29
+ "type": "array",
30
+ "items": {
31
+ "type": "object",
32
+ "properties": {
33
+ "brand_id": {
34
+ "type": "string"
35
+ },
36
+ "name": {
37
+ "type": "string"
38
+ },
39
+ "target_market": {
40
+ "type": "string"
41
+ },
42
+ "voice": {
43
+ "type": "string"
44
+ },
45
+ "keywords": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "string"
49
+ }
50
+ },
51
+ "configured": {
52
+ "type": "boolean"
53
+ },
54
+ "is_default": {
55
+ "type": "boolean"
56
+ },
57
+ "product_count": {
58
+ "type": "integer"
59
+ }
60
+ },
61
+ "required": [
62
+ "brand_id",
63
+ "name",
64
+ "keywords",
65
+ "configured",
66
+ "is_default",
67
+ "product_count"
68
+ ]
69
+ }
70
+ },
71
+ "brands_used": {
72
+ "type": "integer"
73
+ },
74
+ "brand_limit": {
75
+ "type": [
76
+ "integer",
77
+ "null"
78
+ ]
79
+ },
80
+ "unlimited_brands": {
81
+ "type": "boolean"
82
+ },
83
+ "can_create_brand": {
84
+ "type": "boolean"
85
+ }
86
+ },
87
+ "required": [
88
+ "brands",
89
+ "brands_used",
90
+ "unlimited_brands",
91
+ "can_create_brand"
92
+ ],
93
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
94
+ },
95
+ "annotations": {
96
+ "readOnlyHint": true,
97
+ "destructiveHint": false,
98
+ "idempotentHint": true,
99
+ "openWorldHint": false
100
+ }
101
+ },
102
+ {
103
+ "name": "list_products",
104
+ "title": "List the account's products",
105
+ "description": "List the account's products, newest first — the ones imported here, on\nthe website, or from photos dropped on the workbench. Use it to find a\nproduct_id you do not have: a product the user made on the website, or\none from an earlier conversation. Then `get_product` for its full state.\n\n`query` matches the name or the source URL, `brand_id` narrows to one\nbrand (see `list_brands`), and `limit` caps the list (default 20, at\nmost 50). A product still waiting on its brand decision shows\n`brand_decision_required: true` and no brand.\n\nThis does not spend credits.\n",
106
+ "inputSchema": {
107
+ "type": "object",
108
+ "properties": {
109
+ "query": {
110
+ "type": "string",
111
+ "description": "Matches the product's name or source URL, case-insensitively."
112
+ },
113
+ "brand_id": {
114
+ "type": "string",
115
+ "description": "Only this brand's products."
116
+ },
117
+ "limit": {
118
+ "type": "integer",
119
+ "minimum": 1,
120
+ "maximum": 50,
121
+ "description": "How many, newest first. Default 20."
122
+ }
123
+ },
124
+ "required": [],
125
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
126
+ },
127
+ "outputSchema": {
128
+ "type": "object",
129
+ "properties": {
130
+ "products": {
131
+ "type": "array",
132
+ "items": {
133
+ "type": "object",
134
+ "properties": {
135
+ "product_id": {
136
+ "type": "string"
137
+ },
138
+ "name": {
139
+ "type": "string"
140
+ },
141
+ "state": {
142
+ "type": "string"
143
+ },
144
+ "import_status": {
145
+ "type": "string"
146
+ },
147
+ "source_url": {
148
+ "type": "string"
149
+ },
150
+ "image_count": {
151
+ "type": "integer"
152
+ },
153
+ "brand": {
154
+ "type": "object",
155
+ "properties": {
156
+ "brand_id": {
157
+ "type": [
158
+ "string",
159
+ "null"
160
+ ]
161
+ },
162
+ "name": {
163
+ "type": [
164
+ "string",
165
+ "null"
166
+ ]
167
+ }
168
+ },
169
+ "required": []
170
+ },
171
+ "brand_decision_required": {
172
+ "type": "boolean"
173
+ },
174
+ "video_count": {
175
+ "type": "integer"
176
+ },
177
+ "latest_video_status": {
178
+ "type": "string"
179
+ },
180
+ "created_at": {
181
+ "type": "string"
182
+ },
183
+ "workbench_url": {
184
+ "type": "string"
185
+ }
186
+ },
187
+ "required": [
188
+ "product_id",
189
+ "state",
190
+ "image_count",
191
+ "video_count",
192
+ "created_at",
193
+ "workbench_url"
194
+ ]
195
+ }
196
+ },
197
+ "count": {
198
+ "type": "integer"
199
+ },
200
+ "total": {
201
+ "type": "integer"
202
+ },
203
+ "next_step": {
204
+ "type": "string"
205
+ }
206
+ },
207
+ "required": [
208
+ "products",
209
+ "count",
210
+ "total",
211
+ "next_step"
212
+ ],
213
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
214
+ },
25
215
  "annotations": {
26
216
  "readOnlyHint": true,
27
217
  "destructiveHint": false,
@@ -50,6 +240,309 @@
50
240
  ],
51
241
  "$schema": "https://json-schema.org/draft/2020-12/schema"
52
242
  },
243
+ "outputSchema": {
244
+ "type": "object",
245
+ "properties": {
246
+ "product_id": {
247
+ "type": "string"
248
+ },
249
+ "name": {
250
+ "type": "string"
251
+ },
252
+ "description": {
253
+ "type": "string"
254
+ },
255
+ "price": {
256
+ "type": "string"
257
+ },
258
+ "link_url": {
259
+ "type": "string"
260
+ },
261
+ "source_url": {
262
+ "type": "string"
263
+ },
264
+ "import_status": {
265
+ "type": "string"
266
+ },
267
+ "import_failed_reason": {
268
+ "type": "string"
269
+ },
270
+ "image_count": {
271
+ "type": "integer"
272
+ },
273
+ "usable_image_count": {
274
+ "type": "integer"
275
+ },
276
+ "images": {
277
+ "type": "array",
278
+ "items": {
279
+ "type": "object",
280
+ "properties": {
281
+ "image_id": {
282
+ "type": "string"
283
+ },
284
+ "url": {
285
+ "type": "string"
286
+ },
287
+ "filename": {
288
+ "type": "string"
289
+ },
290
+ "usable": {
291
+ "type": "boolean"
292
+ },
293
+ "selected": {
294
+ "type": "boolean"
295
+ }
296
+ },
297
+ "required": [
298
+ "image_id",
299
+ "url",
300
+ "filename",
301
+ "usable",
302
+ "selected"
303
+ ]
304
+ }
305
+ },
306
+ "state": {
307
+ "type": "string"
308
+ },
309
+ "brand": {
310
+ "type": "object",
311
+ "properties": {
312
+ "brand_id": {
313
+ "type": "string"
314
+ },
315
+ "name": {
316
+ "type": "string"
317
+ },
318
+ "target_market": {
319
+ "type": [
320
+ "string",
321
+ "null"
322
+ ]
323
+ },
324
+ "keywords": {
325
+ "type": "array",
326
+ "items": {
327
+ "type": "string"
328
+ }
329
+ }
330
+ },
331
+ "required": [
332
+ "brand_id",
333
+ "name",
334
+ "keywords"
335
+ ]
336
+ },
337
+ "brand_decision_required": {
338
+ "type": "object",
339
+ "properties": {
340
+ "drafting": {
341
+ "type": "boolean"
342
+ },
343
+ "reason": {
344
+ "type": "string"
345
+ },
346
+ "detected_brand_name": {
347
+ "type": [
348
+ "string",
349
+ "null"
350
+ ]
351
+ },
352
+ "existing_brands": {
353
+ "type": "array",
354
+ "items": {
355
+ "type": "object",
356
+ "properties": {
357
+ "brand_id": {
358
+ "type": "string"
359
+ },
360
+ "name": {
361
+ "type": "string"
362
+ },
363
+ "target_market": {
364
+ "type": [
365
+ "string",
366
+ "null"
367
+ ]
368
+ },
369
+ "keywords": {
370
+ "type": "array",
371
+ "items": {
372
+ "type": "string"
373
+ }
374
+ }
375
+ },
376
+ "required": [
377
+ "brand_id",
378
+ "name",
379
+ "keywords"
380
+ ]
381
+ }
382
+ },
383
+ "can_create_brand": {
384
+ "type": "boolean"
385
+ },
386
+ "brand_limit": {
387
+ "type": [
388
+ "integer",
389
+ "null"
390
+ ]
391
+ },
392
+ "brands_used": {
393
+ "type": "integer"
394
+ },
395
+ "resolve_with": {
396
+ "type": "string"
397
+ }
398
+ },
399
+ "required": [
400
+ "drafting"
401
+ ]
402
+ },
403
+ "workbench_url": {
404
+ "type": "string"
405
+ },
406
+ "video_direction": {
407
+ "type": "object",
408
+ "properties": {
409
+ "video_request_id": {
410
+ "type": "string"
411
+ },
412
+ "drafting": {
413
+ "type": "boolean"
414
+ },
415
+ "creative_direction": {
416
+ "type": "string"
417
+ },
418
+ "draft_failed": {
419
+ "type": "boolean"
420
+ },
421
+ "draft_error": {
422
+ "type": "string"
423
+ },
424
+ "creator_note": {
425
+ "type": "string"
426
+ },
427
+ "format": {
428
+ "type": "string"
429
+ },
430
+ "format_options": {
431
+ "type": "array",
432
+ "items": {
433
+ "type": "object",
434
+ "properties": {
435
+ "key": {
436
+ "type": "string"
437
+ },
438
+ "summary": {
439
+ "type": "string"
440
+ }
441
+ },
442
+ "required": [
443
+ "key",
444
+ "summary"
445
+ ]
446
+ }
447
+ },
448
+ "selected_image_ids": {
449
+ "type": "array",
450
+ "items": {
451
+ "type": "string"
452
+ }
453
+ },
454
+ "ratio": {
455
+ "type": "string"
456
+ },
457
+ "resolution": {
458
+ "type": "string"
459
+ },
460
+ "duration_seconds": {
461
+ "type": "integer"
462
+ },
463
+ "enable_audio": {
464
+ "type": "boolean"
465
+ },
466
+ "target_market": {
467
+ "type": "string"
468
+ },
469
+ "credit_cost": {
470
+ "type": "number"
471
+ },
472
+ "affordable": {
473
+ "type": "boolean"
474
+ },
475
+ "editable": {
476
+ "type": "boolean"
477
+ }
478
+ },
479
+ "required": [
480
+ "video_request_id",
481
+ "drafting",
482
+ "draft_failed",
483
+ "format_options",
484
+ "selected_image_ids",
485
+ "credit_cost",
486
+ "editable"
487
+ ]
488
+ },
489
+ "videos": {
490
+ "type": "array",
491
+ "items": {
492
+ "type": "object",
493
+ "properties": {
494
+ "video_request_id": {
495
+ "type": "string"
496
+ },
497
+ "status": {
498
+ "type": "string"
499
+ },
500
+ "failed_reason": {
501
+ "type": "string"
502
+ },
503
+ "output_url": {
504
+ "type": "string"
505
+ },
506
+ "watermarked": {
507
+ "type": "boolean"
508
+ },
509
+ "duration_seconds": {
510
+ "type": "integer"
511
+ },
512
+ "script": {
513
+ "type": "string"
514
+ },
515
+ "share_url": {
516
+ "type": "string"
517
+ }
518
+ },
519
+ "required": [
520
+ "video_request_id",
521
+ "status"
522
+ ]
523
+ }
524
+ },
525
+ "next_step": {
526
+ "type": "string"
527
+ },
528
+ "already_imported": {
529
+ "type": "boolean"
530
+ },
531
+ "retried": {
532
+ "type": "boolean"
533
+ }
534
+ },
535
+ "required": [
536
+ "product_id",
537
+ "image_count",
538
+ "usable_image_count",
539
+ "images",
540
+ "state",
541
+ "workbench_url",
542
+ "videos"
543
+ ],
544
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
545
+ },
53
546
  "annotations": {
54
547
  "readOnlyHint": false,
55
548
  "destructiveHint": true,
@@ -59,8 +552,8 @@
59
552
  },
60
553
  {
61
554
  "name": "create_product_from_images",
62
- "title": "Create a product from image URLs",
63
- "description": "Start a new InstantClips product from hosted product photos, for a\nproduct that has no public page to scrape.\n\nImages must be publicly reachable URLs — this endpoint cannot read files\nfrom the caller's machine. Images larger than\n8MB are skipped; at most\n9 are used in a render.\n\nReturns immediately with a product_id; the downloads run in the\nbackground. Poll `get_product` until `import_status` is \"imported\".\n\nPhotos carry no brand identity, so nothing can detect the brand here.\nWithout `brand_id` the product waits on a brand decision\n(`brand_decision_required` on the response and on `get_product`) and\nno video direction is drafted until it is settled with\n`set_product_brand` or `create_brand`. Ask the user which brand this\nis; do not pick for them.\n\nPrefer `import_product_from_url` when a product page exists — the scrape\nalso collects the name, description, price and brand identity, which\nmake for a far better direction draft than images alone.\n\nDirection drafting sends product facts, photos and brand context to\nan external AI service when the product is ready and its brand is settled.\n\nThis does not spend credits. Only `generate_video` does.\n",
555
+ "title": "Create a product from photos",
556
+ "description": "Start a new InstantClips product from product photos, for a product\nthat has no public page to scrape.\n\nPhotos arrive one of two ways: `image_urls`, publicly reachable URLs,\nor `image_files`, the photos the user attached to the conversation,\nfor clients that pass attachments to tools (ChatGPT fills it in from\nthe attachments — do not build it by hand). Either or both, at least\none photo. This endpoint cannot read files from the caller's machine.\nImages larger than 8MB are skipped; at\nmost 9 are used in a render.\n\nWith `image_urls` alone the downloads run in the background: poll\n`get_product` until `import_status` is \"imported\". Attached photos are\ndownloaded before this call answers, so the product comes back\nimported — or failed, with the reason and the way on in `next_step`.\n\nPhotos carry no brand identity, so nothing can detect the brand here.\nWithout `brand_id` the product waits on a brand decision\n(`brand_decision_required` on the response and on `get_product`) and\nno video direction is drafted until it is settled with\n`set_product_brand` or `create_brand`. Ask the user which brand this\nis; do not pick for them.\n\nPrefer `import_product_from_url` when a product page exists — the scrape\nalso collects the name, description, price and brand identity, which\nmake for a far better direction draft than images alone.\n\nDirection drafting sends product facts, photos and brand context to\nan external AI service when the product is ready and its brand is settled.\n\nThis does not spend credits. Only `generate_video` does.\n",
64
557
  "inputSchema": {
65
558
  "type": "object",
66
559
  "properties": {
@@ -72,89 +565,1575 @@
72
565
  "description": "Publicly reachable image URLs, most representative first.",
73
566
  "minItems": 1
74
567
  },
568
+ "image_files": {
569
+ "type": "array",
570
+ "items": {
571
+ "type": "object",
572
+ "properties": {
573
+ "download_url": {
574
+ "type": "string"
575
+ },
576
+ "file_id": {
577
+ "type": "string"
578
+ },
579
+ "mime_type": {
580
+ "type": "string"
581
+ },
582
+ "file_name": {
583
+ "type": "string"
584
+ }
585
+ },
586
+ "required": [
587
+ "download_url",
588
+ "file_id"
589
+ ],
590
+ "additionalProperties": false
591
+ },
592
+ "description": "Photos attached to the conversation, as the client supplies them (a download_url and file_id per file). Leave it out unless the client filled it in."
593
+ },
594
+ "name": {
595
+ "type": "string",
596
+ "description": "Product name."
597
+ },
598
+ "description": {
599
+ "type": "string",
600
+ "description": "Optional. What the product is, in a sentence or two — feeds the direction draft."
601
+ },
602
+ "creator_note": {
603
+ "type": "string",
604
+ "description": "Optional. A short free-text note to the director: the angle, occasion or message this video should carry."
605
+ },
606
+ "brand_id": {
607
+ "type": "string",
608
+ "description": "Optional, and only when the user has said which brand this product belongs to (from `list_brands`). Omit it and the product waits on a brand decision instead of falling through to the account's default brand."
609
+ }
610
+ },
611
+ "required": [
612
+ "name"
613
+ ],
614
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
615
+ },
616
+ "outputSchema": {
617
+ "type": "object",
618
+ "properties": {
619
+ "product_id": {
620
+ "type": "string"
621
+ },
622
+ "name": {
623
+ "type": "string"
624
+ },
625
+ "description": {
626
+ "type": "string"
627
+ },
628
+ "price": {
629
+ "type": "string"
630
+ },
631
+ "link_url": {
632
+ "type": "string"
633
+ },
634
+ "source_url": {
635
+ "type": "string"
636
+ },
637
+ "import_status": {
638
+ "type": "string"
639
+ },
640
+ "import_failed_reason": {
641
+ "type": "string"
642
+ },
643
+ "image_count": {
644
+ "type": "integer"
645
+ },
646
+ "usable_image_count": {
647
+ "type": "integer"
648
+ },
649
+ "images": {
650
+ "type": "array",
651
+ "items": {
652
+ "type": "object",
653
+ "properties": {
654
+ "image_id": {
655
+ "type": "string"
656
+ },
657
+ "url": {
658
+ "type": "string"
659
+ },
660
+ "filename": {
661
+ "type": "string"
662
+ },
663
+ "usable": {
664
+ "type": "boolean"
665
+ },
666
+ "selected": {
667
+ "type": "boolean"
668
+ }
669
+ },
670
+ "required": [
671
+ "image_id",
672
+ "url",
673
+ "filename",
674
+ "usable",
675
+ "selected"
676
+ ]
677
+ }
678
+ },
679
+ "state": {
680
+ "type": "string"
681
+ },
682
+ "brand": {
683
+ "type": "object",
684
+ "properties": {
685
+ "brand_id": {
686
+ "type": "string"
687
+ },
688
+ "name": {
689
+ "type": "string"
690
+ },
691
+ "target_market": {
692
+ "type": [
693
+ "string",
694
+ "null"
695
+ ]
696
+ },
697
+ "keywords": {
698
+ "type": "array",
699
+ "items": {
700
+ "type": "string"
701
+ }
702
+ }
703
+ },
704
+ "required": [
705
+ "brand_id",
706
+ "name",
707
+ "keywords"
708
+ ]
709
+ },
710
+ "brand_decision_required": {
711
+ "type": "object",
712
+ "properties": {
713
+ "drafting": {
714
+ "type": "boolean"
715
+ },
716
+ "reason": {
717
+ "type": "string"
718
+ },
719
+ "detected_brand_name": {
720
+ "type": [
721
+ "string",
722
+ "null"
723
+ ]
724
+ },
725
+ "existing_brands": {
726
+ "type": "array",
727
+ "items": {
728
+ "type": "object",
729
+ "properties": {
730
+ "brand_id": {
731
+ "type": "string"
732
+ },
733
+ "name": {
734
+ "type": "string"
735
+ },
736
+ "target_market": {
737
+ "type": [
738
+ "string",
739
+ "null"
740
+ ]
741
+ },
742
+ "keywords": {
743
+ "type": "array",
744
+ "items": {
745
+ "type": "string"
746
+ }
747
+ }
748
+ },
749
+ "required": [
750
+ "brand_id",
751
+ "name",
752
+ "keywords"
753
+ ]
754
+ }
755
+ },
756
+ "can_create_brand": {
757
+ "type": "boolean"
758
+ },
759
+ "brand_limit": {
760
+ "type": [
761
+ "integer",
762
+ "null"
763
+ ]
764
+ },
765
+ "brands_used": {
766
+ "type": "integer"
767
+ },
768
+ "resolve_with": {
769
+ "type": "string"
770
+ }
771
+ },
772
+ "required": [
773
+ "drafting"
774
+ ]
775
+ },
776
+ "workbench_url": {
777
+ "type": "string"
778
+ },
779
+ "video_direction": {
780
+ "type": "object",
781
+ "properties": {
782
+ "video_request_id": {
783
+ "type": "string"
784
+ },
785
+ "drafting": {
786
+ "type": "boolean"
787
+ },
788
+ "creative_direction": {
789
+ "type": "string"
790
+ },
791
+ "draft_failed": {
792
+ "type": "boolean"
793
+ },
794
+ "draft_error": {
795
+ "type": "string"
796
+ },
797
+ "creator_note": {
798
+ "type": "string"
799
+ },
800
+ "format": {
801
+ "type": "string"
802
+ },
803
+ "format_options": {
804
+ "type": "array",
805
+ "items": {
806
+ "type": "object",
807
+ "properties": {
808
+ "key": {
809
+ "type": "string"
810
+ },
811
+ "summary": {
812
+ "type": "string"
813
+ }
814
+ },
815
+ "required": [
816
+ "key",
817
+ "summary"
818
+ ]
819
+ }
820
+ },
821
+ "selected_image_ids": {
822
+ "type": "array",
823
+ "items": {
824
+ "type": "string"
825
+ }
826
+ },
827
+ "ratio": {
828
+ "type": "string"
829
+ },
830
+ "resolution": {
831
+ "type": "string"
832
+ },
833
+ "duration_seconds": {
834
+ "type": "integer"
835
+ },
836
+ "enable_audio": {
837
+ "type": "boolean"
838
+ },
839
+ "target_market": {
840
+ "type": "string"
841
+ },
842
+ "credit_cost": {
843
+ "type": "number"
844
+ },
845
+ "affordable": {
846
+ "type": "boolean"
847
+ },
848
+ "editable": {
849
+ "type": "boolean"
850
+ }
851
+ },
852
+ "required": [
853
+ "video_request_id",
854
+ "drafting",
855
+ "draft_failed",
856
+ "format_options",
857
+ "selected_image_ids",
858
+ "credit_cost",
859
+ "editable"
860
+ ]
861
+ },
862
+ "videos": {
863
+ "type": "array",
864
+ "items": {
865
+ "type": "object",
866
+ "properties": {
867
+ "video_request_id": {
868
+ "type": "string"
869
+ },
870
+ "status": {
871
+ "type": "string"
872
+ },
873
+ "failed_reason": {
874
+ "type": "string"
875
+ },
876
+ "output_url": {
877
+ "type": "string"
878
+ },
879
+ "watermarked": {
880
+ "type": "boolean"
881
+ },
882
+ "duration_seconds": {
883
+ "type": "integer"
884
+ },
885
+ "script": {
886
+ "type": "string"
887
+ },
888
+ "share_url": {
889
+ "type": "string"
890
+ }
891
+ },
892
+ "required": [
893
+ "video_request_id",
894
+ "status"
895
+ ]
896
+ }
897
+ },
898
+ "next_step": {
899
+ "type": "string"
900
+ }
901
+ },
902
+ "required": [
903
+ "product_id",
904
+ "image_count",
905
+ "usable_image_count",
906
+ "images",
907
+ "state",
908
+ "workbench_url",
909
+ "videos"
910
+ ],
911
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
912
+ },
913
+ "annotations": {
914
+ "readOnlyHint": false,
915
+ "destructiveHint": false,
916
+ "idempotentHint": false,
917
+ "openWorldHint": true
918
+ },
919
+ "_meta": {
920
+ "openai/fileParams": [
921
+ "image_files"
922
+ ]
923
+ }
924
+ },
925
+ {
926
+ "name": "get_product",
927
+ "title": "Get a product and its video direction",
928
+ "description": "Read a product: what the import found, the current video direction and\nsettings, and every video generated from it.\n\nUse this to poll after `import_product_from_url` or\n`create_product_from_images`. The product is ready to work with when\n`import_status` is \"imported\", there is no `brand_decision_required`,\nAND `video_direction.drafting` is false. If a brand decision is present\nwith `drafting: false`, ask the user to choose a brand and resolve it\nwith `create_brand` or `set_product_brand` before waiting for a direction.\nPoll every 20-30 seconds while import or drafting is in progress.\n\n`import_status` values: \"pending\" and \"importing\" mean keep polling;\n\"imported\" means done; \"failed\" means it did not work and\n`import_failed_reason` says why.\n\n`video_direction.credit_cost` is what `generate_video` will charge for\nthe current settings. `duration_seconds`, `ratio`, `resolution` and\n`enable_audio` are those settings; change them with\n`update_video_direction`, not in the direction text.\n\nOnce generation has started the direction is locked and\n`video_direction.editable` is false. Editing or redrafting then opens\nthe next video's draft, and `next_step` says so.\n",
929
+ "inputSchema": {
930
+ "type": "object",
931
+ "properties": {
932
+ "product_id": {
933
+ "type": "string",
934
+ "description": "The product's id."
935
+ }
936
+ },
937
+ "required": [
938
+ "product_id"
939
+ ],
940
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
941
+ },
942
+ "outputSchema": {
943
+ "type": "object",
944
+ "properties": {
945
+ "product_id": {
946
+ "type": "string"
947
+ },
948
+ "name": {
949
+ "type": "string"
950
+ },
951
+ "description": {
952
+ "type": "string"
953
+ },
954
+ "price": {
955
+ "type": "string"
956
+ },
957
+ "link_url": {
958
+ "type": "string"
959
+ },
960
+ "source_url": {
961
+ "type": "string"
962
+ },
963
+ "import_status": {
964
+ "type": "string"
965
+ },
966
+ "import_failed_reason": {
967
+ "type": "string"
968
+ },
969
+ "image_count": {
970
+ "type": "integer"
971
+ },
972
+ "usable_image_count": {
973
+ "type": "integer"
974
+ },
975
+ "images": {
976
+ "type": "array",
977
+ "items": {
978
+ "type": "object",
979
+ "properties": {
980
+ "image_id": {
981
+ "type": "string"
982
+ },
983
+ "url": {
984
+ "type": "string"
985
+ },
986
+ "filename": {
987
+ "type": "string"
988
+ },
989
+ "usable": {
990
+ "type": "boolean"
991
+ },
992
+ "selected": {
993
+ "type": "boolean"
994
+ }
995
+ },
996
+ "required": [
997
+ "image_id",
998
+ "url",
999
+ "filename",
1000
+ "usable",
1001
+ "selected"
1002
+ ]
1003
+ }
1004
+ },
1005
+ "state": {
1006
+ "type": "string"
1007
+ },
1008
+ "brand": {
1009
+ "type": "object",
1010
+ "properties": {
1011
+ "brand_id": {
1012
+ "type": "string"
1013
+ },
1014
+ "name": {
1015
+ "type": "string"
1016
+ },
1017
+ "target_market": {
1018
+ "type": [
1019
+ "string",
1020
+ "null"
1021
+ ]
1022
+ },
1023
+ "keywords": {
1024
+ "type": "array",
1025
+ "items": {
1026
+ "type": "string"
1027
+ }
1028
+ }
1029
+ },
1030
+ "required": [
1031
+ "brand_id",
1032
+ "name",
1033
+ "keywords"
1034
+ ]
1035
+ },
1036
+ "brand_decision_required": {
1037
+ "type": "object",
1038
+ "properties": {
1039
+ "drafting": {
1040
+ "type": "boolean"
1041
+ },
1042
+ "reason": {
1043
+ "type": "string"
1044
+ },
1045
+ "detected_brand_name": {
1046
+ "type": [
1047
+ "string",
1048
+ "null"
1049
+ ]
1050
+ },
1051
+ "existing_brands": {
1052
+ "type": "array",
1053
+ "items": {
1054
+ "type": "object",
1055
+ "properties": {
1056
+ "brand_id": {
1057
+ "type": "string"
1058
+ },
1059
+ "name": {
1060
+ "type": "string"
1061
+ },
1062
+ "target_market": {
1063
+ "type": [
1064
+ "string",
1065
+ "null"
1066
+ ]
1067
+ },
1068
+ "keywords": {
1069
+ "type": "array",
1070
+ "items": {
1071
+ "type": "string"
1072
+ }
1073
+ }
1074
+ },
1075
+ "required": [
1076
+ "brand_id",
1077
+ "name",
1078
+ "keywords"
1079
+ ]
1080
+ }
1081
+ },
1082
+ "can_create_brand": {
1083
+ "type": "boolean"
1084
+ },
1085
+ "brand_limit": {
1086
+ "type": [
1087
+ "integer",
1088
+ "null"
1089
+ ]
1090
+ },
1091
+ "brands_used": {
1092
+ "type": "integer"
1093
+ },
1094
+ "resolve_with": {
1095
+ "type": "string"
1096
+ }
1097
+ },
1098
+ "required": [
1099
+ "drafting"
1100
+ ]
1101
+ },
1102
+ "workbench_url": {
1103
+ "type": "string"
1104
+ },
1105
+ "video_direction": {
1106
+ "type": "object",
1107
+ "properties": {
1108
+ "video_request_id": {
1109
+ "type": "string"
1110
+ },
1111
+ "drafting": {
1112
+ "type": "boolean"
1113
+ },
1114
+ "creative_direction": {
1115
+ "type": "string"
1116
+ },
1117
+ "draft_failed": {
1118
+ "type": "boolean"
1119
+ },
1120
+ "draft_error": {
1121
+ "type": "string"
1122
+ },
1123
+ "creator_note": {
1124
+ "type": "string"
1125
+ },
1126
+ "format": {
1127
+ "type": "string"
1128
+ },
1129
+ "format_options": {
1130
+ "type": "array",
1131
+ "items": {
1132
+ "type": "object",
1133
+ "properties": {
1134
+ "key": {
1135
+ "type": "string"
1136
+ },
1137
+ "summary": {
1138
+ "type": "string"
1139
+ }
1140
+ },
1141
+ "required": [
1142
+ "key",
1143
+ "summary"
1144
+ ]
1145
+ }
1146
+ },
1147
+ "selected_image_ids": {
1148
+ "type": "array",
1149
+ "items": {
1150
+ "type": "string"
1151
+ }
1152
+ },
1153
+ "ratio": {
1154
+ "type": "string"
1155
+ },
1156
+ "resolution": {
1157
+ "type": "string"
1158
+ },
1159
+ "duration_seconds": {
1160
+ "type": "integer"
1161
+ },
1162
+ "enable_audio": {
1163
+ "type": "boolean"
1164
+ },
1165
+ "target_market": {
1166
+ "type": "string"
1167
+ },
1168
+ "credit_cost": {
1169
+ "type": "number"
1170
+ },
1171
+ "affordable": {
1172
+ "type": "boolean"
1173
+ },
1174
+ "editable": {
1175
+ "type": "boolean"
1176
+ }
1177
+ },
1178
+ "required": [
1179
+ "video_request_id",
1180
+ "drafting",
1181
+ "draft_failed",
1182
+ "format_options",
1183
+ "selected_image_ids",
1184
+ "credit_cost",
1185
+ "editable"
1186
+ ]
1187
+ },
1188
+ "videos": {
1189
+ "type": "array",
1190
+ "items": {
1191
+ "type": "object",
1192
+ "properties": {
1193
+ "video_request_id": {
1194
+ "type": "string"
1195
+ },
1196
+ "status": {
1197
+ "type": "string"
1198
+ },
1199
+ "failed_reason": {
1200
+ "type": "string"
1201
+ },
1202
+ "output_url": {
1203
+ "type": "string"
1204
+ },
1205
+ "watermarked": {
1206
+ "type": "boolean"
1207
+ },
1208
+ "duration_seconds": {
1209
+ "type": "integer"
1210
+ },
1211
+ "script": {
1212
+ "type": "string"
1213
+ },
1214
+ "share_url": {
1215
+ "type": "string"
1216
+ }
1217
+ },
1218
+ "required": [
1219
+ "video_request_id",
1220
+ "status"
1221
+ ]
1222
+ }
1223
+ },
1224
+ "next_step": {
1225
+ "type": "string"
1226
+ },
1227
+ "credits_remaining": {
1228
+ "type": "number"
1229
+ }
1230
+ },
1231
+ "required": [
1232
+ "product_id",
1233
+ "image_count",
1234
+ "usable_image_count",
1235
+ "images",
1236
+ "state",
1237
+ "workbench_url",
1238
+ "videos",
1239
+ "credits_remaining"
1240
+ ],
1241
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
1242
+ },
1243
+ "annotations": {
1244
+ "readOnlyHint": true,
1245
+ "destructiveHint": false,
1246
+ "idempotentHint": true,
1247
+ "openWorldHint": false
1248
+ }
1249
+ },
1250
+ {
1251
+ "name": "create_brand",
1252
+ "title": "Create a brand for a product",
1253
+ "description": "Create a new brand for a product that is waiting on\n`brand_decision_required`, and attach the product to it.\n\nUse this when the product belongs to a company the account has no brand\nfor yet — the usual case when someone brings a new store. For a product\nimported from a URL the brand's name, voice, target market and keywords\nare taken from what the storefront scrape drafted; the user can rename\nit with `name`. For a product created from photos nothing was detected\n(`detected_brand_name` is null), so `name` is required and `voice`,\n`target_market` and `keywords` should come from the user — ask them how\nthe brand sounds and who it sells to. Anything you pass overrides the\ndetected value.\n\nAsk the user before calling this. It consumes one of the plan's brand\nslots, and on a plan that has run out this fails with a brand-limit\nerror — at which point the choices are to attach the product to an\nexisting brand with `set_product_brand`, to re-point an existing brand\nat this identity with `set_product_brand` and `replace_identity: true`,\nor to upgrade.\n\nOnce this returns, the video direction starts drafting: poll\n`get_product` until `video_direction.drafting` is false.\n\nDirection drafting sends product facts, photos and brand context to\nan external AI service when the product is ready and its brand is settled.\n\nThis does not spend credits.\n",
1254
+ "inputSchema": {
1255
+ "type": "object",
1256
+ "properties": {
1257
+ "product_id": {
1258
+ "type": "string",
1259
+ "description": "The product waiting on a brand decision."
1260
+ },
1261
+ "name": {
1262
+ "type": "string",
1263
+ "description": "The brand's name. Optional when a storefront name was detected (it overrides it); required for a product created from photos."
1264
+ },
1265
+ "voice": {
1266
+ "type": "string",
1267
+ "description": "Optional. How the brand talks, in a sentence or two — the tone every video direction is drafted in."
1268
+ },
1269
+ "target_market": {
1270
+ "type": "string",
1271
+ "description": "Optional. Who the brand sells to, as \"Region, Language\" (e.g. \"US, English\"). Sets the market and spoken language of every video on the brand."
1272
+ },
1273
+ "keywords": {
1274
+ "type": "array",
1275
+ "items": {
1276
+ "type": "string"
1277
+ },
1278
+ "description": "Optional. A few short keywords for the brand's themes and audience — generic enough to survive a different product."
1279
+ }
1280
+ },
1281
+ "required": [
1282
+ "product_id"
1283
+ ],
1284
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
1285
+ },
1286
+ "outputSchema": {
1287
+ "type": "object",
1288
+ "properties": {
1289
+ "product_id": {
1290
+ "type": "string"
1291
+ },
1292
+ "name": {
1293
+ "type": "string"
1294
+ },
1295
+ "description": {
1296
+ "type": "string"
1297
+ },
1298
+ "price": {
1299
+ "type": "string"
1300
+ },
1301
+ "link_url": {
1302
+ "type": "string"
1303
+ },
1304
+ "source_url": {
1305
+ "type": "string"
1306
+ },
1307
+ "import_status": {
1308
+ "type": "string"
1309
+ },
1310
+ "import_failed_reason": {
1311
+ "type": "string"
1312
+ },
1313
+ "image_count": {
1314
+ "type": "integer"
1315
+ },
1316
+ "usable_image_count": {
1317
+ "type": "integer"
1318
+ },
1319
+ "images": {
1320
+ "type": "array",
1321
+ "items": {
1322
+ "type": "object",
1323
+ "properties": {
1324
+ "image_id": {
1325
+ "type": "string"
1326
+ },
1327
+ "url": {
1328
+ "type": "string"
1329
+ },
1330
+ "filename": {
1331
+ "type": "string"
1332
+ },
1333
+ "usable": {
1334
+ "type": "boolean"
1335
+ },
1336
+ "selected": {
1337
+ "type": "boolean"
1338
+ }
1339
+ },
1340
+ "required": [
1341
+ "image_id",
1342
+ "url",
1343
+ "filename",
1344
+ "usable",
1345
+ "selected"
1346
+ ]
1347
+ }
1348
+ },
1349
+ "state": {
1350
+ "type": "string"
1351
+ },
1352
+ "brand": {
1353
+ "type": "object",
1354
+ "properties": {
1355
+ "brand_id": {
1356
+ "type": "string"
1357
+ },
1358
+ "name": {
1359
+ "type": "string"
1360
+ },
1361
+ "target_market": {
1362
+ "type": [
1363
+ "string",
1364
+ "null"
1365
+ ]
1366
+ },
1367
+ "keywords": {
1368
+ "type": "array",
1369
+ "items": {
1370
+ "type": "string"
1371
+ }
1372
+ }
1373
+ },
1374
+ "required": [
1375
+ "brand_id",
1376
+ "name",
1377
+ "keywords"
1378
+ ]
1379
+ },
1380
+ "brand_decision_required": {
1381
+ "type": "object",
1382
+ "properties": {
1383
+ "drafting": {
1384
+ "type": "boolean"
1385
+ },
1386
+ "reason": {
1387
+ "type": "string"
1388
+ },
1389
+ "detected_brand_name": {
1390
+ "type": [
1391
+ "string",
1392
+ "null"
1393
+ ]
1394
+ },
1395
+ "existing_brands": {
1396
+ "type": "array",
1397
+ "items": {
1398
+ "type": "object",
1399
+ "properties": {
1400
+ "brand_id": {
1401
+ "type": "string"
1402
+ },
1403
+ "name": {
1404
+ "type": "string"
1405
+ },
1406
+ "target_market": {
1407
+ "type": [
1408
+ "string",
1409
+ "null"
1410
+ ]
1411
+ },
1412
+ "keywords": {
1413
+ "type": "array",
1414
+ "items": {
1415
+ "type": "string"
1416
+ }
1417
+ }
1418
+ },
1419
+ "required": [
1420
+ "brand_id",
1421
+ "name",
1422
+ "keywords"
1423
+ ]
1424
+ }
1425
+ },
1426
+ "can_create_brand": {
1427
+ "type": "boolean"
1428
+ },
1429
+ "brand_limit": {
1430
+ "type": [
1431
+ "integer",
1432
+ "null"
1433
+ ]
1434
+ },
1435
+ "brands_used": {
1436
+ "type": "integer"
1437
+ },
1438
+ "resolve_with": {
1439
+ "type": "string"
1440
+ }
1441
+ },
1442
+ "required": [
1443
+ "drafting"
1444
+ ]
1445
+ },
1446
+ "workbench_url": {
1447
+ "type": "string"
1448
+ },
1449
+ "video_direction": {
1450
+ "type": "object",
1451
+ "properties": {
1452
+ "video_request_id": {
1453
+ "type": "string"
1454
+ },
1455
+ "drafting": {
1456
+ "type": "boolean"
1457
+ },
1458
+ "creative_direction": {
1459
+ "type": "string"
1460
+ },
1461
+ "draft_failed": {
1462
+ "type": "boolean"
1463
+ },
1464
+ "draft_error": {
1465
+ "type": "string"
1466
+ },
1467
+ "creator_note": {
1468
+ "type": "string"
1469
+ },
1470
+ "format": {
1471
+ "type": "string"
1472
+ },
1473
+ "format_options": {
1474
+ "type": "array",
1475
+ "items": {
1476
+ "type": "object",
1477
+ "properties": {
1478
+ "key": {
1479
+ "type": "string"
1480
+ },
1481
+ "summary": {
1482
+ "type": "string"
1483
+ }
1484
+ },
1485
+ "required": [
1486
+ "key",
1487
+ "summary"
1488
+ ]
1489
+ }
1490
+ },
1491
+ "selected_image_ids": {
1492
+ "type": "array",
1493
+ "items": {
1494
+ "type": "string"
1495
+ }
1496
+ },
1497
+ "ratio": {
1498
+ "type": "string"
1499
+ },
1500
+ "resolution": {
1501
+ "type": "string"
1502
+ },
1503
+ "duration_seconds": {
1504
+ "type": "integer"
1505
+ },
1506
+ "enable_audio": {
1507
+ "type": "boolean"
1508
+ },
1509
+ "target_market": {
1510
+ "type": "string"
1511
+ },
1512
+ "credit_cost": {
1513
+ "type": "number"
1514
+ },
1515
+ "affordable": {
1516
+ "type": "boolean"
1517
+ },
1518
+ "editable": {
1519
+ "type": "boolean"
1520
+ }
1521
+ },
1522
+ "required": [
1523
+ "video_request_id",
1524
+ "drafting",
1525
+ "draft_failed",
1526
+ "format_options",
1527
+ "selected_image_ids",
1528
+ "credit_cost",
1529
+ "editable"
1530
+ ]
1531
+ },
1532
+ "videos": {
1533
+ "type": "array",
1534
+ "items": {
1535
+ "type": "object",
1536
+ "properties": {
1537
+ "video_request_id": {
1538
+ "type": "string"
1539
+ },
1540
+ "status": {
1541
+ "type": "string"
1542
+ },
1543
+ "failed_reason": {
1544
+ "type": "string"
1545
+ },
1546
+ "output_url": {
1547
+ "type": "string"
1548
+ },
1549
+ "watermarked": {
1550
+ "type": "boolean"
1551
+ },
1552
+ "duration_seconds": {
1553
+ "type": "integer"
1554
+ },
1555
+ "script": {
1556
+ "type": "string"
1557
+ },
1558
+ "share_url": {
1559
+ "type": "string"
1560
+ }
1561
+ },
1562
+ "required": [
1563
+ "video_request_id",
1564
+ "status"
1565
+ ]
1566
+ }
1567
+ },
1568
+ "next_step": {
1569
+ "type": "string"
1570
+ },
1571
+ "created_brand": {
1572
+ "type": "object",
1573
+ "properties": {
1574
+ "brand_id": {
1575
+ "type": "string"
1576
+ },
1577
+ "name": {
1578
+ "type": "string"
1579
+ },
1580
+ "target_market": {
1581
+ "type": [
1582
+ "string",
1583
+ "null"
1584
+ ]
1585
+ },
1586
+ "keywords": {
1587
+ "type": "array",
1588
+ "items": {
1589
+ "type": "string"
1590
+ }
1591
+ }
1592
+ },
1593
+ "required": [
1594
+ "brand_id",
1595
+ "name",
1596
+ "keywords"
1597
+ ]
1598
+ }
1599
+ },
1600
+ "required": [
1601
+ "product_id",
1602
+ "image_count",
1603
+ "usable_image_count",
1604
+ "images",
1605
+ "state",
1606
+ "workbench_url",
1607
+ "videos",
1608
+ "created_brand"
1609
+ ],
1610
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
1611
+ },
1612
+ "annotations": {
1613
+ "readOnlyHint": false,
1614
+ "destructiveHint": false,
1615
+ "idempotentHint": false,
1616
+ "openWorldHint": true
1617
+ }
1618
+ },
1619
+ {
1620
+ "name": "set_product_brand",
1621
+ "title": "Attach a product to an existing brand",
1622
+ "description": "Attach a product waiting on `brand_decision_required` to one of the\naccount's existing brands. Use `list_brands` to see them.\n\nOnly do this when the user has confirmed the product really belongs to\nthat brand. Attaching a product to an unrelated brand is not a cosmetic\nmislabel: every video is drafted in that brand's voice, to its target\nmarket, with its keywords.\n\nBy default the brand's existing identity is left untouched. Pass\n`replace_identity: true` to instead overwrite that brand's voice, target\nmarket and keywords with the identity detected on this product — the\n\"re-point my brand at a different company\" move, for an account at its\nbrand limit. This rewrites a brand every other product on it shares, so\nconfirm it with the user explicitly first.\n\nOnce this returns, the video direction starts drafting: poll\n`get_product` until `video_direction.drafting` is false.\n\nReplacement also applies nonempty detected logo and colors, and can\nname an existing Default brand shell. Blank draft fields preserve saved\nvalues. An uploaded logo replaces the attached logo.\n\nDirection drafting sends product facts, photos and brand context to\nan external AI service when the product is ready and its brand is settled.\n\nThis does not spend credits.\n",
1623
+ "inputSchema": {
1624
+ "type": "object",
1625
+ "properties": {
1626
+ "product_id": {
1627
+ "type": "string",
1628
+ "description": "The product waiting on a brand decision."
1629
+ },
1630
+ "brand_id": {
1631
+ "type": "string",
1632
+ "description": "The brand to attach it to, from `list_brands`."
1633
+ },
1634
+ "replace_identity": {
1635
+ "type": "boolean",
1636
+ "description": "Optional, default false. Overwrite the brand's voice, target market and keywords with this product's detected identity. Also applies logo and colors; blank fields are preserved. Affects every product on that brand — confirm with the user."
1637
+ }
1638
+ },
1639
+ "required": [
1640
+ "product_id",
1641
+ "brand_id"
1642
+ ],
1643
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
1644
+ },
1645
+ "outputSchema": {
1646
+ "type": "object",
1647
+ "properties": {
1648
+ "product_id": {
1649
+ "type": "string"
1650
+ },
1651
+ "name": {
1652
+ "type": "string"
1653
+ },
1654
+ "description": {
1655
+ "type": "string"
1656
+ },
1657
+ "price": {
1658
+ "type": "string"
1659
+ },
1660
+ "link_url": {
1661
+ "type": "string"
1662
+ },
1663
+ "source_url": {
1664
+ "type": "string"
1665
+ },
1666
+ "import_status": {
1667
+ "type": "string"
1668
+ },
1669
+ "import_failed_reason": {
1670
+ "type": "string"
1671
+ },
1672
+ "image_count": {
1673
+ "type": "integer"
1674
+ },
1675
+ "usable_image_count": {
1676
+ "type": "integer"
1677
+ },
1678
+ "images": {
1679
+ "type": "array",
1680
+ "items": {
1681
+ "type": "object",
1682
+ "properties": {
1683
+ "image_id": {
1684
+ "type": "string"
1685
+ },
1686
+ "url": {
1687
+ "type": "string"
1688
+ },
1689
+ "filename": {
1690
+ "type": "string"
1691
+ },
1692
+ "usable": {
1693
+ "type": "boolean"
1694
+ },
1695
+ "selected": {
1696
+ "type": "boolean"
1697
+ }
1698
+ },
1699
+ "required": [
1700
+ "image_id",
1701
+ "url",
1702
+ "filename",
1703
+ "usable",
1704
+ "selected"
1705
+ ]
1706
+ }
1707
+ },
1708
+ "state": {
1709
+ "type": "string"
1710
+ },
1711
+ "brand": {
1712
+ "type": "object",
1713
+ "properties": {
1714
+ "brand_id": {
1715
+ "type": "string"
1716
+ },
1717
+ "name": {
1718
+ "type": "string"
1719
+ },
1720
+ "target_market": {
1721
+ "type": [
1722
+ "string",
1723
+ "null"
1724
+ ]
1725
+ },
1726
+ "keywords": {
1727
+ "type": "array",
1728
+ "items": {
1729
+ "type": "string"
1730
+ }
1731
+ }
1732
+ },
1733
+ "required": [
1734
+ "brand_id",
1735
+ "name",
1736
+ "keywords"
1737
+ ]
1738
+ },
1739
+ "brand_decision_required": {
1740
+ "type": "object",
1741
+ "properties": {
1742
+ "drafting": {
1743
+ "type": "boolean"
1744
+ },
1745
+ "reason": {
1746
+ "type": "string"
1747
+ },
1748
+ "detected_brand_name": {
1749
+ "type": [
1750
+ "string",
1751
+ "null"
1752
+ ]
1753
+ },
1754
+ "existing_brands": {
1755
+ "type": "array",
1756
+ "items": {
1757
+ "type": "object",
1758
+ "properties": {
1759
+ "brand_id": {
1760
+ "type": "string"
1761
+ },
1762
+ "name": {
1763
+ "type": "string"
1764
+ },
1765
+ "target_market": {
1766
+ "type": [
1767
+ "string",
1768
+ "null"
1769
+ ]
1770
+ },
1771
+ "keywords": {
1772
+ "type": "array",
1773
+ "items": {
1774
+ "type": "string"
1775
+ }
1776
+ }
1777
+ },
1778
+ "required": [
1779
+ "brand_id",
1780
+ "name",
1781
+ "keywords"
1782
+ ]
1783
+ }
1784
+ },
1785
+ "can_create_brand": {
1786
+ "type": "boolean"
1787
+ },
1788
+ "brand_limit": {
1789
+ "type": [
1790
+ "integer",
1791
+ "null"
1792
+ ]
1793
+ },
1794
+ "brands_used": {
1795
+ "type": "integer"
1796
+ },
1797
+ "resolve_with": {
1798
+ "type": "string"
1799
+ }
1800
+ },
1801
+ "required": [
1802
+ "drafting"
1803
+ ]
1804
+ },
1805
+ "workbench_url": {
1806
+ "type": "string"
1807
+ },
1808
+ "video_direction": {
1809
+ "type": "object",
1810
+ "properties": {
1811
+ "video_request_id": {
1812
+ "type": "string"
1813
+ },
1814
+ "drafting": {
1815
+ "type": "boolean"
1816
+ },
1817
+ "creative_direction": {
1818
+ "type": "string"
1819
+ },
1820
+ "draft_failed": {
1821
+ "type": "boolean"
1822
+ },
1823
+ "draft_error": {
1824
+ "type": "string"
1825
+ },
1826
+ "creator_note": {
1827
+ "type": "string"
1828
+ },
1829
+ "format": {
1830
+ "type": "string"
1831
+ },
1832
+ "format_options": {
1833
+ "type": "array",
1834
+ "items": {
1835
+ "type": "object",
1836
+ "properties": {
1837
+ "key": {
1838
+ "type": "string"
1839
+ },
1840
+ "summary": {
1841
+ "type": "string"
1842
+ }
1843
+ },
1844
+ "required": [
1845
+ "key",
1846
+ "summary"
1847
+ ]
1848
+ }
1849
+ },
1850
+ "selected_image_ids": {
1851
+ "type": "array",
1852
+ "items": {
1853
+ "type": "string"
1854
+ }
1855
+ },
1856
+ "ratio": {
1857
+ "type": "string"
1858
+ },
1859
+ "resolution": {
1860
+ "type": "string"
1861
+ },
1862
+ "duration_seconds": {
1863
+ "type": "integer"
1864
+ },
1865
+ "enable_audio": {
1866
+ "type": "boolean"
1867
+ },
1868
+ "target_market": {
1869
+ "type": "string"
1870
+ },
1871
+ "credit_cost": {
1872
+ "type": "number"
1873
+ },
1874
+ "affordable": {
1875
+ "type": "boolean"
1876
+ },
1877
+ "editable": {
1878
+ "type": "boolean"
1879
+ }
1880
+ },
1881
+ "required": [
1882
+ "video_request_id",
1883
+ "drafting",
1884
+ "draft_failed",
1885
+ "format_options",
1886
+ "selected_image_ids",
1887
+ "credit_cost",
1888
+ "editable"
1889
+ ]
1890
+ },
1891
+ "videos": {
1892
+ "type": "array",
1893
+ "items": {
1894
+ "type": "object",
1895
+ "properties": {
1896
+ "video_request_id": {
1897
+ "type": "string"
1898
+ },
1899
+ "status": {
1900
+ "type": "string"
1901
+ },
1902
+ "failed_reason": {
1903
+ "type": "string"
1904
+ },
1905
+ "output_url": {
1906
+ "type": "string"
1907
+ },
1908
+ "watermarked": {
1909
+ "type": "boolean"
1910
+ },
1911
+ "duration_seconds": {
1912
+ "type": "integer"
1913
+ },
1914
+ "script": {
1915
+ "type": "string"
1916
+ },
1917
+ "share_url": {
1918
+ "type": "string"
1919
+ }
1920
+ },
1921
+ "required": [
1922
+ "video_request_id",
1923
+ "status"
1924
+ ]
1925
+ }
1926
+ },
1927
+ "next_step": {
1928
+ "type": "string"
1929
+ },
1930
+ "identity_replaced": {
1931
+ "type": "object",
1932
+ "properties": {
1933
+ "brand_id": {
1934
+ "type": "string"
1935
+ },
1936
+ "name": {
1937
+ "type": "string"
1938
+ },
1939
+ "target_market": {
1940
+ "type": [
1941
+ "string",
1942
+ "null"
1943
+ ]
1944
+ },
1945
+ "keywords": {
1946
+ "type": "array",
1947
+ "items": {
1948
+ "type": "string"
1949
+ }
1950
+ }
1951
+ },
1952
+ "required": [
1953
+ "brand_id",
1954
+ "name",
1955
+ "keywords"
1956
+ ]
1957
+ }
1958
+ },
1959
+ "required": [
1960
+ "product_id",
1961
+ "image_count",
1962
+ "usable_image_count",
1963
+ "images",
1964
+ "state",
1965
+ "workbench_url",
1966
+ "videos"
1967
+ ],
1968
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
1969
+ },
1970
+ "annotations": {
1971
+ "readOnlyHint": false,
1972
+ "destructiveHint": true,
1973
+ "idempotentHint": false,
1974
+ "openWorldHint": true
1975
+ }
1976
+ },
1977
+ {
1978
+ "name": "update_brand",
1979
+ "title": "Edit a brand's identity",
1980
+ "description": "Edit a brand: `name`, `voice` (how it sounds — a few sentences),\n`target_market` (where it sells, e.g. \"US/North America\"; it drives the\nspoken language) and `keywords` (the themes drafts lean on; the list you\npass replaces the old one). This is the identity every video for the\nbrand's products is drafted against. Drafts already written keep their\ntext — `redraft_video_direction` on a product to use the new identity.\n\nOnly the fields you pass change. `list_brands` has the ids and the\ncurrent values. This does not spend credits.\n",
1981
+ "inputSchema": {
1982
+ "type": "object",
1983
+ "properties": {
1984
+ "brand_id": {
1985
+ "type": "string",
1986
+ "description": "The brand's id, from list_brands."
1987
+ },
75
1988
  "name": {
76
1989
  "type": "string",
77
- "description": "Product name."
1990
+ "description": "The brand's name."
78
1991
  },
79
- "description": {
1992
+ "voice": {
80
1993
  "type": "string",
81
- "description": "Optional. What the product is, in a sentence or two — feeds the direction draft."
1994
+ "description": "How the brand sounds, in a few sentences."
82
1995
  },
83
- "creator_note": {
1996
+ "target_market": {
84
1997
  "type": "string",
85
- "description": "Optional. A short free-text note to the director: the angle, occasion or message this video should carry."
1998
+ "description": "Free text, e.g. \"US/North America\" or \"Japan\"."
86
1999
  },
87
- "brand_id": {
88
- "type": "string",
89
- "description": "Optional, and only when the user has said which brand this product belongs to (from `list_brands`). Omit it and the product waits on a brand decision instead of falling through to the account's default brand."
2000
+ "keywords": {
2001
+ "type": "array",
2002
+ "items": {
2003
+ "type": "string"
2004
+ },
2005
+ "description": "The themes drafts lean on. Replaces the whole list."
90
2006
  }
91
2007
  },
92
2008
  "required": [
93
- "image_urls",
94
- "name"
2009
+ "brand_id"
95
2010
  ],
96
2011
  "$schema": "https://json-schema.org/draft/2020-12/schema"
97
2012
  },
98
- "annotations": {
99
- "readOnlyHint": false,
100
- "destructiveHint": false,
101
- "idempotentHint": false,
102
- "openWorldHint": true
103
- }
104
- },
105
- {
106
- "name": "get_product",
107
- "title": "Get a product and its video direction",
108
- "description": "Read a product: what the import found, the current video direction and\nsettings, and every video generated from it.\n\nUse this to poll after `import_product_from_url` or\n`create_product_from_images`. The product is ready to work with when\n`import_status` is \"imported\", there is no `brand_decision_required`,\nAND `video_direction.drafting` is false. If a brand decision is present\nwith `drafting: false`, ask the user to choose a brand and resolve it\nwith `create_brand` or `set_product_brand` before waiting for a direction.\nPoll every 20-30 seconds while import or drafting is in progress.\n\n`import_status` values: \"pending\" and \"importing\" mean keep polling;\n\"imported\" means done; \"failed\" means it did not work and\n`import_failed_reason` says why.\n\n`video_direction.credit_cost` is what `generate_video` will charge for\nthe current settings.\n\nOnce generation has started the direction is locked and\n`video_direction.editable` is false. Editing or redrafting then opens\nthe next video's draft, and `next_step` says so.\n",
109
- "inputSchema": {
2013
+ "outputSchema": {
110
2014
  "type": "object",
111
2015
  "properties": {
112
- "product_id": {
113
- "type": "string",
114
- "description": "The product's id."
2016
+ "brand_id": {
2017
+ "type": "string"
2018
+ },
2019
+ "name": {
2020
+ "type": "string"
2021
+ },
2022
+ "target_market": {
2023
+ "type": [
2024
+ "string",
2025
+ "null"
2026
+ ]
2027
+ },
2028
+ "keywords": {
2029
+ "type": "array",
2030
+ "items": {
2031
+ "type": "string"
2032
+ }
2033
+ },
2034
+ "voice": {
2035
+ "type": [
2036
+ "string",
2037
+ "null"
2038
+ ]
2039
+ },
2040
+ "configured": {
2041
+ "type": "boolean"
2042
+ },
2043
+ "is_default": {
2044
+ "type": "boolean"
2045
+ },
2046
+ "product_count": {
2047
+ "type": "integer"
2048
+ },
2049
+ "next_step": {
2050
+ "type": "string"
115
2051
  }
116
2052
  },
117
2053
  "required": [
118
- "product_id"
2054
+ "brand_id",
2055
+ "name",
2056
+ "keywords",
2057
+ "configured",
2058
+ "is_default",
2059
+ "product_count",
2060
+ "next_step"
119
2061
  ],
120
2062
  "$schema": "https://json-schema.org/draft/2020-12/schema"
121
2063
  },
122
2064
  "annotations": {
123
- "readOnlyHint": true,
124
- "destructiveHint": false,
2065
+ "readOnlyHint": false,
2066
+ "destructiveHint": true,
125
2067
  "idempotentHint": true,
126
2068
  "openWorldHint": false
127
2069
  }
128
2070
  },
129
2071
  {
130
- "name": "create_brand",
131
- "title": "Create a brand for a product",
132
- "description": "Create a new brand for a product that is waiting on\n`brand_decision_required`, and attach the product to it.\n\nUse this when the product belongs to a company the account has no brand\nfor yet — the usual case when someone brings a new store. For a product\nimported from a URL the brand's name, voice, target market and keywords\nare taken from what the storefront scrape drafted; the user can rename\nit with `name`. For a product created from photos nothing was detected\n(`detected_brand_name` is null), so `name` is required and `voice`,\n`target_market` and `keywords` should come from the user — ask them how\nthe brand sounds and who it sells to. Anything you pass overrides the\ndetected value.\n\nAsk the user before calling this. It consumes one of the plan's brand\nslots, and on a plan that has run out this fails with a brand-limit\nerror — at which point the choices are to attach the product to an\nexisting brand with `set_product_brand`, to re-point an existing brand\nat this identity with `set_product_brand` and `replace_identity: true`,\nor to upgrade.\n\nOnce this returns, the video direction starts drafting: poll\n`get_product` until `video_direction.drafting` is false.\n\nDirection drafting sends product facts, photos and brand context to\nan external AI service when the product is ready and its brand is settled.\n\nThis does not spend credits.\n",
2072
+ "name": "update_product",
2073
+ "title": "Edit a product's facts, link and photos",
2074
+ "description": "Edit what a product says about itself. `name`, `description` and\n`price` are the facts the direction draft is written from — fix a\nscrape that got them wrong, then `redraft_video_direction` so the next\ndraft uses them (the response's `next_step` says so when a direction\nalready exists). `link_url` is the product link posted with the video\nand shown on its share page: http(s) only, or empty to clear it.\n\n`add_image_urls` downloads hosted photos and adds them to the product;\n`add_image_files` does the same for photos the user attached to the\nconversation, for clients that pass attachments to tools (ChatGPT\nfills it in — do not build it by hand). Up to 9 per call\nand 8 MB each; the usable ones join the render's selection while\nthere is room, as the workbench's \"+\" tile does, and photos added to\na product whose import failed complete that import. `remove_image_ids`\ndeletes photos by the image_id `get_product` lists; a removed photo\nleaves the selection by itself. Only the fields you pass change;\n`get_product` shows `price` and `link_url` while they are set.\n\nThis does not spend credits.\n",
133
2075
  "inputSchema": {
134
2076
  "type": "object",
135
2077
  "properties": {
136
2078
  "product_id": {
137
2079
  "type": "string",
138
- "description": "The product waiting on a brand decision."
2080
+ "description": "The product's id."
139
2081
  },
140
2082
  "name": {
141
2083
  "type": "string",
142
- "description": "The brand's name. Optional when a storefront name was detected (it overrides it); required for a product created from photos."
2084
+ "description": "The product's name."
143
2085
  },
144
- "voice": {
2086
+ "description": {
145
2087
  "type": "string",
146
- "description": "Optional. How the brand talks, in a sentence or two — the tone every video direction is drafted in."
2088
+ "description": "What the product is; the draft reads it. Empty clears it."
147
2089
  },
148
- "target_market": {
2090
+ "price": {
149
2091
  "type": "string",
150
- "description": "Optional. Who the brand sells to, as \"Region, Language\" (e.g. \"US, English\"). Sets the market and spoken language of every video on the brand."
2092
+ "description": "Free text as the store shows it, e.g. \"$29\" or \"¥3,980\". Empty clears it."
151
2093
  },
152
- "keywords": {
2094
+ "link_url": {
2095
+ "type": "string",
2096
+ "description": "The product link posted with the video. http(s) only; empty clears it."
2097
+ },
2098
+ "add_image_urls": {
153
2099
  "type": "array",
154
2100
  "items": {
155
2101
  "type": "string"
156
2102
  },
157
- "description": "Optional. A few short keywords for the brand's themes and audience — generic enough to survive a different product."
2103
+ "description": "Hosted image URLs to download and add, in the order they should appear."
2104
+ },
2105
+ "add_image_files": {
2106
+ "type": "array",
2107
+ "items": {
2108
+ "type": "object",
2109
+ "properties": {
2110
+ "download_url": {
2111
+ "type": "string"
2112
+ },
2113
+ "file_id": {
2114
+ "type": "string"
2115
+ },
2116
+ "mime_type": {
2117
+ "type": "string"
2118
+ },
2119
+ "file_name": {
2120
+ "type": "string"
2121
+ }
2122
+ },
2123
+ "required": [
2124
+ "download_url",
2125
+ "file_id"
2126
+ ],
2127
+ "additionalProperties": false
2128
+ },
2129
+ "description": "Photos attached to the conversation, as the client supplies them (a download_url and file_id per file). Leave it out unless the client filled it in."
2130
+ },
2131
+ "remove_image_ids": {
2132
+ "type": "array",
2133
+ "items": {
2134
+ "type": "string"
2135
+ },
2136
+ "description": "image_id values from get_product's images to delete."
158
2137
  }
159
2138
  },
160
2139
  "required": [
@@ -162,36 +2141,300 @@
162
2141
  ],
163
2142
  "$schema": "https://json-schema.org/draft/2020-12/schema"
164
2143
  },
165
- "annotations": {
166
- "readOnlyHint": false,
167
- "destructiveHint": false,
168
- "idempotentHint": false,
169
- "openWorldHint": true
170
- }
171
- },
172
- {
173
- "name": "set_product_brand",
174
- "title": "Attach a product to an existing brand",
175
- "description": "Attach a product waiting on `brand_decision_required` to one of the\naccount's existing brands. Use `list_brands` to see them.\n\nOnly do this when the user has confirmed the product really belongs to\nthat brand. Attaching a product to an unrelated brand is not a cosmetic\nmislabel: every video is drafted in that brand's voice, to its target\nmarket, with its keywords.\n\nBy default the brand's existing identity is left untouched. Pass\n`replace_identity: true` to instead overwrite that brand's voice, target\nmarket and keywords with the identity detected on this product — the\n\"re-point my brand at a different company\" move, for an account at its\nbrand limit. This rewrites a brand every other product on it shares, so\nconfirm it with the user explicitly first.\n\nOnce this returns, the video direction starts drafting: poll\n`get_product` until `video_direction.drafting` is false.\n\nReplacement also applies nonempty detected logo and colors, and can\nname an existing Default brand shell. Blank draft fields preserve saved\nvalues. An uploaded logo replaces the attached logo.\n\nDirection drafting sends product facts, photos and brand context to\nan external AI service when the product is ready and its brand is settled.\n\nThis does not spend credits.\n",
176
- "inputSchema": {
2144
+ "outputSchema": {
177
2145
  "type": "object",
178
2146
  "properties": {
179
2147
  "product_id": {
180
- "type": "string",
181
- "description": "The product waiting on a brand decision."
2148
+ "type": "string"
182
2149
  },
183
- "brand_id": {
184
- "type": "string",
185
- "description": "The brand to attach it to, from `list_brands`."
2150
+ "name": {
2151
+ "type": "string"
186
2152
  },
187
- "replace_identity": {
188
- "type": "boolean",
189
- "description": "Optional, default false. Overwrite the brand's voice, target market and keywords with this product's detected identity. Also applies logo and colors; blank fields are preserved. Affects every product on that brand — confirm with the user."
2153
+ "description": {
2154
+ "type": "string"
2155
+ },
2156
+ "price": {
2157
+ "type": "string"
2158
+ },
2159
+ "link_url": {
2160
+ "type": "string"
2161
+ },
2162
+ "source_url": {
2163
+ "type": "string"
2164
+ },
2165
+ "import_status": {
2166
+ "type": "string"
2167
+ },
2168
+ "import_failed_reason": {
2169
+ "type": "string"
2170
+ },
2171
+ "image_count": {
2172
+ "type": "integer"
2173
+ },
2174
+ "usable_image_count": {
2175
+ "type": "integer"
2176
+ },
2177
+ "images": {
2178
+ "type": "array",
2179
+ "items": {
2180
+ "type": "object",
2181
+ "properties": {
2182
+ "image_id": {
2183
+ "type": "string"
2184
+ },
2185
+ "url": {
2186
+ "type": "string"
2187
+ },
2188
+ "filename": {
2189
+ "type": "string"
2190
+ },
2191
+ "usable": {
2192
+ "type": "boolean"
2193
+ },
2194
+ "selected": {
2195
+ "type": "boolean"
2196
+ }
2197
+ },
2198
+ "required": [
2199
+ "image_id",
2200
+ "url",
2201
+ "filename",
2202
+ "usable",
2203
+ "selected"
2204
+ ]
2205
+ }
2206
+ },
2207
+ "state": {
2208
+ "type": "string"
2209
+ },
2210
+ "brand": {
2211
+ "type": "object",
2212
+ "properties": {
2213
+ "brand_id": {
2214
+ "type": "string"
2215
+ },
2216
+ "name": {
2217
+ "type": "string"
2218
+ },
2219
+ "target_market": {
2220
+ "type": [
2221
+ "string",
2222
+ "null"
2223
+ ]
2224
+ },
2225
+ "keywords": {
2226
+ "type": "array",
2227
+ "items": {
2228
+ "type": "string"
2229
+ }
2230
+ }
2231
+ },
2232
+ "required": [
2233
+ "brand_id",
2234
+ "name",
2235
+ "keywords"
2236
+ ]
2237
+ },
2238
+ "brand_decision_required": {
2239
+ "type": "object",
2240
+ "properties": {
2241
+ "drafting": {
2242
+ "type": "boolean"
2243
+ },
2244
+ "reason": {
2245
+ "type": "string"
2246
+ },
2247
+ "detected_brand_name": {
2248
+ "type": [
2249
+ "string",
2250
+ "null"
2251
+ ]
2252
+ },
2253
+ "existing_brands": {
2254
+ "type": "array",
2255
+ "items": {
2256
+ "type": "object",
2257
+ "properties": {
2258
+ "brand_id": {
2259
+ "type": "string"
2260
+ },
2261
+ "name": {
2262
+ "type": "string"
2263
+ },
2264
+ "target_market": {
2265
+ "type": [
2266
+ "string",
2267
+ "null"
2268
+ ]
2269
+ },
2270
+ "keywords": {
2271
+ "type": "array",
2272
+ "items": {
2273
+ "type": "string"
2274
+ }
2275
+ }
2276
+ },
2277
+ "required": [
2278
+ "brand_id",
2279
+ "name",
2280
+ "keywords"
2281
+ ]
2282
+ }
2283
+ },
2284
+ "can_create_brand": {
2285
+ "type": "boolean"
2286
+ },
2287
+ "brand_limit": {
2288
+ "type": [
2289
+ "integer",
2290
+ "null"
2291
+ ]
2292
+ },
2293
+ "brands_used": {
2294
+ "type": "integer"
2295
+ },
2296
+ "resolve_with": {
2297
+ "type": "string"
2298
+ }
2299
+ },
2300
+ "required": [
2301
+ "drafting"
2302
+ ]
2303
+ },
2304
+ "workbench_url": {
2305
+ "type": "string"
2306
+ },
2307
+ "video_direction": {
2308
+ "type": "object",
2309
+ "properties": {
2310
+ "video_request_id": {
2311
+ "type": "string"
2312
+ },
2313
+ "drafting": {
2314
+ "type": "boolean"
2315
+ },
2316
+ "creative_direction": {
2317
+ "type": "string"
2318
+ },
2319
+ "draft_failed": {
2320
+ "type": "boolean"
2321
+ },
2322
+ "draft_error": {
2323
+ "type": "string"
2324
+ },
2325
+ "creator_note": {
2326
+ "type": "string"
2327
+ },
2328
+ "format": {
2329
+ "type": "string"
2330
+ },
2331
+ "format_options": {
2332
+ "type": "array",
2333
+ "items": {
2334
+ "type": "object",
2335
+ "properties": {
2336
+ "key": {
2337
+ "type": "string"
2338
+ },
2339
+ "summary": {
2340
+ "type": "string"
2341
+ }
2342
+ },
2343
+ "required": [
2344
+ "key",
2345
+ "summary"
2346
+ ]
2347
+ }
2348
+ },
2349
+ "selected_image_ids": {
2350
+ "type": "array",
2351
+ "items": {
2352
+ "type": "string"
2353
+ }
2354
+ },
2355
+ "ratio": {
2356
+ "type": "string"
2357
+ },
2358
+ "resolution": {
2359
+ "type": "string"
2360
+ },
2361
+ "duration_seconds": {
2362
+ "type": "integer"
2363
+ },
2364
+ "enable_audio": {
2365
+ "type": "boolean"
2366
+ },
2367
+ "target_market": {
2368
+ "type": "string"
2369
+ },
2370
+ "credit_cost": {
2371
+ "type": "number"
2372
+ },
2373
+ "affordable": {
2374
+ "type": "boolean"
2375
+ },
2376
+ "editable": {
2377
+ "type": "boolean"
2378
+ }
2379
+ },
2380
+ "required": [
2381
+ "video_request_id",
2382
+ "drafting",
2383
+ "draft_failed",
2384
+ "format_options",
2385
+ "selected_image_ids",
2386
+ "credit_cost",
2387
+ "editable"
2388
+ ]
2389
+ },
2390
+ "videos": {
2391
+ "type": "array",
2392
+ "items": {
2393
+ "type": "object",
2394
+ "properties": {
2395
+ "video_request_id": {
2396
+ "type": "string"
2397
+ },
2398
+ "status": {
2399
+ "type": "string"
2400
+ },
2401
+ "failed_reason": {
2402
+ "type": "string"
2403
+ },
2404
+ "output_url": {
2405
+ "type": "string"
2406
+ },
2407
+ "watermarked": {
2408
+ "type": "boolean"
2409
+ },
2410
+ "duration_seconds": {
2411
+ "type": "integer"
2412
+ },
2413
+ "script": {
2414
+ "type": "string"
2415
+ },
2416
+ "share_url": {
2417
+ "type": "string"
2418
+ }
2419
+ },
2420
+ "required": [
2421
+ "video_request_id",
2422
+ "status"
2423
+ ]
2424
+ }
2425
+ },
2426
+ "next_step": {
2427
+ "type": "string"
190
2428
  }
191
2429
  },
192
2430
  "required": [
193
2431
  "product_id",
194
- "brand_id"
2432
+ "image_count",
2433
+ "usable_image_count",
2434
+ "images",
2435
+ "state",
2436
+ "workbench_url",
2437
+ "videos"
195
2438
  ],
196
2439
  "$schema": "https://json-schema.org/draft/2020-12/schema"
197
2440
  },
@@ -200,12 +2443,17 @@
200
2443
  "destructiveHint": true,
201
2444
  "idempotentHint": false,
202
2445
  "openWorldHint": true
2446
+ },
2447
+ "_meta": {
2448
+ "openai/fileParams": [
2449
+ "add_image_files"
2450
+ ]
203
2451
  }
204
2452
  },
205
2453
  {
206
2454
  "name": "update_video_direction",
207
2455
  "title": "Edit the video direction and render settings",
208
- "description": "Edit the creative direction and render settings for a product's next\nvideo. Only the fields you pass are changed; everything else keeps its\ncurrent value. Supplied text replaces the saved text; an empty creative\ndirection clears it. A target_market change updates the shared brand\nand affects future videos for its other products.\n\n`creative_direction` is the plan the render is built from. It is free\ntext, but the drafts follow a six-section shape that works well and is\nworth preserving when editing:\n\n Hook: ...\n Content Focus: ...\n Format: ...\n Suggesting Visual Aesthetic: ...\n Execution Guidelines: ...\n Strict Guidelines & Restrictions: ...\n\nDo not invent a direction from nothing when one has not been drafted\nyet — call `redraft_video_direction` and edit what comes back. Leaving\nit empty is also valid: generation works without a direction.\n\n`creator_note` is different and smaller: the user's own short note to\nthe director (\"mention it is machine washable\", \"for Father's Day\"). It\nis carried through to the render verbatim, so put the user's words in\nit, not your paraphrase.\n\nA target_market change after a direction exists gets a `next_step` in\nthe response: the direction's wording sets the spoken language, so it\nneeds a redraft (or an edit) to match the new market.\n\nA launched video cannot change: if the product's last video has\nalready launched, this opens the next video's draft (seeded from that\nvideo) and edits that; the response says `opened_new_video: true` and\ncarries the new video_request_id.\n\nThis does not spend credits.\n",
2456
+ "description": "Edit the creative direction and render settings for a product's next\nvideo. Only the fields you pass are changed; everything else keeps its\ncurrent value. Supplied text replaces the saved text; an empty creative\ndirection clears it. A target_market change updates the shared brand\nand affects future videos for its other products.\n\n`creative_direction` is the plan the render is built from. It is free\ntext, but the drafts follow a six-section shape that works well and is\nworth preserving when editing:\n\n Hook: ...\n Content Focus: ...\n Format: ...\n Suggesting Visual Aesthetic: ...\n Execution Guidelines: ...\n Strict Guidelines & Restrictions: ...\n\nDo not invent a direction from nothing when one has not been drafted\nyet — call `redraft_video_direction` and edit what comes back. Leaving\nit empty is also valid: generation works without a direction.\n\n`creator_note` is different and smaller: the user's own short note to\nthe director (\"mention it is machine washable\", \"for Father's Day\"). It\nis carried through to the render verbatim, so put the user's words in\nit, not your paraphrase.\n\n`selected_image_ids` chooses which of the product's photos the render\nuses, in order, by the image_id `get_product` lists under `images`\n(usable ones only, at most 9); an empty list restores the\ndefault, the first usable ones. The poll's `selected_image_ids` shows\nwhat would go out now.\n\n`duration_seconds` is the render length — 15, 20, 25 or 30 — and a\nsetting, not part of the direction: writing \"20 seconds\" into the text\nchanges nothing. Longer costs more; the response's `credit_cost` is\nthe new price, and the user must hear it before `generate_video`.\nAbove the plan's ceiling it clamps like resolution (free: 20s).\n\nA target_market change after a direction exists gets a `next_step` in\nthe response: the direction's wording sets the spoken language, so it\nneeds a redraft (or an edit) to match the new market.\n\nA launched video cannot change: if the product's last video has\nalready launched, this opens the next video's draft (seeded from that\nvideo) and edits that; the response says `opened_new_video: true` and\ncarries the new video_request_id.\n\nThis does not spend credits.\n",
209
2457
  "inputSchema": {
210
2458
  "type": "object",
211
2459
  "properties": {
@@ -240,6 +2488,23 @@
240
2488
  ],
241
2489
  "description": "1080P is available to credit-pack purchasers and eligible tiers; a pick above the account's ceiling becomes that ceiling (the response reports what was actually saved)."
242
2490
  },
2491
+ "duration_seconds": {
2492
+ "type": "integer",
2493
+ "enum": [
2494
+ 15,
2495
+ 20,
2496
+ 25,
2497
+ 30
2498
+ ],
2499
+ "description": "Render length in seconds. Priced per second, so the response's credit_cost changes with it; a pick above the plan's ceiling becomes that ceiling (free accounts: 20). The direction text never sets the length — this does."
2500
+ },
2501
+ "selected_image_ids": {
2502
+ "type": "array",
2503
+ "items": {
2504
+ "type": "string"
2505
+ },
2506
+ "description": "The photos the render uses, in order, by image_id from get_product's images; usable ones only, at most 9. An empty list restores the default (the first usable ones)."
2507
+ },
243
2508
  "enable_audio": {
244
2509
  "type": "boolean",
245
2510
  "description": "Whether the render has sound."
@@ -254,6 +2519,101 @@
254
2519
  ],
255
2520
  "$schema": "https://json-schema.org/draft/2020-12/schema"
256
2521
  },
2522
+ "outputSchema": {
2523
+ "type": "object",
2524
+ "properties": {
2525
+ "video_request_id": {
2526
+ "type": "string"
2527
+ },
2528
+ "drafting": {
2529
+ "type": "boolean"
2530
+ },
2531
+ "creative_direction": {
2532
+ "type": "string"
2533
+ },
2534
+ "draft_failed": {
2535
+ "type": "boolean"
2536
+ },
2537
+ "draft_error": {
2538
+ "type": "string"
2539
+ },
2540
+ "creator_note": {
2541
+ "type": "string"
2542
+ },
2543
+ "format": {
2544
+ "type": "string"
2545
+ },
2546
+ "format_options": {
2547
+ "type": "array",
2548
+ "items": {
2549
+ "type": "object",
2550
+ "properties": {
2551
+ "key": {
2552
+ "type": "string"
2553
+ },
2554
+ "summary": {
2555
+ "type": "string"
2556
+ }
2557
+ },
2558
+ "required": [
2559
+ "key",
2560
+ "summary"
2561
+ ]
2562
+ }
2563
+ },
2564
+ "selected_image_ids": {
2565
+ "type": "array",
2566
+ "items": {
2567
+ "type": "string"
2568
+ }
2569
+ },
2570
+ "ratio": {
2571
+ "type": "string"
2572
+ },
2573
+ "resolution": {
2574
+ "type": "string"
2575
+ },
2576
+ "duration_seconds": {
2577
+ "type": "integer"
2578
+ },
2579
+ "enable_audio": {
2580
+ "type": "boolean"
2581
+ },
2582
+ "target_market": {
2583
+ "type": "string"
2584
+ },
2585
+ "credit_cost": {
2586
+ "type": "number"
2587
+ },
2588
+ "affordable": {
2589
+ "type": "boolean"
2590
+ },
2591
+ "editable": {
2592
+ "type": "boolean"
2593
+ },
2594
+ "product_id": {
2595
+ "type": "string"
2596
+ },
2597
+ "opened_new_video": {
2598
+ "type": "boolean"
2599
+ },
2600
+ "next_step": {
2601
+ "type": "string"
2602
+ }
2603
+ },
2604
+ "required": [
2605
+ "video_request_id",
2606
+ "drafting",
2607
+ "draft_failed",
2608
+ "format_options",
2609
+ "selected_image_ids",
2610
+ "credit_cost",
2611
+ "editable",
2612
+ "product_id",
2613
+ "opened_new_video"
2614
+ ],
2615
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
2616
+ },
257
2617
  "annotations": {
258
2618
  "readOnlyHint": false,
259
2619
  "destructiveHint": true,
@@ -274,7 +2634,7 @@
274
2634
  },
275
2635
  "format": {
276
2636
  "type": "string",
277
- "description": "Optional. Pin a specific video format instead of letting the drafter pick one — e.g. \"asmr\", \"hands_demo\", \"pov\". Unknown values are ignored, so leave it out unless the user asked for a particular kind of video."
2637
+ "description": "Optional. Pin the angle instead of letting the drafter pick one: a key from video_direction.format_options in get_product (this product's shortlist, or the whole catalogue, each with a one-line summary). Unknown keys are ignored, so leave it out unless the user asked for a particular kind of video."
278
2638
  }
279
2639
  },
280
2640
  "required": [
@@ -282,6 +2642,102 @@
282
2642
  ],
283
2643
  "$schema": "https://json-schema.org/draft/2020-12/schema"
284
2644
  },
2645
+ "outputSchema": {
2646
+ "type": "object",
2647
+ "properties": {
2648
+ "video_request_id": {
2649
+ "type": "string"
2650
+ },
2651
+ "drafting": {
2652
+ "type": "boolean"
2653
+ },
2654
+ "creative_direction": {
2655
+ "type": "string"
2656
+ },
2657
+ "draft_failed": {
2658
+ "type": "boolean"
2659
+ },
2660
+ "draft_error": {
2661
+ "type": "string"
2662
+ },
2663
+ "creator_note": {
2664
+ "type": "string"
2665
+ },
2666
+ "format": {
2667
+ "type": "string"
2668
+ },
2669
+ "format_options": {
2670
+ "type": "array",
2671
+ "items": {
2672
+ "type": "object",
2673
+ "properties": {
2674
+ "key": {
2675
+ "type": "string"
2676
+ },
2677
+ "summary": {
2678
+ "type": "string"
2679
+ }
2680
+ },
2681
+ "required": [
2682
+ "key",
2683
+ "summary"
2684
+ ]
2685
+ }
2686
+ },
2687
+ "selected_image_ids": {
2688
+ "type": "array",
2689
+ "items": {
2690
+ "type": "string"
2691
+ }
2692
+ },
2693
+ "ratio": {
2694
+ "type": "string"
2695
+ },
2696
+ "resolution": {
2697
+ "type": "string"
2698
+ },
2699
+ "duration_seconds": {
2700
+ "type": "integer"
2701
+ },
2702
+ "enable_audio": {
2703
+ "type": "boolean"
2704
+ },
2705
+ "target_market": {
2706
+ "type": "string"
2707
+ },
2708
+ "credit_cost": {
2709
+ "type": "number"
2710
+ },
2711
+ "affordable": {
2712
+ "type": "boolean"
2713
+ },
2714
+ "editable": {
2715
+ "type": "boolean"
2716
+ },
2717
+ "product_id": {
2718
+ "type": "string"
2719
+ },
2720
+ "opened_new_video": {
2721
+ "type": "boolean"
2722
+ },
2723
+ "next_step": {
2724
+ "type": "string"
2725
+ }
2726
+ },
2727
+ "required": [
2728
+ "video_request_id",
2729
+ "drafting",
2730
+ "draft_failed",
2731
+ "format_options",
2732
+ "selected_image_ids",
2733
+ "credit_cost",
2734
+ "editable",
2735
+ "product_id",
2736
+ "opened_new_video",
2737
+ "next_step"
2738
+ ],
2739
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
2740
+ },
285
2741
  "annotations": {
286
2742
  "readOnlyHint": false,
287
2743
  "destructiveHint": true,
@@ -311,6 +2767,79 @@
311
2767
  ],
312
2768
  "$schema": "https://json-schema.org/draft/2020-12/schema"
313
2769
  },
2770
+ "outputSchema": {
2771
+ "type": "object",
2772
+ "properties": {
2773
+ "product_id": {
2774
+ "type": "string"
2775
+ },
2776
+ "opened_new_video": {
2777
+ "type": "boolean"
2778
+ },
2779
+ "queued": {
2780
+ "type": "integer"
2781
+ },
2782
+ "skipped_insufficient_credit": {
2783
+ "type": "integer"
2784
+ },
2785
+ "credits_charged": {
2786
+ "type": "number"
2787
+ },
2788
+ "videos": {
2789
+ "type": "array",
2790
+ "items": {
2791
+ "type": "object",
2792
+ "properties": {
2793
+ "video_request_id": {
2794
+ "type": "string"
2795
+ },
2796
+ "status": {
2797
+ "type": "string"
2798
+ },
2799
+ "failed_reason": {
2800
+ "type": "string"
2801
+ },
2802
+ "output_url": {
2803
+ "type": "string"
2804
+ },
2805
+ "watermarked": {
2806
+ "type": "boolean"
2807
+ },
2808
+ "duration_seconds": {
2809
+ "type": "integer"
2810
+ },
2811
+ "script": {
2812
+ "type": "string"
2813
+ },
2814
+ "share_url": {
2815
+ "type": "string"
2816
+ }
2817
+ },
2818
+ "required": [
2819
+ "video_request_id",
2820
+ "status"
2821
+ ]
2822
+ }
2823
+ },
2824
+ "next_step": {
2825
+ "type": "string"
2826
+ },
2827
+ "credits_remaining": {
2828
+ "type": "number"
2829
+ }
2830
+ },
2831
+ "required": [
2832
+ "product_id",
2833
+ "opened_new_video",
2834
+ "queued",
2835
+ "skipped_insufficient_credit",
2836
+ "credits_charged",
2837
+ "videos",
2838
+ "next_step",
2839
+ "credits_remaining"
2840
+ ],
2841
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
2842
+ },
314
2843
  "annotations": {
315
2844
  "readOnlyHint": false,
316
2845
  "destructiveHint": true,
@@ -335,6 +2864,54 @@
335
2864
  ],
336
2865
  "$schema": "https://json-schema.org/draft/2020-12/schema"
337
2866
  },
2867
+ "outputSchema": {
2868
+ "type": "object",
2869
+ "properties": {
2870
+ "video_request_id": {
2871
+ "type": "string"
2872
+ },
2873
+ "status": {
2874
+ "type": "string"
2875
+ },
2876
+ "failed_reason": {
2877
+ "type": "string"
2878
+ },
2879
+ "output_url": {
2880
+ "type": "string"
2881
+ },
2882
+ "watermarked": {
2883
+ "type": "boolean"
2884
+ },
2885
+ "duration_seconds": {
2886
+ "type": "integer"
2887
+ },
2888
+ "script": {
2889
+ "type": "string"
2890
+ },
2891
+ "share_url": {
2892
+ "type": "string"
2893
+ },
2894
+ "product_id": {
2895
+ "type": "string"
2896
+ },
2897
+ "product_name": {
2898
+ "type": "string"
2899
+ },
2900
+ "workbench_url": {
2901
+ "type": "string"
2902
+ },
2903
+ "next_step": {
2904
+ "type": "string"
2905
+ }
2906
+ },
2907
+ "required": [
2908
+ "video_request_id",
2909
+ "status",
2910
+ "product_id",
2911
+ "workbench_url"
2912
+ ],
2913
+ "$schema": "https://json-schema.org/draft/2020-12/schema"
2914
+ },
338
2915
  "annotations": {
339
2916
  "readOnlyHint": true,
340
2917
  "destructiveHint": false,