Quickads
Create, run and analyze ads
- Category
- Pending
- Primary Subcategory
- Pending
Integration details
Description
QuickAds helps you research successful ads, discover trending hooks, and turn insights into new campaigns. Create AI images and videos, publish posts, launch ad campaigns, run automated agents, and analyze the performance of your content, ads, and ad accounts - all from one place.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Category
- Pending
- Primary Subcategory
- Pending
- Secondary Subcategories
- None listed
- Brand
- Unknown
- Access
- Account required
- First tracked
- 2026-09-24
- Tool count
- 37
- Geography
- US
The broad Category that contains the Primary Subcategory.
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Quickads
Get updates when Quickads’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competitive lineup
37 tools agents can invoke
Re-host a selected image on our storage, describe it, and show it to Claude. Call this after the user picks an image (from search_stock_images / scrape_site_images) or provides an image URL. It: (1) downloads and re-hosts the image on our bucket and returns a stable 'reference_url'; (2) if describe=True, auto-generates a short description of what the image shows; (3) returns the image inline so you can SEE it. Then confirm/refine the description WITH THE USER, and pass 'reference_url' as one of reference_image_urls to generate_clip / generate_video / build_storyboard (remember: reference images cannot be combined with first_frame_url/ last_frame_url). 'purpose' can be 'reference', 'character', 'product', or 'template' — use 'template' for a reference/competitor AD whose style will be cloned via generate_ad_to_ad's template_image_url.
Build a video storyboard from a script/idea. Returns a task_id to poll. 'model' is REQUIRED and must be chosen by the user: first call list_video_models, show the options, and ASK THE USER which model to use — never pick one on their behalf. Poll get_task_status(task_id) until status is 'Completed'. For Seedance 2 models the completed task's 'response' contains the storyboard text — review/edit it, then pass it as the 'prompt' to generate_video. For veo/kling/seedance-1-5-pro the response contains a scene-based storyboard tied to the returned 'project_id' — pass that project_id to generate_video.
Estimate the ai_video_credit cost of a generation vs. the user's balance. ALWAYS call this BEFORE build_storyboard / generate_video / generate_clip and TELL THE USER the cost against their remaining ai_video_credits, then proceed only if they have enough (or explicitly confirm). Cost = per-second rate (model + resolution) × duration, rounded up (min 1). Generating character / product reference sheets does NOT cost ai_video_credits.
Apply a free-text edit to a generated character/product sheet (GPT Image 2 image-to-image). Use to refine a sheet from generate_character / generate_product_sheet (e.g. "make the lighting warmer", "change the shirt to red") while preserving layout and identity. Returns IMMEDIATELY with an auto-polling widget (runs in the background — do NOT poll get_task_status in a loop); the edited sheet appears when ready.
Clone a reference ad's style/layout onto the user's product. Returns a task_id to poll. 'template_image_url' is REQUIRED — it is the reference ad whose style/ layout is being cloned, and this pipeline cannot run without a real image. 'style'/'prompt' only REFINE the clone; they do not replace it. To get that URL, call open_reference_ad_uploader — the employee drops the ad file or pastes its image URL and the widget reports the hosted URL back; if that message doesn't arrive, recover it with get_recent_uploads (take the newest entry whose purpose is 'template'). Never ask the employee to type a URL blind. Pass 'product_image_url' if the user has a product shot; set has_product_image=False if they don't. If the employee gives a website/ product URL instead of a ready image and details, call BOTH get_product_details_from_url AND scrape_product_images_from_url for that URL, then pass the former's 'product_details' object here, the latter's picked/rehosted URL as 'product_image_url', and the SAME url again as 'web_url' (don't ask for it twice — it's the one URL the employee already gave for this ad). IMPORTANT — logo/brand-color source: 'include_logo' and 'include_brand_colors' only have something to apply if 'product_details' carries a populated 'brand' object (dark_logo/light_logo/colors) — that ONLY comes from get_product_details_from_url's return value. Whenever the employee gives a URL, you MUST call get_product_details_from_url and pass its full, unmodified 'product_details' object here — skipping it means the generated ad will silently come out with no logo/brand colors even though those flags are True. DO NOT RETYPE 'product_details' FROM MEMORY. Copy the exact JSON object get_product_details_from_url returned, verbatim, field-for-field — especially the nested 'brand' key (brand.colors.primary/secondary/ tertiary, brand.dark_logo, brand.light_logo, brand.logo). If you reconstruct or summarize it instead of passing the literal object, the 'brand' nested fields are the ones most likely to get dropped, and include_brand_colors/include_logo will then have nothing to apply even though you set them to True. ASK ONE THING PER TURN — this is the most important rule here. Never call a widget tool and ask a question in the same turn (the question card covers the widget), and never stack two questions together. Ask, stop, wait for the answer, then move to the next step. Use the structured multiple-choice UI for each one, not a paragraph. The order: 1. REFERENCE AD — call open_reference_ad_uploader on its own and wait for the hosted URL. Nothing else this turn. 2. PRODUCT SOURCE — ask how the product comes in: a product/brand URL you scrape / they upload a photo / no product image at all (style-only clone). 3. Act on that answer, still one tool-surface per turn: - URL -> get_product_details_from_url, then scrape_product_images_from_url, then wait for their pick - upload -> scrape_product_images_from_url's picker has an upload lane - none -> set has_product_image=False and skip ahead 4. include_logo — yes (default) / no 5. include_brand_colors — yes / no. Brand colours are filled in from the account's saved brand automatically, so "yes" is safe to offer even if you never fetched a brand object yourself. 6. ai_model_name — show the friendly names, pass the model_N string: "Nano Banana" -> "model_1", "Nano Banana Pro" -> "model_2", "Nano Banana 2" -> "model_3" 7. stage — offer these exact strings plus a skip option: "Stage 0: Brand Awareness" / "Stage 1: Customers UNAWARE of PAIN POINTS" / "Stage 2: Aware of the problem but UNAWARE of PRODUCT" / "Stage 3: Aware of product but UNAWARE of RELATIVE BENEFITS" / "Stage 4: Aware of above but CREATE URGENCY to act" / "Stage 5: Retargeting" 8. campaign_objective — suggest "Brand Awareness" / "Traffic" / "Engagement" / "Leads" / "Sales" / "App Promotion", plus free text and a skip option 9. COPY — ask once for custom_heading / custom_subheading / custom_cta / additional_instructions together, leading with a "let AI write all the copy" option so they can clear all four in one tap. Only split into separate turns if they choose to write their own. 10. Then call this tool. Do NOT ask about 'has_product_image' — derive it from step 2/3. Do NOT ask for 'web_url' separately — reuse the product/service URL from step 3. Each generation bills AI credits, so finish the whole sequence before calling; re-running just to add a heading is a wasted charge. What the three context params actually do: - 'stage' shapes the generated ad COPY via funnel-stage messaging guidance. Accepts the exact labels above, "0".."5", or a close paraphrase; anything unresolvable is rejected rather than silently treated as Stage 0. - 'campaign_objective' steers only the post-generation evaluation commentary — it does NOT change the image. Don't oversell it. - 'web_url' is background text/copy enrichment ONLY. It does NOT supply the logo or brand colors — 'product_details' does that. Poll get_task_status(task_id) until 'Completed', then call show_ad_result(task_id=...) to actually display the ad inline — announcing it as ready without that call leaves the employee with text and no picture. The raw URL is in response.data.image_url. This flow DOES deduct AI credits, for every account including brand-new ones — same as the REST endpoint. Do not tell the employee it's free. Generation can occasionally take up to ~5 minutes. Keep calling get_task_status every ~15s and do NOT stop or ask the user whether to keep waiting — only stop once status is 'Completed' or 'Error'. "In Progress" this long is expected, not stuck.
Generate several ad-image variations. Returns a task_id to poll. ASK ONE THING PER TURN — never call a widget tool and ask a question in the same turn (the question card covers the widget), and never stack two questions. Ask, stop, wait, next. Use the structured multiple-choice UI. 1. WHICH KIND of variations — ask this first, before anything else: - "Quick" -> fast visual/layout variety on the same ad. Send auto_selected=False and NO variation_type. - "Auto" -> the layout-preset engine picks the compositions. Send auto_selected=True and NO variation_type. - "Advance" -> copy-focused rewrites. Send variation_type, e.g. ["Tone"] / ["Messaging Angle"] / ["Target Persona"] / ["Visual Layout"] (this is what selects the path). ══ IF THEY CHOSE "AUTO", the flow is SHORT — ask exactly three things and take everything else as-is. Do NOT ask about count, colour hex, text rewrite, logo, headings, CTA, stage or aspect ratio; auto either ignores those or has a sensible default already: A1. BASE AD — call list_my_recent_creatives ALONE, wait for the pick, pass it as 'project_id'. (If they insist on uploading instead, the open_reference_ad_uploader route from step 2 still works.) A2. BRAND COLOURS — include_brand_colors yes / no. That's the only colour question in this mode. A3. MODEL — ai_model_name: show the friendly names and pass the model_N string ("Nano Banana" -> "model_1", "Nano Banana Pro" -> "model_2", "Nano Banana 2" -> "model_3"). Then call this tool with auto_selected=True and nothing else set. The funnel stage defaults to "Stage 3: Aware of product but UNAWARE of RELATIVE BENEFITS" automatically when you leave 'stage' empty on an auto run, so don't ask for it — only pass 'stage' if the employee brings it up unprompted. ══ IF THEY CHOSE "ADVANCE", follow THIS list (it replaces steps 2-8): B0. BASE AD — call list_my_recent_creatives ALONE, wait for the pick, pass it as 'project_id'. B1. TEMPLATES (optional) — ask whether they want the variations built from catalog templates. If yes, call list_ad_templates(multi_select=True) ALONE and wait; pass the ids it reports back as 'variation_template_ids' and add "Visual Layout" to variation_type. THE NUMBER OF TEMPLATES IS THE NUMBER OF VARIATIONS — never ask "how many" in that case; this tool overrides total_variations to match. If they DON'T want templates, ask how many variations instead (advance has no upper limit). B2. MESSAGING ANGLE — yes/no. Yes -> add "Messaging Angle". B3. CUSTOMER STAGE — offer the six stage labels. Yes -> add "Customer Stage" to variation_type AND pass the chosen label as 'stage'. If they decline, leave 'stage' empty; it defaults to "Stage 0: Brand Awareness" on advance runs. B4. TONE — offer: Soft / Casual / Formal / Enthusiastic / Confident / Friendly / Professional / Playful / Sarcastic / Informative / Inspirational / Narrative. If they pick one, add "Tone" to variation_type AND pass it as 'variation_tone'. If they decline, leave it empty (it defaults to "Soft"). B5. ADDITIONAL INFO (optional) — free text, e.g. "keep the background minimal, emphasise the discount badge". Pass as 'additional_info' (NOT 'additional_instructions'). B6. BRAND COLOURS — include_brand_colors yes / no. B7. MODEL — ai_model_name, friendly names -> model_1/2/3. So 'variation_type' is assembled from whichever of B1-B4 they said yes to; it must be non-empty or you are not on the advance path at all. ══ IF THEY CHOSE "QUICK", continue with the full sequence: 2. WHERE THE BASE AD COMES FROM — two options, exactly one wins: - "One of my recent creatives" -> call list_my_recent_creatives ALONE, wait for the picked project_id, pass it as 'project_id'. Nothing else is needed: the pipeline pulls the base image, the product shot AND the brand (colours + logo) straight off that saved project. - "I'll upload an ad" -> call open_reference_ad_uploader ALONE, wait for the hosted URL, pass it as 'template_image_url'. THEN ask for their brand/product URL, call get_product_details_from_url, and pass its object as 'product_details' (that is where brand colours and the logo come from in this path). NEVER send both 'project_id' and 'template_image_url' — the tool rejects that, because the URL would silently win and the picked creative would be ignored. 3. HOW MANY — quick accepts 1-5 only (hard backend limit, this tool rejects more). Advance has no cap. 4. COLOUR — ask this only AFTER their base ad is settled (step 2), and ask it as ONE question with three answers, never as two separate yes/no rounds: - "Use my brand colours" -> include_brand_colors=True, and do NOT ask for a custom colour. - "Use a specific colour" -> call open_color_picker ALONE (pass the chosen ad's URL as base_image_url when you have one) and wait for the hex it reports back; send that as variation_color, and do NOT ask about brand colours. Never ask them to type a hex into chat — an unparseable value is dropped silently by the pipeline. - "Leave the colours alone" -> send neither. These two are mutually exclusive and this tool rejects both together: the pipeline force-disables the brand palette whenever variation_color is set, so asking for both would silently throw the brand away. 5. TEXT — "Should the AI rewrite the ad copy for each variation, or keep the existing text?" Rewrite -> text_variation=True; keep -> False. 6. SETTINGS — include_logo (yes default / no), then ai_model_name: show the friendly names and pass the model_N string — "Nano Banana" -> "model_1", "Nano Banana Pro" -> "model_2", "Nano Banana 2" -> "model_3". 7. COPY — only when text_variation is False and they want to fix the wording themselves: ask once for custom_heading / custom_subheading / custom_cta / additional_instructions together, leading with a "let AI write all the copy" option so they can clear all four in one tap. 8. Then call this tool. Steps 2-8 are the QUICK/ADVANCE sequence — auto uses the short A1-A3 list above instead. The AUTO path drops variation_color, text_variation and include_logo at the dispatch boundary, so this tool rejects the first two rather than pretending they took effect, and asking about the logo there is simply wasted. 'stage' shapes the generated COPY via funnel-stage messaging guidance. Pass one of the exact labels ("Stage 0: Brand Awareness" … "Stage 5: Retargeting"), "0".."5", or a close paraphrase; anything unresolvable is rejected rather than silently treated as Stage 0. On an auto run an empty stage becomes "Stage 3: Aware of product but UNAWARE of RELATIVE BENEFITS". Do NOT ask about 'has_product_image' — derive it. Note that QUICK mode force-disables product replacement server-side, so don't promise a product swap there; use auto or advance if the product must be replaced. IMPORTANT — logo/brand-color source: when you go the UPLOAD route, 'include_logo' / 'include_brand_colors' only have something to apply if 'product_details' carries a populated 'brand' object (colors / dark_logo / light_logo). Pass get_product_details_from_url's object verbatim — do NOT retype or summarise it, the nested 'brand' key is the first thing that gets dropped. (Missing brands are also backfilled from the account's saved brand, so 'yes' is always safe to offer.) When you go the project_id route this is moot — the saved project already has it. DO NOT RETYPE 'product_details' FROM MEMORY. Copy the exact JSON object get_product_details_from_url returned, verbatim, field-for-field — especially the nested 'brand' key (brand.colors.primary/secondary/ tertiary, brand.dark_logo, brand.light_logo, brand.logo). If you reconstruct or summarize it instead of passing the literal object, the 'brand' nested fields are the ones most likely to get dropped, and include_brand_colors/include_logo will then have nothing to apply even though you set them to True. Poll get_task_status(task_id) until 'Completed', then call show_ad_result(task_id=...) to actually display the variations inline (they page 3-at-a-time behind arrows) — announcing them as ready without that call leaves the employee with text and no pictures. The raw URLs are in response.data.image_urls. Generation can occasionally take up to ~5 minutes (more for larger 'total_variations'). Keep calling get_task_status every ~15s and do NOT stop or ask the user whether to keep waiting — only stop once status is 'Completed' or 'Error'. "In Progress" this long is expected, not stuck. This flow DOES deduct AI credits — roughly one per generated variation (two on "Nano Banana Pro"/"Nano Banana 2"), for every account including brand-new ones. So a 5-variation run costs ~5 credits; don't tell the employee it's free, and settle the whole question sequence before calling.
Create a multi-angle CHARACTER reference sheet from one person's photo (GPT Image 2). Use when the user wants a consistent character/avatar in the video. 'image_url' is the main photo; 'additional_image_urls' are optional extra shots of the SAME person for better likeness. Returns IMMEDIATELY with an auto-polling widget (the sheet takes ~1-3 minutes and generates in the background — do NOT poll get_task_status in a loop). When it finishes, the widget shows the sheet; use its URL as a reference_image_urls entry so the character stays consistent.
Generate ONE standalone video clip from a prompt — no storyboard, no project. 'model' is REQUIRED and must be chosen by the user: show them the options (call list_video_models and read each model's 'input_rules') and ASK which to use; never pick one silently. Supports EVERY multimodal model in the registry: bytedance/seedance-2, -fast, -mini; veo-3-1, veo-3-1-fast; kling-3, kling-3-turbo; gemini-omni; seedance-1-5-pro. Each model accepts DIFFERENT inputs — the rules are enforced server-side and a violation returns a clear error: - Seedance 2 (-fast/-mini): text→video, first/last frames, OR up to 9 reference images / 3 videos / 3 audios. 4-15s. - Veo 3.1: text→video or first/last frames only (NO reference images). 4/6/8s. - Veo 3.1 Fast: also reference→video with 1-3 images (forced 8s). - Kling 3.0: text→video or 1-2 frames (NO reference images). 3-15s; resolution sets the mode (720p=std, 1080p=pro, 4k=4K). - Kling 3 Turbo: image-to-video — REQUIRES exactly ONE input image (reference_image_urls). 3-15s. - Kling Motion: motion transfer — REQUIRES a reference image (character, in reference_image_urls) AND one reference video (motion, in reference_video_urls). Optional character_orientation = 'image' (≤10s) | 'video' (≤30s). 720p/1080p. - Kling 3.0 Omni: pass 'mode' = text | image | transformation | reference. text→prompt only; image→first_frame_url (opt last_frame_url); transformation →exactly ONE reference_video_url (source) + optional reference images; reference→reference images and/or one reference_video_url. Optional multi-shot via multi_prompt=[{prompt,duration}] (≤6, each 1-12s, total ≤15s) and 'elements' =[{name,description,element_input_urls}]. 3-15s, 720p/1080p/4k. - Gemini Omni: text→video plus up to 7 reference images and/or 1 reference video (NOT first/last frames). 4/6/8/10s. - Seedance 1.5 Pro: text→video or a first frame. 4/8/12s, 720p. Frames and references are MUTUALLY EXCLUSIVE on every model. Durations snap to each model's allowed set. Before calling, OFFER open_image_uploader so the user can OPTIONALLY upload reference image(s) — pass returned URLs as reference_image_urls (skip the offer if references were already provided). Poll get_task_status(task_id) until 'Completed'; the clip URL is in 'response.video_url'.
Generate a single first-frame / scene IMAGE from a prompt, BEFORE generating a video. Use when the user wants to lock the opening shot / look first (an image they can review, then drive the video from). 'reference_image_urls' optionally steer the look (product, character, style). 'image_model' is any supported image model (all of them accept reference images): 'nanobanana', 'nanobanana_pro', 'nanobanana_2', 'seedream' (Kie.ai) or 'gpt_image_2' (OpenAI GPT Image 2); separator style is forgiving ('nano-banana-2', 'gpt'), but an unrecognised name is REJECTED rather than quietly swapped. Omit it for the default (gpt_image_2). For SEVERAL images that must share a face or product, use generate_image with 'items' instead — consistency only works inside one call. Returns IMMEDIATELY with an auto-polling widget (runs in the background — do NOT poll get_task_status in a loop). When it's ready, show it; if the user approves, pass its URL to generate_video as the first frame (a reference_image_urls entry) so the video starts from that image.
Generate MULTIPLE images at once and show them ALL in ONE grid widget. Use when the user asks for several frames / scenes / images together (e.g. "make 3 scene frames"). 'frames' is a JSON array string; each item is an object: {"prompt": str, "reference_image_urls"?: [str], "aspect_ratio"?: str, "image_model"?: str, "label"?: str} Per-item aspect_ratio / image_model override the tool-level defaults. 'image_model' is any supported image model (all of them accept reference images): 'nanobanana', 'nanobanana_pro', 'nanobanana_2', 'seedream' (Kie.ai) or 'gpt_image_2' (OpenAI GPT Image 2). Separator style is forgiving ('nano-banana-2', 'gpt'), but an unrecognised name is REJECTED rather than quietly swapped for a working one. Omit it for the house default (gpt_image_2). Returns IMMEDIATELY with an auto-polling widget (do NOT poll get_task_status in a loop) that renders EVERY generated image in a grid, each with its own download + copy-link button.
Generate one ad per Quickads ad-template preset. Returns a task_id to poll. 'template_image_ids' must be existing Quickads ad-template UUIDs, not raw image URLs — these come from list_ad_templates(query, stage, has_product_image); call it first to browse/search the catalog and show the gallery widget, then pass the 'template_id' of whichever the employee picks (can be more than one, to batch-generate across several templates in one call). Pass 'product_image_url' for the product to place into each template. If the employee gives a website/product URL instead of a ready image and details, call BOTH get_product_details_from_url AND scrape_product_images_from_url for that URL, then pass the former's 'product_details' object here, the latter's picked/rehosted URL as 'product_image_url', and the SAME url again as 'web_url' (do not ask for it twice — it's the one URL the employee already gave for this ad). IMPORTANT — logo/brand-color source: 'include_logo' and 'include_brand_colors' only have something to apply if 'product_details' carries a populated 'brand' object (dark_logo/light_logo/colors) — that ONLY comes from get_product_details_from_url's return value. 'web_url' is a SEPARATE input used purely for background text/copy enrichment — it does NOT feed the logo or brand colors. So whenever the employee gives a URL, you MUST still call get_product_details_from_url and pass its full, unmodified 'product_details' object here — never call this tool with only 'web_url'/'product_image_url' and no 'product_details', or the generated ad will silently come out with no logo/brand colors even though those flags are True. DO NOT RETYPE 'product_details' FROM MEMORY. Copy the exact JSON object get_product_details_from_url returned, verbatim, field-for-field — especially the nested 'brand' key (brand.colors.primary/secondary/ tertiary, brand.dark_logo, brand.light_logo, brand.logo). If you reconstruct or summarize it instead of passing the literal object, the 'brand' nested fields are the ones most likely to get dropped, and include_brand_colors/include_logo will then have nothing to apply even though you set them to True. ASK ONE THING PER TURN — this is the most important rule here. Never call a widget tool and ask a question in the same turn (the question card covers the widget), and never stack two questions together. Ask, stop, wait for the answer, then move to the next step. Use the structured multiple-choice UI for each one, not a paragraph. The order: 1. TEMPLATE — call list_ad_templates on its own and wait for their pick. Nothing else this turn. 2. PRODUCT — get_product_details_from_url, then scrape_product_images_from_url, then wait for their picked image (one tool-surface per turn). 3. include_logo — yes (default) / no 4. include_brand_colors — yes / no. Brand colours are filled in from the account's saved brand automatically, so "yes" is safe to offer even if you never fetched a brand object yourself. 5. ai_model_name — show the friendly names, pass the model_N string: "Nano Banana" -> "model_1", "Nano Banana Pro" -> "model_2", "Nano Banana 2" -> "model_3" 6. COPY — ask once for custom_heading / custom_subheading / custom_cta / additional_instructions together, leading with a "let AI write all the copy" option so they can clear all four in one tap. Only split into separate turns if they choose to write their own. 7. Then call this tool. Do NOT ask about 'has_product_image' — set it yourself from whether the employee picked a product or service-industry template in step 1 (True for product, False for service). Do NOT ask for 'web_url' separately — reuse the product/service URL from step 2. Poll get_task_status(task_id) until 'Completed', then call show_ad_result(task_id=...) to actually display the ad(s) inline — announcing them as ready without that call leaves the employee with text and no picture. The raw URLs are in response.data.image_urls. EXISTING accounts are credit-metered for this flow; brand-new (recently signed-up) accounts get a free pass — same billing behavior as the REST endpoint. Don't tell an existing account it's free. Generation can occasionally take up to ~5 minutes. Keep calling get_task_status every ~15s and do NOT stop or ask the user whether to keep waiting — only stop once status is 'Completed' or 'Error'. "In Progress" this long is expected, not stuck.
Generate a video from a catalog template (the template flow's final step). 'template_id' comes from recommend_templates. 'prompt' = the dialogue/script / ad copy for the video. 'reference_image_urls' MUST supply the template's required images (see recommend_templates 'image_roles' / 'required_image_count') in order — for Seedance 2 / Short clip templates this is enforced; ClaudeHTML templates work from the script alone (images optional). Returns the inline native player, which POLLS AUTOMATICALLY and updates to the finished video — do NOT poll get_task_status yourself unless the user says it isn't updating.
Generate one image, or a whole consistent set of them, on any supported model. ONE IMAGE — pass 'prompt' and nothing else: generate_image(prompt="a cat on a red sofa, golden hour") generate_image(prompt="this pack on marble", model="gpt_image_2", ratio="4x5", reference_image_urls=["https://…/pack.png"]) MANY IMAGES THAT MUST MATCH EACH OTHER — pass 'items'. This is the reason this tool exists: items can reference each other, so the same face and the same product carry across every frame. That only works INSIDE ONE CALL — separate calls produce visibly different people and packs. Send the whole set at once. Each entry in 'items': prompt (str) required. Name reference images inline as @image1, @image2 … — see the ordering rule below. model (str) "nanobanana" | "nanobanana_pro" | "nanobanana_2" | "seedream" | "gpt_image_2". Separator style is forgiving ("nano-banana-2", "gpt"). Unrecognised names are REJECTED, not silently swapped. Default gpt_image_2 (the house default). ratio (str) "9x16" | "16x9" | "1x1" | "4x5" | "3x4" | "2x3" … URL-safe, no colons. Default 9x16. references (list of str) keys/ids of OTHER items in THIS call, fed in as reference images. The backend topologically sorts these, so list order does not matter — but a cycle is rejected, and an item whose reference failed is skipped rather than generated wrong. reference_image_urls (list of str) hosted http(s) images from outside the call. No effect on ordering. …plus, optionally, ONE of these two ways to address the item: id (str) your own label, so other items can reference it. Use this to chain — frame 2 references frame 1 for continuity. angle/beat/slot storyboard addressing. 'angle' is the angle slug ("a1"), 'slot' is the image's role AND its filename ("char", "product", "first_frame", "end_frame"), 'beat' is the beat id ("b01") or null for angle-level images (character and product sheets). angle + slot must be given TOGETHER; sending one without the other is an error. Omit all three and an id is assigned automatically. Typical storyboard shape: the char and product items have references=[]; each first_frame references ["a1/char", "a1/product"] so the same face and pack appear; each end_frame references the char, the product AND its own first_frame so the shot stays continuous. REFERENCE ORDER IS A CONTRACT: 'references' resolve first, in the order you listed them, then 'reference_image_urls'. @image1 is the first reference and the numbering runs continuously into the URLs. Tool-level 'model' and 'ratio' act as DEFAULTS for items that don't set their own (same convention as generate_frames). Tool-level 'reference_image_urls' is single-image only — with 'items' it has to go on the item that needs it, because reference order is per-item. Returns task_id, accepted (item count) and status. Poll get_image_status(task_id) for the URLs — results stream in level by level, so partial output is visible before the run finishes, and the response body is the only authoritative source of both the URL and the per-item outcome.
Create a PRODUCT turnaround sheet (all angles + detail shots) from product photo(s) (GPT Image 2). Use when the user wants their product shown consistently in the video. Pass one or more product photos. Returns IMMEDIATELY with an auto-polling widget (the sheet takes ~1-3 minutes and generates in the background — do NOT poll get_task_status in a loop). When it finishes, use the sheet's URL as a reference_image_urls entry for generation.
Generate the final video. Returns a task_id to poll. 'model' must be the one the user already chose (if they never picked one, call list_video_models and ask first). For Seedance 2 models pass 'prompt' = the (optionally user-edited) storyboard text from build_storyboard. EVERY other registry model (veo-3-1, veo-3-1-fast, kling-3, kling-3-turbo, gemini-omni, seedance-1-5-pro) generates a SINGLE clip directly from 'prompt' — same as generate_clip — honoring that model's input rules (see list_video_models 'input_rules'); no project_id needed. Before generating, OFFER open_image_uploader so the user can OPTIONALLY upload reference image(s) to steer the look — pass any returned URLs as reference_image_urls (skip the offer if references were already provided). If the user wants to lock the opening shot first, offer generate_frame (a first-frame/scene image) or generate_character (a consistent character) and pass the resulting URL as a reference_image_urls entry. Poll get_task_status(task_id) until 'Completed'; the video URL is in 'response'.
List every avatar in the avatars_lib catalogue, paginated -- the whole library, not a persona match. Use this when the ask is about the library itself rather than about filling a role: "what avatars do we have", "how many South Asian women are in the library", "show me everything added recently", an audit of inactive rows, or any time you need a stable page-by-page walk through the catalogue. For "find someone who fits this character" use search_avatar_references instead -- it ranks by persona fit and hides rows that would wreck a generation; this tool ranks nothing and hides nothing. Filters are the coarse dashboard set and are all exact-match except search_keyword, which is a case-insensitive substring across display_name, file_name, person_id and image_id. 'active' is tri-state: leave it unset for every row, true for live rows only, false to audit what has been retired. There is deliberately no usable_as_reference or face_clear filter here -- a catalogue listing is supposed to show the flawed rows too, which is exactly why you should not feed a row straight from this tool into a generator without checking its usable_as_reference and face_clear values. Rows come back newest-first (createdAt desc) as full avatar records: id, image_id, person_id, display_name, gender, age, age_range, ethnicity, vibe_expression, wardrobe, setting, apparent_class_context, tags, hosted_url, shot_type, angle, face_clear, resolution, resolution_band, orientation, usable_as_reference, review_notes, active, created_at, updated_at. Paging: 'page' is 1-based and 'page_size' is capped at 100. The response carries 'total' (rows matching the filters), 'pages', 'page' and 'page_size' -- read 'pages' rather than guessing when the library ends, and note that rows are one IMAGE each, so one person with six shots occupies six rows. An empty library or a filter that matches nothing returns data: [] with total 0 and a 'message' field; that is a real answer, not an error, so do not retry it.
Poll a generate_image run and get the image URLs back. Returns: status "pending" | "done" | "error" total / completed / failed images one entry per requested item, each with key, id, angle, beat, slot, ratio, model, path, image_url and a per-item status of "done", "failed" or "skipped". "skipped" means one of its references never generated, so it was not attempted — fix that reference and re-run. Results land level by level, so calling this while status is still 'pending' returns the images finished so far. Wait a few seconds between polls; a single image is quick, a full storyboard takes a couple of minutes. This response is the authoritative source for both the URL and the outcome. Do not construct URLs from the path and assume they exist — a failed item has a path and no image.
Get every reference shot on file for one avatars_lib person, by their person_id. Use this once search_avatar_references has picked a person and the storyboard needs more of their shots as references than the search result carried -- e.g. a specific angle or shot_type wasn't in the first batch. Default limit is 3 (matches the dashboard's "top 3" view); raise it if you genuinely need this person's full set. Returns the person's identity fields once (gender, age, ethnicity, vibe_expression, wardrobe, setting, apparent_class_context, tags) plus 'total_images' (their full count, which may exceed what 'images' contains if limit/offset paged it down) and 'images[]' -- each with hosted_url, shot_type, angle, face_clear, resolution_band. Same reference-safety defaults as search_avatar_references (active/usable_as_reference/face_clear/hosted_url), with the same two override flags. Raises an error if person_id doesn't match anyone -- double check it came from a prior search_avatar_references result rather than being guessed.
Extract product/brand details from a website URL (scrape + LLM extraction). ASKING FOR THE URL: when you need a URL and don't have one yet, ask with your structured multiple-choice question UI (a free-text/"other" option plus ~3 suggested URLs), never a plain paragraph. Pick the suggestions yourself, fresh each time rather than reusing a fixed trio, and match them to what's being advertised — real product-brand sites for a product template, real service-business sites for a service-industry template, ideally from the brand/industry the employee already mentioned. Use when the employee gives a product/brand URL instead of typing details by hand. Returns a 'product_details' object — pass it (as JSON, e.g. json.dumps(product_details)) straight into generate_ad_to_ad's, generate_from_ad_template's, or generate_ad_variations' 'product_details'-style inputs where applicable; it already carries product_name, product_description, price, other_information, summery, caption, ideal_customer, industry, product_category, stage, and brand (logo/colors) — no reshaping needed. Pair with scrape_product_images_from_url to also get a product photo from the same site.
Fetch the hosted URLs of images the user recently uploaded in the widget. Call this whenever the user says they uploaded / attached an image (e.g. via the 'Upload your own' tile from open_image_uploader) but you don't yet have its hosted URL — the widget hosts the file on Quickads storage but the URL may not reach you automatically. This returns the most recent uploads (newest first); use the returned http(s) URL(s) as reference_image_urls (or image_url for generate_character) when generating. If it returns nothing, ask the user to click 'Upload your own' again and wait for the ✓. Every entry carries a 'purpose'. MATCH ON IT rather than just taking the newest: a reference AD to clone (for generate_ad_to_ad's template_image_url, uploaded via open_reference_ad_uploader) has purpose='template', while the product-image picker's uploads have purpose='product'. Taking the newest entry blindly grabs the wrong image whenever both widgets were used in the same session.
Get the status of a build_storyboard / generate_video / generate_clip / generate_ad_to_ad / generate_from_ad_template / generate_ad_variations task. Statuses: 'Queued' / 'Processing' -> still running (poll again in ~10s), 'Completed' -> result is in 'response', 'Failed' -> see 'error'. For video tasks the result renders an inline NATIVE video player widget: a status card (status badge + selected model/specs + prompt) while generating, and the playable <video> once Completed. Keep polling on the same task_id. For the image-ad tasks (generate_ad_to_ad / generate_from_ad_template / generate_ad_variations): as soon as the status is 'Completed', CALL show_ad_result(task_id=...) — that renders the finished creative(s) inline with a copy-URL button on each. Never announce the ad as "ready" without calling it, and never write the image as chat markdown (``) — this host shows remote markdown images as a grey "Show Image" placeholder instead of loading them, which is what show_ad_result exists to avoid. Mention the raw URL in text only if the user asks for it.
Browse the Quickads ad-template catalog to find a template_image_id. BEFORE YOUR FIRST CALL: ask the employee for everything you'll need, in ONE round, using your structured multiple-choice/quick-reply question UI (one question per pick, NOT a free-text paragraph). Collect the URL in this same round too — the gallery widget CANNOT ask you anything later (this host exposes no chat-injection API to widgets), so anything you skip here means a dead end after they pick a template. THEN CALL THIS ALONE, AS THE WHOLE TURN. Never ask a question in the same turn you render the gallery — the question card covers the widget and the employee can't browse and answer at once. Render it, add at most one short line ("pick the one you like"), then END YOUR TURN and wait for their pick. Set multi_select=True when you're collecting templates for ADVANCE ad variations. The grid then lets the employee add several and press Done, and it reports them together as "Use these N ad templates for the variations (variation_template_ids): id, id, …" — pass that list to generate_ad_variations' 'variation_template_ids'. The count of templates IS the number of variations, so do not ask "how many" afterwards. Leave multi_select at its default (False) for generate_from_ad_template, which takes one pick at a time. The questions to ask BEFORE that call are: Q1 (choice): which stage — Stage 0: Brand Awareness Stage 1: Customers UNAWARE of PAIN POINTS Stage 2: Aware of the problem but UNAWARE of PRODUCT Stage 3: Aware of product but UNAWARE of RELATIVE BENEFITS Stage 4: Aware of above but CREATE URGENCY to act Stage 5: Retargeting (or "All stages") Q2 (choice): product templates (default) or service-industry templates (no product placement — has_product_image=False) Q3 (choice, with a free-text option): how many to show — offer a few presets (e.g. 6 / 12 / 24) plus "other". Q4 (free text, with suggestions): the product/service URL the ad should be built from — always include an "other"/free-text option, plus ~3 real, currently-live example URLs that YOU pick fresh each time (don't reuse the same three every run — the employee should see different ideas on each visit). Derive them from context: if their message named a brand, industry, or vertical, suggest sites from that space; if they said nothing, offer a spread (some product-brand sites, some service-business sites, since Q2's answer isn't known yet when you ask). Only if you genuinely can't think of anything contextual, fall back to: nike.com / mamaearth.in (product), urbancompany.com / practo.com (service). Defaults to Stage 0 if you don't pass 'stage' at all — pass stage=None explicitly if the employee wants ALL stages mixed together. Skip asking (and don't show the question UI) for anything they already specified in their message (e.g. "show me 10 stage 2 service templates for nike.com"). AFTER results are shown: the employee clicks a template in the gallery and pastes a short prompt naming its template_id. At that point you ALREADY have their URL from Q4 — do NOT ask again; go straight to get_product_details_from_url + scrape_product_images_from_url on that URL, then generate_from_ad_template. The gallery's own stage dropdown re-calls this tool directly, so stage/product switches need no chat turn. This catalog is GLOBAL — shared across all accounts, not owned by the caller. It's organized into 6 numbered 'stage' buckets (0-5, ~170-200 templates each) representing customer-awareness-funnel stages (Brand Awareness -> Retargeting; see STAGE_LABELS) — pass 'stage' to browse one bucket at a time; the gallery widget also lets the employee switch stages directly, no need to re-call this yourself just to change stage. 'query' ranks templates by their 'concept_name' (a short design-pattern family name, e.g. "The Premium Variant Cluster") and 'core_idea' (a 1-2 sentence description) — these are the ONLY searchable text fields; do NOT ask for or filter by industry/vertical, the catalog has no real per-template industry data. 'has_product_image' mirrors the app's own filter: True (default) returns templates whose concept includes a product placement (or leaves it unspecified); False returns templates explicitly without one. Each result includes 'template_id' (pass this as one entry of generate_from_ad_template's template_image_ids — you can pass more than one to batch-generate across several templates in one call), a 'preview_url' mockup, and up to 6 'example_output_urls' — REAL past-generated ads made from that template (an empty list is normal; most templates have few or no linked generations yet). The result also lists 'available_concepts' (unique design families in the current stage/ has_product scope) so you can steer the employee. Show the gallery widget; when they click a card it sends you the template_id in a follow-up message — then call generate_from_ad_template.
Show the employee's own recently generated ads so they can pick one to vary. CALL THIS ALONE, AS THE WHOLE TURN. Never ask a question in the same turn you render this grid — the question card covers it and they can't browse and answer at once. Render it, add at most one short line ("pick the ad you want to make variations of"), then END YOUR TURN and wait for their pick. Each card carries a numeric 'project_id'. That is what generate_ad_variations' 'project_id' takes — NOT a URL and NOT a UUID. When the employee picks one, the widget reports it back in chat as "Use this creative as the variations base (project_id): <id>". Pass that id and pass NOTHING for template_image_url: the pipeline pulls the base image, the product shot AND the brand (colours + logo) straight off that saved project, so there is nothing else to collect. Newest first, default 10 (max 24). Only finished image ads appear (rendered creatives with a stored output image). Note that several cards may share the same title — one variations run saves a set of sibling ads — so the images and timestamps are what tell them apart. The list spans ALL the brands on the account, not just the one currently being discussed. If the employee picks a creative from a different brand, say so, because its brand colours and logo come from that creative's own saved data.
List the AI video models and each model's per-model input rules. Every model here is generated as a single clip via generate_clip. They differ in what inputs they accept — read each model's 'input_rules': - text→video vs image-to-video (kling-3-turbo REQUIRES one input image); - whether it accepts first/last frames (Veo, Seedance); - how many reference images / videos / audios it takes (e.g. Gemini Omni up to 7 images + 1 video; Seedance 2 up to 9 images / 3 videos / 3 audios; Veo 3.1 Fast up to 3 reference images, always 8s; Veo 3.1 / Kling 3.0 / Seedance 1.5 accept frames only, no reference images). - Frames and references are mutually exclusive on every model. The Seedance 2 family ('storyboard_text': true) can ALSO drive the multi-scene build_storyboard → generate_video flow for longer stitched videos.
Show a colour picker so the employee can choose the variation colour. CALL THIS ALONE, AS THE WHOLE TURN. Never ask a question in the same turn — the question card covers the picker. Open it, add at most one short line ("pick the colour you want"), then END YOUR TURN and wait. Use it when the employee answered "use a specific colour" to the colour question in generate_ad_variations' flow. Do NOT open it when they chose their brand colours — the two are mutually exclusive and passing both is rejected. They can use the native colour wheel, tap a preset swatch, or type a hex. The widget previews the colour on a mock ad (background, headline and CTA) with automatic light/dark text, so they can see the contrast before spending credits. It reports the value back in chat as "Use this variation colour (variation_color): #DDB5FF" — pass exactly that hex as generate_ad_variations' 'variation_color'. Optionally pass 'base_image_url' — the ad they're making variations of — to show it beside the swatch for context, and 'current_color' to pre-select a hex they already mentioned. This tool only picks a value; it generates nothing and costs no credits.
Show an inline uploader so the user can pick a LOCAL image OR video to use as a reference. Use when the user wants to upload their own photo/artwork/clip from their device (rather than search stock or scrape a URL). Renders the picker widget with an upload drop zone: the user chooses a file (image ≤15 MB, or video mp4/mov/webm ≤50 MB), the widget hosts it and reports the hosted URL back to you — use an image URL as a reference_image_urls entry and a VIDEO URL as a reference_video_urls entry when generating. If you don't see the URL, call get_recent_uploads (each item is tagged image/video). (The user can also paste an http(s) image URL and you call add_reference_image.)
Show an uploader so the employee can supply the REFERENCE AD to clone. CALL THIS ALONE, AS THE WHOLE TURN. Do not ask the employee any question in the same turn you call this — a question card renders on top of the uploader and they cannot use both at once. Call it, add at most one short line telling them to drop the ad or paste its URL, then END YOUR TURN and wait for the hosted URL. Only after it arrives do you ask about the product, the model, the stage, or anything else. Two flows need this, and both take the hosted URL as 'template_image_url': - generate_ad_to_ad — the ad whose style/layout gets CLONED onto the employee's product. - generate_ad_variations — the ad they want VARIATIONS of, when they'd rather upload one than pick from list_my_recent_creatives. (If they pick a saved creative instead, skip this tool entirely and pass that project_id — no upload needed.) Neither flow can run without a base image, so call this whenever you don't already have a hosted URL. Never ask the employee to type a URL blind; open this instead. The widget has TWO lanes, both hosting the result on Quickads storage: a drag-and-drop / file-pick zone (for a screenshot or a saved ad file), and a "paste the image URL" field (for an ad already online — it gets re-hosted, which is required for the thumbnail to render at all). Optionally pass 'template_image_url' to pre-populate: if the employee already pasted a reference-ad URL in chat, hand it over here and the widget shows it already re-hosted and pre-selected — which also proves the URL is fetchable before you spend a generation on it. An unreachable URL is not an error; the uploader still opens so they can drop the file instead. This tool does NOT generate anything and costs no credits.
Recommend suitable video templates from the Quickads catalog. This is the DEFAULT when the user wants a video but has NOT provided their own storyboard/script. Searches only the supported families (Seedance 2 / Short clip / ClaudeHTML). CONSIDER THE USER'S INDUSTRY/CATEGORY: pass 'category' = their industry (e.g. "Skincare", "Fashion", "SaaS", "Real Estate" — partial, case-insensitive) whenever you can infer it, and 'query' = the topic/brief (e.g. "skincare ugc"); results are ranked with category/industry as the strongest signal. The result also lists 'available_categories' so you can steer the user by industry. Each returned template includes its 'template_id', 'category', a preview, duration, and its REQUIREMENTS — 'required_image_count' + 'image_roles' (what each reference image should be) and 'input_fields' (text inputs like dialogue). Suggest the best-fit template, tell them exactly which reference images and script it needs, help them gather those (search_stock_images / open_image_uploader), then call generate_from_template(template_id, prompt=the script, reference_image_urls=[...]).
Pull candidate product photos from a website URL. CALL THIS ALONE, AS THE WHOLE TURN. Never ask the employee a question in the same turn you render this picker — the question card covers the grid and they can't pick and answer at once. Render it, add at most one short line ("click the product photo you want"), then END YOUR TURN and wait for their pick. Use when the employee gives a product/brand URL and needs a product image. Every candidate is already re-hosted onto Quickads storage before you see it (so thumbnails always render regardless of the source site's domain). Returns candidates in a CLICKABLE picker grid — tell the employee to click the image they want; the widget reports the (already-hosted) URL back to you via chat — no further rehosting needed, just use that URL directly as 'product_image_url'. The widget ALSO has an "upload your own product photo" drop zone, for when nothing scraped from the site is usable — those uploads go to Quickads storage too and behave identically, so never tell the employee to go elsewhere to upload. Capped at 30 scraped candidates (fewer if some fail to rehost). Pair with get_product_details_from_url to also get product text from the same site.
Pull images (logo, hero/og image, product photos) from a brand/product URL. Use when the user references their website, a product page, or a brand link. Returns candidates in a CLICKABLE picker grid — the user clicks the image(s) they want; the widget re-hosts each pick and reports its reference URL back to you via context (do NOT call add_reference_image yourself for grid picks). For product catalogs the logo + hero + on-page images are surfaced.
Search the avatars_lib reference library for real people matching a persona, ranked by fit. Call this BEFORE generating a brand-new character sheet whenever the storyboard needs a person: an existing hosted reference is cheaper and holds up better across frames than a freshly generated one. Pass the persona in 'q' as prose exactly as you'd describe it internally (e.g. "warm Indian woman, early 30s, home kitchen") -- structured filters alone miss what prose catches. Add structured filters (gender, age_range, ethnicity, ...) whenever the persona pins those down; they narrow the search, 'q' just biases the ranking. Results are grouped by person, not by image -- pick a person, then use ALL of their 'images[].hosted_url' as the reference set for that character (multiple angles/shots of the same person is the point). Sorted by 'match_score' (0..1, highest first); a near-miss with a lower score still beats falling through to generation, so don't discard a result just because it isn't a perfect match. If 'relaxed' comes back true, nothing matched every soft attribute (vibe_expression/setting/apparent_class_context/wardrobe) exactly, so those were dropped and the returned people are the closest available -- identity (gender/age/ethnicity) and per-image quality filters were NOT relaxed, so everything returned still satisfies those exactly. Defaults exclude unusable/inactive/unclear-face/no-URL rows -- the most likely source of character drift if fed to a generator. Only override include_unusable/include_inactive if you deliberately need to inspect flagged rows (e.g. an admin/QA request); there's no override for a blurry face or a dead URL. If 'count' comes back 0, there's genuinely nobody in this account's library matching the identity/quality filters given -- move on to generating a character rather than retrying. Once you've picked a person, call get_person_avatar_shots(person_id) if you need more of their shots than this returned (search doesn't cap images per person, but get_person_avatar_shots is the one built for "give me everything for this person").
Search stock images for a topic and show them in a grid for the user to pick. Use when the user wants a video "about" something and you need real reference imagery. 'orientation' is portrait (9:16, default), landscape (16:9), or square. Returns candidates in a CLICKABLE picker grid — the user clicks the image(s) they want; the widget re-hosts each pick and reports its reference URL back to you via context. Do NOT call add_reference_image yourself for grid picks — just use the reference URLs you receive when generating.
Display finished ad creative(s) inline, each with a copy-URL button. Call this the moment an image-ad task reaches 'Completed' — pass the 'task_id' you were polling and it pulls the creative(s) out itself. Do NOT describe the ad as "ready" without calling this, or the employee gets text with no picture. Do NOT write the image as chat markdown (``) either: this host renders remote markdown images as a grey "Show Image" placeholder instead of loading them, which is exactly what this widget exists to avoid. Also use it to re-display an earlier ad, or to show arbitrary hosted ad images by passing 'image_urls' instead of a task_id. Several images (e.g. from generate_ad_variations) page 3-at-a-time behind arrows. This tool only renders — it generates nothing and costs no credits.
Show MULTIPLE finished clips together in ONE native player (a grid). Use this whenever you have more than one clip to display — several generate_clip results, the clips of a multi-scene / 30s+ video, etc. Showing each clip with its own show_video (one widget per clip) makes the host render duplicate widgets that collapse to a single clip; show_clips renders them all as a grid in a SINGLE widget so every clip appears, each with its own player + per-clip download. 'clips' is a JSON array (newest→oldest or scene order) of objects: [{"video_url": "https://…", "duration_seconds": 15, "title": "Scene 1", "thumbnail_url": "https://…"}]. Only 'video_url' is required per clip. width/height are the clips' pixel dimensions (from 'video_dimensions').
Show a completed video in the inline NATIVE video player (not Remotion). Call this to let the user WATCH a finished clip instead of clicking a URL — pass the 'video_url' from a completed generation task (get_task_status), 'duration_seconds' = its duration, and width/height = its 'video_dimensions'. ALWAYS pass 'prompt' = the video's generation prompt / storyboard text and 'model' / 'resolution' / 'aspect_ratio' — the card shows the prompt (clamped, with Show more) + spec chips above the player, so omitting them leaves it blank. get_task_status already renders this player (with the prompt from the task) while polling and on completion; use show_video to (re)display any completed or user-provided URL. The Remotion player is for EDITING only (create_edit_project -> preview_video).
Transcribe a video's speech and get ready-to-use captions (Whisper). Pass the clip's URL (e.g. 'response.video_url' from a completed generate_clip / generate_video task) and the spoken language as an ISO 639-1 code ('en', 'hi', 'es', ...) or a plain name ('English', 'Hindi'). Returns the full transcript text, word-level timestamps ('words'), and caption lines grouped for on-screen display ('captions', each with text/ start/end in seconds). Call it once per clip to caption each video.
Host a LOCAL image OR video on Quickads storage and return an http(s) URL. Use this when the image is NOT already a public URL — a chat attachment, an extracted video frame on disk, a screenshot, a real person's photo you must not send to a third-party host. Every other tool (generate_character, generate_product_sheet, and the reference_image_urls / first_frame_url / last_frame_url params) needs an http(s) URL; upload_asset is how a local image becomes one. Pass the image as base64 (raw, or a 'data:image/...;base64,' URI). It is stored on Quickads' OWN bucket (never a third party); the returned 'asset_url' can be fed straight into those tools. 'purpose' can be 'reference', 'character', 'product', or 'template' — use 'template' for a reference/competitor AD whose style will be cloned via generate_ad_to_ad's template_image_url.
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.