AI Producer by OpusClip
Edit videos with AI chat
- Category
- Content & Design
- Primary Subcategory
- Video & Podcast Editing
Integration details
Description
Create an editable talking-head video in chat. Upload footage, direct cuts, captions, reframing, and motion graphics, then open the AI Producer preview to refine or export.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Video & Podcast Editing
- Secondary Subcategories
- None listed
- Brand
- OpusClip
- Access
- Account required
- First tracked
- 2026-09-20
- Tool count
- 38
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for AI Producer by OpusClip
Get updates when AI Producer by OpusClip’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

Competing in ChatGPT Video & Podcast Editing
View Category38 tools agents can invoke
Bake the caption layer from the subtitle pattern the caller picks into compositions/narrator_captions.html and transcript-src.json. A host project's result carries host_div for index.html and files ({path, sha256}) to commit, adding those entries when you name expected_files, or they stay staged. position, placement, hide_intervals, caption_windows, emphasis_word_ids, font and accent are optional; one model call fills the pattern and emphasis left out. Billing: paid, priced by source length and lane; get_pricing states the amount.
build_captions
Place one certified package on this project's timeline at timeline_in_ms, the placement the browser's Add runs. expected_project_revision must equal the revision list_motion_assets returned; another is refused with the current one. A media input is a registered asset id or, for a video input, ordered staged segments {path, sha256, start_ms, end_ms, geometry} from frame_speaker, verified before they bind. The same idempotency_key replays the first receipt. Refused: an unknown or retired package, a required input without a value, a project under a task. Billing: free.
materialize_motion_asset
Write music, beat timing and a ducked audio mix. Requires sections or direction; direction alone requires a stored timeline. Sound effects use the plan's sfx beats. Takes the project lock and returns task_id; get_task reports completion. Repeats start another priced run. Billing: paid, 5 credits per music cue delivered (up to 3), 3 more when a music direction's planning runs, and 1 more per second of generated sound effects in the mix (up to 10); get_pricing states the amount.
add_music
Generate sound effects at the points you choose on the finished cut's timeline (at_ms) and mix them with the voice and any music. Send 1 to 12 hits in one call: each call replaces the project's previous sound-effect track. A hit that starts past the end of the cut is refused, not retried. Takes the project lock and returns task_id; get_task reports completion. Repeats start another priced run. Billing: paid, 1 credit per started second of generated sound effects that land in the mix; get_pricing states the amount.
add_sound_effects
Judge every file staged for one project and accept all or refuse all; only this call moves a staged file into the workspace a render reads. A composition is refused for external scripts, inline handlers, javascript: URLs, network calls in executable script code, or more than 64 KiB (4 MiB for compositions/narrator_captions.html), because it is served into the project preview beside the page. A sub-composition is also refused when it carries no <template> (missing_composition_template), when its window.__timelines[id] = tl assignment sits after </template> (timeline_outside_template), when it registers a key no host in the file carries (timeline_id_mismatch) - only template content is cloned, so that timeline never registers and the export blocks on it - or when a script binds a literal [data-composition-id=id] selector with a class the host does not carry or :not(.visual-host), or sends a :scope > child query to that root, because the export mount strips the inner root's data-* attributes and only the host carries the id, so that root reads null and the script throws before it registers. A composition's media, stylesheet and mount references (img, video, audio, source, link, data-composition-src) are read from the project root (public/..., styles/..., compositions/...), never from compositions/, because the editor mounts the template into index.html; a ../ path there names a file above the root and is refused as missing_reference. Only a composition's script src is read from its own file (../public/vendor/gsap.min.js), as the export's page load reads it, and a url() inside a .css file is read from that stylesheet. Every file a document or a live style names must be in the workspace or in the same commit, or the round is refused as missing_reference instead of exporting without it; a @font-face src is the exception, since the browser falls back when a face is absent. data-start, data-duration and data-media-start are seconds, and a value that is not a finite number in range (start and media offset at or above 0, duration above 0) is refused as invalid_timing rather than failing the export later. The caption layer, the composition declaring data-composition-id narrator-captions, is accepted only when its words are one inline JSON array declared as const WORDS = [...];, one object per word with double-quoted keys word, start and end (finite seconds on the cut) and group_id (an integer per phrase), because that array is all the editor and a long export read; any other caption layer is refused as invalid_caption_words, whatever the cut's length, with the accepted form and an example in its repair_hint, and build_captions stages a caption layer in that form. A file already committed under public/, and every committed image, video, audio file or font, is never replaced in place: staging different bytes at its path is refused as immutable_asset, so upload the new bytes under a new name and repoint its references in the same round. A document or stylesheet under compositions/, styles/ or fonts/ is replaced as before, within the stylesheet budget: every export re-copies and re-fingerprints them, so one over 1 MiB is stylesheet_too_large, a project past 16 MiB of them is stylesheet_total_bytes, and one past 512 is stylesheet_file_count. Already over a limit, a project still previews, exports and replaces a stylesheet without growing that dimension. On a project that records its input cap (every new project; an older one keeps its one-pass export and is not judged), a cut longer than 5 minutes is exported in stretches, and the export shifts the clock of a layer mounted for the whole cut only by rewriting an inline const WORDS = [...]; array of rows with start, end and group_id. So on such a cut a round is refused as unexportable_long_cut when the tree it leaves is one the export's planner cannot read - most often a subtitle or overlay layer of your own that spans the whole cut and keeps its times in another array - naming the file, the planner's check as code, and the change in repair_hint: build that layer's timeline from const WORDS rows and from nothing else. The same tree on a cut of 5 minutes or less is accepted, since it exports in one pass. A referenced video or audio file no decoder can open is refused as invalid_media naming the element that plays it, and the export refuses the same bytes before it captures. Where the deployment also boots the candidate, a composition this round writes or newly mounts, whose setup script throws, is refused as composition_setup_failed carrying the thrown message, and one that finishes without throwing and still never registers its timeline as composition_timeline_not_registered. A composition the round neither wrote nor newly mounted is not refused for how it starts: it rides the accepted round under warnings as composition_broken_elsewhere, and the export drops that moment, or refuses the render once every mounted moment in the tree is one of them. A check the server did not run refuses nothing and says so under warnings.A refused round moves nothing and names each offending file with the rule it broke. Returns task_id, agent_page_url and page_url. page_url opens the project in the product app, with its navigation and without the AIP chat, and is the durable link to give a person in the final reply. agent_page_url opens the editor view for embedded panels; it is not the final delivery link. get_task on that task_id answers this exact round in result: outcome, accepted, issues (code, path, message, retryable, repair_hint), the digest it left, and next_action; succeeded is that verdict rather than the lifecycle, and a refused round is a done task that accepted nothing. list_workspace.last_promote is the latest round only, which the next commit replaces. Two signed uploads to one path are one staged object and the last write wins, so expected_files binds the round to the staged bytes it claims, yours and the ones a stage result named for you (build_captions files): a named file that is absent or changed refuses the round with workspace_upload_missing or workspace_upload_conflict, and a staged file the batch does not name stays staged. An entry may carry the file itself instead: content is its complete UTF-8 text, staged by this call, so markup, stylesheets and JSON need no sign_workspace_upload, no PUT and no poll, and the server hashes what it stages, and stages it before the round starts, so a commit refused for the project lock leaves those files staged and the same call later stages them again. Send at most 262144 bytes of content over the whole call, and upload anything heavier or binary. A round that changes a composition also proves each one initializes, and any round proves each changed media file opens as media, unless warnings say a check did not run; it never proves the whole tree renders, which start_export runs. An accepted round also lists warnings ({rule, count, message}) for what the tree does that the editor or the export will not follow: timed elements on the root timeline outside a visual host, which play but are not listed or movable as effects; a speaker lane that plays a different cut from the one the audio mix will bake, so the export desyncs; a root audio the editor's player does not resolve (no audio#speaker-audio and no audio.speaker-clip), so the project opens with no player; and a clip inside a composition whose window never meets its host's (a clip's data-start is the host's absolute clock), which never shows. A warning refuses nothing; re-author and commit again. An accepted round becomes a version (source host, this task_id) capturing index.html and the .html and .css under compositions/ and styles/, not fonts or media. base_digest is a digest from list_workspace or last_promote; a base that no longer matches is refused with nothing moved, as 409 with current_digest when already visible and as an outcome stale_base on the round's own verdict when it landed after this call. No base means no comparison. Takes the project lock. A round hydrates the whole workspace before it judges a file, so it is capped at 8 commits per 5 minutes per caller plus a shared server cap; over the cap the reply is a 429 that moved nothing and left every staged file staged. Billing: free.
commit_workspace
Display a question as an interactive card, with a text fallback for hosts without card support. Returns the question and options, not a user answer; no project setting changes. Component ids: visual_style, caption_style, rough_cut_boldness, editing_preference_example, editing_preference, bgm_enabled, sfx_enabled. project_id associates the card with an accessible project. agent_components supplies custom questions. No task or project lock. Billing: free.
present_choices
List the Motion library packages with this project's placement state for each, read at project_revision. An entry carries its inputs (a video input that needs a speaker cutout states its slot) and an action: add, chooseInput, chat or unavailable, with the reason and the one call that acts. With at_ms (and the duration_ms you will place with), a cutout package's next carries the complete frame_speaker calls for that effect window, one matte window per kept span. scene_restyle lists the presets this project is served and whether its restyle switch is on. Billing: free.
list_motion_assets
Generate a scene restyle cover for each window and write it into the project workspace; a timeline this server built also gets it placed, one you authored does not. Up to 25 windows per call, each start_ms to end_ms spanning 4-10s of output time, non-overlapping; a window out of bounds is refused at no cost. Covers a submitted visual plan reserved are bought after your windows while the hold has room; the rest stay pending. A window already covered is not bought again; an identical window addresses the one it made. Each verdict in get_task.result carries the cover's workspace path, whether the timeline already carries it, how many generations this call was priced for (generations, billed_generated_seconds), and for a refused window its class, the provider's reason, and whether it could ever differ; that window keeps no cover, plays the raw footage, and is terminal: a re-run never re-attempts it. A content filter refusing a recognizable individual refuses every window of that speaker. A window may name a preset from list_motion_assets.scene_restyle; a preset outside this project's catalogue is refused at no cost. While the project's Scene restyle switch is off the call is refused at no cost unless enable_skill_quote carries the user's literal words asking for it, which turns the switch on for this project first. Billing: paid, 6 credits per started second of video generated, each window once and twice when the identity check rejects its first try, whether or not it ends with a cover, and never for a generation returned in the wrong frame shape; the hold is twice every window sent, and a window already covered, or refused before generating, costs nothing; get_pricing states the amount.
generate_scene_restyles
Read what every capability costs, in credits. Each row carries band (free / negligible / paid / expensive), credits per run, and available; a per_unit row also charges credits_per_unit per unit consumed, up to max_units. On a row without per_unit, credits is the whole price per run; read per_unit before quoting a row that has one, since such rows carry credits 0 and quoting that 0 calls a paid step free. billing.metered says whether credits move here; allowance says whether your day covers any first; project_id adds that project's spend. available=false rows are not callable. Billing: free.
get_pricing
List what one project's render-engine workspace holds, one page per call; pass next_cursor back as cursor. Each file carries path, size in bytes, and md5, the base64 MD5 the store holds (null means unknown). The listing is recursive under path_prefix and covers only render-engine/index.html, render-engine/compositions/, render-engine/public/, render-engine/styles/, render-engine/fonts/. digest is one token over the whole face on every page, whatever path_prefix or cursor; it changes on any write under the face, the editor's included, and is what base_digest is compared against. A cursor is bound to the digest it was read under: a continuation after the face changed is refused with 409 workspace_changed and paging restarts from the first page. staged (what you uploaded that no commit has accepted, by destination; in no render, visible to nobody) and last_promote (the latest commit_workspace round, which the next commit replaces; a commit's own verdict is get_task's result, null before any round) come on the first page only. Billing: free.
list_workspace
Read project phase, status, active task, optional preferences, and editable readiness. include_spend adds ledger spend; null means unavailable. page_url opens the project in the product app, with its navigation and without the AIP chat, and is the durable link to give a person in the final reply. agent_page_url opens the editor view for embedded panels; it is not the final delivery link. Billing: free.
get_project
Read the live state of the exact task a mutation on this surface returned. Terminal exactly when status is one of done | failed | cancelled; settled only then. succeeded is the outcome to branch on and done is only the lifecycle: a commit_workspace round that refused every file is done with succeeded false, and answers that round in result (outcome, accepted, issues, next_action). failed carries error, and a failed export's result names what to repair: result.issues (composition_id, path, code, cause) or result.planner (reason, duration_s, max_duration_s, plus file and check when it could not read the tree). Beside it, failure carries a stable code and a repair hint where one is known. Show failure.message to the user; error is bounded technical diagnostic text for repair, not user-facing copy. retryable: false means this edit can only fail the same way, null means retryability is unknown. stage, heartbeat_at, attempt and typical_duration_seconds describe progress. deferred is an export parked behind a live turn: it starts when that turn ends. Every reply carries page_url, the durable project page: the link a person can be given. wait_seconds holds the call open until the task settles or its status changes; next_data.poll_args is that held call again: one call per wait, no sleep. A terminal task that took a paid hold also carries billing: credits_held is the ceiling it was quoted, and once settled is true, credits_charged is what it actually took and billable_units what that paid for where the price is per unit. A task turns terminal before its charge settles, so settled false means the amount is not known yet and the next poll carries it; billing absent means no user-paid hold. A project's run_status is not this task's outcome. Billing: free.
get_task
Render the project's current editable preview to a downloadable mp4. A render this call starts passes render-tree admission first: a preview that fails it is refused with the blocking issues and no export is created. Admission is capped at 8 per 5 minutes per caller plus a shared server cap; over it the reply is a 429 with no verdict. An export already running, or still fresh for this preview, is returned without admission, and says so in reuse_reason. status deferred means a live turn owns the project and starts the export when it ends. Every reply that started, reused or parked an export carries task_id, current_workspace_digest (the accepted workspace NOW, the same token list_workspace reports), staged_files_present and warnings, so a refused commit, an upload nobody committed and an unchanged workspace no longer read alike. Those fields describe the workspace, not the returned file: this call does not yet tell you which workspace a given mp4 rendered, and naming the one you want is not supported. current_workspace_digest is null when the workspace could not be read, which does not affect the export. The file comes from get_export_url. page_url opens the project in the product app, with its navigation and without the AIP chat, and is the durable link to give a person in the final reply. agent_page_url opens the editor view for embedded panels; it is not the final delivery link. Billing: free.
start_export
Ingest/transcribe uploaded video_ref into an editable draft; needs a credit wallet. Source limit: 15 minutes; staff 60. Fixed per project, longer refused before billing. Returns project_id, task_id, agent_page_url, page_url (the durable link here to give a person); get_task reports preparation progress. Voice leveled, never isolated: a clean voice is the separately billed enhance_voice. Billing: paid, 1 credit per started 327 source (not cut) seconds, capped at per_unit max_units; get_pricing states the amount.
start_transcribe_project
Create a project from an attached video when the host cannot move bytes; the server fetches it. One per call; .mp4/.mov/.webm to 3584 MiB (2040 restricted); duration limits as start_transcribe_project. A stub with no file is refused with a fix. Returns project_id, task_id, agent_page_url, page_url; get_task reports preparation progress. Voice leveled, never isolated: a clean voice is the separately billed enhance_voice. Billing: paid, 1 credit per started 327 source seconds, capped at per_unit max_units; get_pricing states the amount.
start_project_from_attachment
List registered project uploads available to composer @asset/handle mentions. Returns asset_id, handle, kind, path and media metadata, without media bytes or download URLs. Generated ledger assets and the source video are not included. Read one with get_project_asset. Billing: free.
list_project_assets
Find b-roll images for this project: one image search per query, then a vision pass picks the best candidate for each, and the reply carries task_id to poll with get_task. List a query in cutout_queries when its moment needs the subject cut out on a transparent background; one not also in queries is refused. Billing: paid, 5 credits per distinct query, a cutout query included, held at that count and settled at the queries the run searched; get_pricing states the amount.
find_broll
List your own projects, newest first, one page per call. total counts every project, and next_cursor is null on the last page. An item's progress is not authoritative: get_project is. page_url opens the project in the product app, with its navigation and without the AIP chat, and is the durable link to give a person in the final reply. agent_page_url opens the editor view for embedded panels; it is not the final delivery link. Billing: free.
list_projects
Mark an externally created, settled editable preview finished. Returns task_id, or success without a task if already finished. Refuses a busy or failed project or one without a settled editable preview. Does not assess editing quality, export or add treatments; the project remains editable. page_url opens the project in the product app, with its navigation and without the AIP chat, and is the durable link to give a person in the final reply. agent_page_url opens the editor view for embedded panels; it is not the final delivery link. Billing: free.
finish_project
Measure the speaker per window (cut seconds) and, with matte true, cut them out. The task result gives each window its on-camera share, face and head band, and for a slot the object_position that keeps the head whole and fits; a matted window adds its pop geometry (sink, card edge, headroom) and render-engine/public/speaker_<slug>.webm, staged for your next commit_workspace (media_start 0). Never writes your tree. Refused before compute: no transcript; a matte without a slot, off camera, unmeasured, or across a cut; over 8 windows; a matte over 30 s a window or 60 s a call. Billing: free.
frame_speaker
Read the download link for the project's latest delivered export. state ready carries download_url and download_expires_at; deferred means a live turn still owns the project; not_done means an export has not delivered; no_export means none was requested. Render progress is get_task's, never here. download_url is a one-use credential minted for the CALLING account (not the owner, which differs on a staff read) and signs whoever opens it into that account. A ready reply lists dropped_visuals, moments the render shipped without because their setup script threw, and what the workspace looks like NOW: current_workspace_digest, staged_files_present and warnings. Those describe the workspace, not this file, which may have rendered an earlier one; current_workspace_digest is null when it could not be read. page_url opens the project in the product app, with its navigation and without the AIP chat, and is the durable link to give a person in the final reply. agent_page_url opens the editor view for embedded panels; it is not the final delivery link. Billing: free.
get_export_url
Enable voice enhancement for an editable project, or disable it; disabling reverts to the original audio. A separate task the user chooses explicitly: creation never runs it. Returns task_id to poll with get_task. Billing: paid, 5 credits per started 30 seconds of the project's source audio to enable, held at what that source measures and settled at the audio enhanced; disabling, or re-enabling audio already enhanced, is free; get_pricing states the amount.
enhance_voice
Mint a single-use browser URL for one readable project. url works exactly once: it starts an agent session and redirects to the project page in agent mode, and url_expires_at is when an unused link dies. A session opened under an OAuth authorization lives as long as that authorization (up to about 30 days) and ends the moment it is revoked; any other caller gets about 8 hours. agent_page_url is the durable panel link and reuses the same browser cookie, so it needs no second ticket. Billing: free.
get_view_url
Sign PUT targets into one project's workspace. No bytes move: your shell PUTs each file to its upload_url, again if needed until upload_expires_at (last write wins); content_type is bound into the signature. Nothing is visible until commit_workspace accepts it. Writable paths are render-engine/index.html, render-engine/compositions/, render-engine/public/, render-engine/styles/, render-engine/fonts/. Other paths, and types no commit accepts (no script, no .svg: only markup, stylesheets, JSON, fonts, images, video and audio), land in rejected with a code; the rest in uploads. Billing: free.
sign_workspace_upload
Sign a local .mp4/.mov/.webm upload. Byte limit: up to 3584 MiB, or 2040 MiB for restricted uploads; duration is separate (start_transcribe_project). At 15 minutes these allow ~33 or ~19 Mbps total average: compress or trim larger files. Returns upload_url, required PUT headers, video_ref, upload_expires_at (null=no deadline). No bytes move until your shell PUTs them; repeat PUTs before expiry replace bytes (single_use=false). Resolve missing authorization for this file/destination before sending; reuse prior authorization; a host denial is not consent. Billing: free.
sign_upload
Read one registered project upload by asset_id, handle or canonical @asset/handle. mode inspect (default) returns metadata and native image content for PNG, JPEG or WebP up to 3 MiB. mode download returns metadata and a download_url valid for 15 minutes, including larger or other media. The registered upload path is not a render URL. Generated ledger assets are not supported. Billing: free.
get_project_asset
Read one package by motion_asset_id and version from the registry: the pinned manifest, the entry source per supported orientation, and its preview. Reads no project. A version the registry does not hold is refused. Billing: free.
get_motion_asset
Read one stable page of a project's canonical chat transcript. The cursor is exclusive. Forward order starts at the oldest message and can enumerate the complete history; backward order starts at the newest. next_cursor is null on the last page. Billing: free.
get_chat_history
Read one file out of a project's render-engine workspace: what is deployed, not what you believe you uploaded. A text source comes back inline in content as utf-8, whole, or the window offset and max_chars name (the reply carries chars and next_offset), so a large file is sampled, not swallowed. Anything else, and any file over 524288 bytes, comes back as download_url with download_expires_at and content null. Readable paths: render-engine/index.html, render-engine/compositions/, render-engine/public/, render-engine/styles/, render-engine/fonts/. Missing answers 404. Read-only. Billing: free.
get_workspace_file
Parse one @aip reference line the user copied off a project page into data. A line names its project, optionally a moment in composition time, and either an element address or a frame region the user drew. references carries one entry per line in the paste, each with kind and the full address for that kind; composition_id is filled only for a moment address and is null for a caption or visual-text reference. Refused when the line names a project other than project_id, or carries no readable reference. Nothing changes. Billing: free.
resolve_selection
Read one project's transcript. detail segments is one line per segment with its text and bounds, a tenth of the bytes: read it first to plan a cut. detail words (default) is every word with its times, what captions are built from. src_*_ms is a position in the SOURCE media (null when none); timeline_*_ms is on the CUT timeline. state ready is the whole document; invalid failed its checks (captions.issues says how); pending has no words yet. state deleted was cut; hidden is not drawn. One call is one page: pass page.next_cursor back as cursor, stitch per page.merge_rule. Billing: free.
get_transcript
Replace the live editable preview with one saved version, through the editor's own restore path. It takes the project lock and returns task_id to poll with get_task; while another task holds the lock it refuses with that active task id. Only a version_id from list_versions is accepted; any other value answers 404. Billing: free.
restore_version
The editing preset saved on the calling account: the answers it keeps as defaults for a new project. Returns editing_preset, null when nothing is saved. The preset is a record of what the user chose; it admits no stage, changes no price, and no other tool on this server reads it. caption_style=no-caption means skip caption generation and leave the caption layer unmounted, not a pattern. Billing: free.
get_editing_preset
Store one decision card's selections. The latest answer replaces that card's previous answer; [] records an empty selection. Returns choices and pending_choices. The archive does not affect execution, pricing or stage admission. Billing: free.
record_choices
Stores the calling account's editing preset. The object sent replaces the saved one whole, so a key left out of it is a key dropped; null, or an object with no answers in it, clears the preset. Returns editing_preset as it now stands. The preset is a record of what the user chose; it admits no stage, changes no price, and no other tool on this server reads it. caption_style=no-caption means skip caption generation and leave the caption layer unmounted, not a pattern. Billing: free.
save_editing_preset
Cancel one active orchestration task, queued or running. Cancellation is graceful rather than immediate: the worker finishes its terminal bookkeeping first, so status reaches cancelled some time after the request is accepted. A task holds its project's lock until it reaches a terminal status, and while it is held every tool that starts a stage or an edit on the project refuses with the active task id; a task nobody cancels holds the lock until it ends on its own. A paid task you cancel keeps what it had already spent, never more than the amount it held, and releases the rest. Billing: free.
cancel_task
List one project's saved editable versions and which of them is live, one page per call in stored order; pass next_cursor back as cursor for the rest. Only a version_id returned here names a version: restore_version answers 404 for any other value. Read-only. Billing: free.
list_versions
Wait inside one call for the exact task a mutation on this surface returned, answering with get_task's fields once status is one of done | failed | cancelled or wait_seconds elapses; a status change alone does not answer. wait.woke_on names what ended the hold. A caller already waiting on 8 tasks is answered at once with woke_on hold_limit; a wait past 4 on one task ends the caller's oldest with woke_on superseded. Sends a notification every 15 seconds while held. A reply that is not terminal carries next_data.poll_args, this wait again. Billing: free.
wait_task
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.
What are AI Producer by OpusClip alternatives on ChatGPT?
As of 2026-09-28, AI Producer by OpusClip competes with BlitzReels, Butter, Descript, DevMotion, Montage, NewsTune Studio, NextClip, OpusClip, Riverside, Tella, Vidmoat in ChatGPT Video & Podcast Editing, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.