Modules
Live op list from GET /v1/catalog. Do not hand-maintain this page.
organisations
MCP pim_organisations. Org membership + invites + workspace access. No create/delete organisation.
{
"op": "list"
}list(read) — List orgs the key/user can seeget(read) — Get one organisationlist_members(read) — List org memberslist_invitations(admin) — List pending invitesinvite(admin) — Invite an emailcancel_invite(admin) — Cancel pending inviteremove_member(admin) — Remove an org memberget_workspace_access(admin) — Org workspace membership mapset_workspace_access(admin) — Replace-set member workspace roles
workspaces
MCP pim_organisations. Workspaces + membership.
{
"op": "list"
}list(read) — List accessible workspacesget(read) — Get one workspacecreate(admin) — Create a workspaceupdate(admin) — Patch workspace name, slug, and settings. syncEnrichment: existingResources never|on_input_change; newResources none|all|selected; columnDefinitionIds allowlistlist_members(read) — List workspace membersinvite_member(admin) — Invite a workspace memberremove_member(admin) — Remove a workspace member
skills
MCP pim_skills. Agent skills catalog.
{
"op": "list"
}list(read) — Search skill manifestget(read) — Load skill markdownfetch(write) — HTTPS fetch via helium-fetch
playbooks
MCP pim_playbooks. Load helium-pim-plan, helium-pim-think, helium-video and video atomics. op=list or a named playbook (plan, think, video, …). Follow the returned markdown, then call pim_flows / pim_columns. Does not write.
{
"op": "plan"
}list(read) — Catalog of playbooks (id, skillId, title, description, uri)get(read) — Load one playbook by id (plan|think|video|video_script|video_product|video_avatar|video_environment)plan(read) — helium-pim-plan: peek, mermaid DAG, confirm, then dispatchthink(read) — helium-pim-think: grid ontology and anti-patternsvideo(read) — helium-video: script → stills → reference-to-video DAGvideo_script(read) — helium-video-script: audience, vibe, concept, scriptvideo_product(read) — helium-video-product: optional packshot stillsvideo_avatar(read) — helium-video-avatar: optional on-camera stillsvideo_environment(read) — helium-video-environment: optional setting stills
resources
MCP pim_resources. Prefer terminal.execute for external catalog discovery/search/read. Resource/type writes, grid projections, lossless reads, and application integrations use these primitives. Untyped list stays a newest-first cross-type array (default 200, max 500). Typed list, grid, and query share exact/keyword search, filters, sorting, projections, and keyset cursors (max 200). find and unique_values remain bounded helpers. Create seeds Resource.attrs JSON; published columns auto-enrich.
{
"op": "create",
"workspaceId": "<uuid>",
"resourceTypeKey": "blog",
"attrs": {
"title": "Hello",
"slug": "hello",
"body": "…"
}
}list_types(read) — List resource typeslist(read) — Untyped legacy newest-first cross-type array (default 200, max 500). q, mode, filters, sort, projection, and cursor require a resource type and use the shared query (max 200).grid(read) — Cursor-paginated grid rows with attrs + cells keyed by column key. Supports q, mode, filters, sort, and projection (max 200).find(read) — Resolve q and/or names to ids. filters and sort reject; bounded search is not complete catalog pagination.unique_values(read) — Distinct attr/column values; q narrows values. filters and sort reject.query(read) — Cursor-paginated resource cards with attrs. Supports q/mode, typed filters including ranges, sort, and projection (max 200).create_type(write) — Create a workspace resource typecreate(write) — Create a resource with authored JSON attrsupdate(write) — Merge authored JSON attrs onto a resource
columns
MCP pim_columns. Prefer terminal.execute for external context/templates, document read/diff/validate/create/patch, activate-only publish, and selected fill. These primitives remain for application integrations, unsupported legacy paths, deletes, and richer refresh scopes. Core owns canonical document validation and diagnostics. HTTP retains author and legacy version operations for dashboard compatibility.
{
"op": "author",
"workspaceId": "<uuid>",
"resourceTypeId": "<uuid>",
"prompt": "SEO title from product title"
}list(read) — List columns. strategy is not required.get(read) — Get one column. With columnVersionId: that version's program only. Else version list is metadata (no programs) plus the active version program.author(write) — NL draft a column via choose_template. Pass columnDefinitionId or columnId to edit an existing definition (no _2 key). Returns { id, status: QUEUED } immediately. Poll author_status. Timeout retries reuse the same run. strategy is not required.author_status(read) — Poll an async author run (authorRunId). status QUEUED|RUNNING|DONE|ERROR. On DONE: columnId + versionId.context(read) — Resource-type context: attributes, columns, relationships, limits, and documentSchemas.column/flow as JSON Schema. resourceTypeId required.templates(read) — List column document templates, or return one template document with templateId.validate(write) — Validate a canonical document without writing. resourceTypeId and document required; returns valid, document when valid, and diagnostics.document(read) — Read parsed canonical document plus sorted pretty JSON text (newline-terminated) for exact patch replacements, revision token, and version heads. columnDefinitionId required.create(write) — Create from canonical document (preferred) or legacy flat fields. Flat fields are canonicalized and validated by core.create_version(write) — HTTP-only legacy manual version escape hatch. MCP uses patch with expectedRevision.patch(write) — Create a validated draft from exact canonical JSON replacements. columnDefinitionId, expectedRevision, and edits [{ oldText, newText }] required.publish(write) — Activate a draft version (columnDefinitionId or columnId, or columnVersionId alone). No generation. Fill with cells.generate or columns.refresh.refresh(write) — Enqueue fill for a column set × optional resourceIds/filters. Column set: columnDefinitionId/columnId, columnDefinitionIds, or resourceTypeId (all published on that type). Never all workspace columns. Returns { runs: [{ columnDefinitionId, opsRunId }] }.delete(write) — Soft-delete a column (draft or published). 409 if another live active version depends on it. Use to clean unused author drafts.
flows
MCP pim_flows. Prefer terminal.execute for external flow document read/diff/validate/create/patch and activate-only publish. Use these primitives for overlay run, preview_step, namespace_graph, deletes, unsupported paths, or application integrations. Reuse column templates for step programs. pim_generate is one atomic shot. HTTP retains author/update for dashboard compatibility.
{
"op": "author",
"workspaceId": "<uuid>",
"resourceTypeId": "<uuid>",
"prompt": "story then hero image from story + title"
}list(read) — List flowsget(read) — Get one flow graphauthor(write) — NL draft or **edit** a flow graph. Seeds current graph.json; set_graph replaces the whole DAG (reuse step ids). Returns the saved flow. Session REST is NDJSON; MCP/v1 runs to completion.preview_step(write) — Dry-run one unpublished step with overlay. Optional cascade later steps. Prefer op=run for a media pipeline.run(write) — Overlay media pipeline. Never publishes columns or writes cells. flowId XOR resourceTypeId+namespace. Runs prerequisite branches topologically; cascade=true also runs downstream branches. Returns status, stoppedAtStepId, overlay, runIds, skippedStepIds, results, and preview[]; legacy current/cascade remain. A waiting_external value is retained in overlay and a resumed run stops without resubmitting it until the caller replaces that sentinel with the completed value. execute=false previews every selected step and returns status=preview.namespace_graph(read) — Live DAG from namespace.leaf columns. Never writes ColumnFlow. Then op=run with the same namespace.publish(write) — Create/patch namespaced columns. Removes deleted steps (soft-delete). Activate only unless sync=true.context(read) — Resource-type direct-authoring context with documentSchemas.column/flow as JSON Schema. resourceTypeId required.validate(write) — Validate a canonical flow document without writing. resourceTypeId and document required; returns valid and diagnostics.document(read) — Read parsed canonical flow document plus sorted pretty JSON text (newline-terminated), revision token, heads, and read-only stepBindings. flowId required.create(write) — Create from a canonical flow document, or legacy flat name/namespace/graph fields canonicalized without stepBindings. resourceTypeId required.update(write) — HTTP-only legacy flow update. MCP uses patch with expectedRevision.patch(write) — Apply exact canonical JSON replacements after matching expectedRevision. flowId, expectedRevision, and edits [{ oldText, newText }] required.delete(write) — Soft-delete a flow
relationships
MCP pim_relationships. Relationship definition + version CRUD. list/get inspect source/target types and outboundCardinality. create starts a draft. create_version clones (set targetResourceTypeId to retarget). publish activates one version and retires the previous.
{
"op": "list",
"workspaceId": "<uuid>"
}list(read) — List relationship definitions with active + all versions (source/target type ids, outboundCardinality).get(read) — Get one relationship definition by relationshipId, including versions.create(write) — Create definition + first draft version. Required: key, name, fromResourceTypeId, toResourceTypeId. Optional outboundCardinality (default multi).create_version(write) — Clone a draft from active/fromVersionId. Override targetResourceTypeId / outboundCardinality to repair a mis-typed connection.publish(write) — Publish relationshipVersionId, set active, retire previous active.
jobs
MCP pim_jobs. Prefer terminal.execute status/wait and error reads for ordinary external run observation. These primitives retain cancellation, richer run queries, and application progress integrations.
{
"op": "get_progress",
"workspaceId": "<uuid>",
"runId": "<uuid>"
}list_runs(read) — List column ops runs. If both resourceTypeId and columnDefinitionId/columnId are set, the column wins.get_progress(read) — Poll fill progress by runId XOR columnDefinitionId/columnId. runId uses that ops run, not latest. cellCountsScope=column: cell counts are current column health, not historical run membership. durationKind=fanout: durationMs is not full generation latency. waitingExternal reports linked provider/finalization work. Poll selected cells and requests; do not retry on old cell activity alone. Keep the user updated while polling. Image ~10-20s, video ~5-6min; give extra slack before calling it stuck.cancel(write) — Cancel a running fill (column or runId)list_errors(read) — Failed/blocked cells for a column or runId. Returns run: null when no ColumnOpsRun. cells.generate returns opsRunId — poll get_progress with that runId.
schedules
MCP pim_jobs. Workspace cron. column_refresh + meta.onlyMissing fills empty cells only (voice leads). Same as session /workspaces/:id/schedules.
{
"op": "create",
"workspaceId": "<uuid>",
"kind": "column_refresh",
"columnDefinitionId": "<uuid>",
"cron": "*/15 10-16 * * 1-5",
"timezone": "UTC",
"meta": {
"onlyMissing": true
}
}list(read) — List schedulesget(read) — Get one schedulecreate(write) — Create a scheduleupdate(write) — Update a scheduledelete(write) — Delete a schedule
cells
MCP pim_cells. Prefer terminal.execute for selected column generate and cell read/history. These primitives retain manual edit/ensure, batch list_state, exact-ID exceptions, and application integrations. Address cellId or resourceId+columnDefinitionId. generate returns opsRunId. list_state is lean batch state (no value). edit requires an explicit override request and value. Image cells: { src, assetId, contentType? } from assets import/upload_finish.
{
"op": "generate",
"workspaceId": "<uuid>",
"resourceId": "<uuid>",
"columnDefinitionId": "<uuid>"
}get(read) — Read a cell including current value revisionlist_state(read) — Batch state-only read. cellIds (max 100) XOR resourceId+columnDefinitionIds. Returns cellId, resourceId, columnDefinitionId, state, stateSummary, currentValueRevisionId — no value. limit does not apply; omit it. pending=queued/not started; stale=inputs changed (needs fill); fresh=current value good; expired=TTL lapsed (still filling); blocked=cannot run (read stateSummary); failed=error; cancelled=stopped. Filling = pending|stale|expired.history(read) — Value revisions (newest 50; limit is history-only)generate(write) — Create a missing cell without independent execution, then enqueue one scoped refresh. Explicit repeated generate calls request new work. Returns { accepted, cellId, opsRunId, columnDefinitionId }. Poll jobs.get_progress with opsRunId and inspect the selected cell.ensure(write) — Create the cell row if missing (no re-run if present)edit(write) — Manual override. value required. Image: { src, assetId, contentType? } from import/upload_finish. Ensures the cell when addressed by resourceId+columnDefinitionId.
terminal
MCP pim_terminal. Default external catalog workflow over MCP or POST /v1/terminal. Start with help or workspace list/open; use ls/read/search, column/flow diff/validate/create/patch, activate-only publish, explicitly selected column generate/refresh, and status/wait. Use domain primitives for flow overlay run/preview, standalone media/models/uploads, resource/type writes, cancellation/schedules, lossless reads, and unsupported scopes/paths. Not a shell or sandbox.
{
"op": "execute",
"command": "workspace open my-brand"
}execute(read) — Preferred entry for supported catalog discovery, document edits, selected column generation, and run observation. Execute one parsed command; nested primitive policy is rechecked before every mutation and dashboard approval is conservative.
assets
MCP pim_generate. Helium CDN images. HTTPS import, or local file: create_upload → PUT putUrl → upload_finish. Never writes a cell.
{
"op": "import",
"workspaceId": "<uuid>",
"sourceUrl": "https://example.com/a.png"
}import(write) — Import an HTTPS image URL (aliases: url, src, refs[0].src).create_upload(write) — Mint 15m presigned PUT URLs (max 20 MB each). count 1–8, default 1 returns one session; count > 1 returns { uploads }. PUT each URL in parallel. Do not set Content-Type. Never writes a cell.upload_finish(write) — After PUT, sniff and persist. One assetId, or assetIds (max 8) returning one result per id. Images/video/audio, or a UTF-8 JSON object for recipe_draft_import.documentAssetId. Missing object: PUT the file first. Idempotent if already ready.
connectors
MCP pim_connectors. Sources. Create/sync are writes.
{
"op": "list",
"workspaceId": "<uuid>"
}catalog(read) — Connector cataloglist(read) — List connectorsget(read) — Get one connectorcreate(admin) — Create a connector. Shopify custom table: config.resourceTypeKey + enrichmentMode independent + syncTypes [product]shopify_status(read) — Shopify token readinesssync_runs(read) — List sync runsbindings(read) — List bindingssync(write) — Enqueue a synccancel(write) — Stop an in-flight sync
connector
MCP pim_connectors. Live api/code/cdn on an active connector. list/describe are reads. api/code/cdn use the merchant token (write). Shopify live-theme edits and publishing are hard-blocked across code/REST/GraphQL regardless of approval; verified unpublished/development edits and live reads remain available. Shopify + GitHub + Helium Data + Helium product info (product_info surface; named actions, sync does not import rows) + Unicommerce (uniware surface; search/get endpoints are reads even though they are POST).
{
"op": "list",
"workspaceId": "<uuid>"
}list(read) — List agent-capable connectorsdescribe(read) — Describe surfaces, scopes, skillsapi(write) — Authenticated fetch (base URL + auth injected); Shopify live-theme mutations/publishing blocked, verified draft edits allowedcode(write) — Codebase trees/list/read/write/search (GitHub also pr); Shopify theme writes require verified unpublished/development rolecdn(write) — Upload to connector CDN
sandbox
MCP pim_sandbox. Named VM pim-ws-{workspaceId} with two GitHub remotes (/org + /workspace). Terminal exec, not fs_*. Helium site is Helium-Intelligence-Clients/seed-workspace (Tailwind/shadcn) in workspace/site. Generate-from-template failures are errors — the thin stub is only when GitHub/template is off. After start, if site/package.json lacks tailwindcss, op=reseed with templateRef (e.g. apparel-gtm) — never overlay files onto the stub. Optional templateRepo + templateRef on start/hydrate/reseed. reseed full-clones then force-pushes (not --depth 1 — GitHub unpack rejects shallow). Hosting is optional Vercel Git deploy. One custom domain per workspace (op=domain, admin). Use hydrate/start to clone remotes (server injects git auth into that command). Never git clone via exec. Delegate site/FS work to agent_run (HarnessAgent + OpenCode in the VM, DeepSeek via AI Gateway, bridges :4000–4001, max 2 concurrent; 3rd is busy). start/hydrate boot OpenChamber UI on :4002 (status.chamberUrl; password is md5 of workspaceId). Keep PIM catalog tools on the outer harness. Poll sessionId. Do not exec opencode or openchamber. Connector working copies: export_code onto /workspace/connectors/{id} (VM-only, gitignored). Flush via pim_connectors live_code.
{
"op": "status",
"workspaceId": "<uuid>"
}status(read) — Sandbox + git remotes + preview/prod/chamber URLs + custom domain verificationstart(write) — getOrCreate VM, clone/pull remotes, npm install site/, boot OpenChamber on :4002. With AI_GATEWAY_API_KEY, inject Vercel AI Gateway into in-VM OpenCode. Optional templateRepo + templateRef for first clone.hydrate(write) — Clone/pull GitHub remotes with App token in git argv (not env). Start the VM if it is down. Boots OpenChamber when the VM is already running. Optional templateRepo + templateRef. Do not git clone via exec. Does not wipe a dirty tree — use reseed.reseed(write) — Wipe /workspace, full-clone Helium-Intelligence-Clients/seed-workspace at templateRef (e.g. apparel-gtm; not --depth 1), force-push the workspace GitHub repo, npm install. Always Approve. Use when the stub landed, to change template/branch, or after GitHub unpack/index-pack failed on a shallow push. Never git clone via exec.stop(write) — Stop the named VMexec(write) — Run a command jailed to /org or /workspace (mutating needs Approve)preview(read) — Sandbox next-dev preview URL for iframe (site :3000 — default)deploy(admin) — Hydrate remotes, enable hosting, link Vercel Git, commit+push site/ (always Approve)domain(admin) — Add or replace the workspace custom hostname on the site Vercel project (omit/empty hostname to detach). Always Approve. Serves traffic only after a production Deploy.export_code(write) — Materialize a code-capable connector onto /workspace/connectors/{id} (always Approve). Gitignored. Flush via pim_connectors live_code.agent_run(write) — Start or continue a HarnessAgent OpenCode session in the named VM (default model deepseek/deepseek-v4-flash-vision-exp, AI Gateway). Returns { sessionId, status: running } before VM boot/attach — poll agent_status. Up to 2 concurrent turns (ports 4000–4001); a 3rd fails the ledger with busy after this call returns. Always Approve. Do not exec opencode by hand.agent_status(read) — Poll one sandbox OpenCode session (HarnessAgent history + status)agent_stats(read) — Token/cost snapshot for one session, or latest sessions if sessionId is omittedagent_cancel(write) — Abort a running sandbox OpenCode session
exports
MCP pim_connectors. Output bindings. Flush is a write.
{
"op": "list",
"workspaceId": "<uuid>"
}list(read) — List bindingsget(read) — Get one bindingdeliveries(read) — Delivery logflush(admin) — Flush deliveries
generate
MCP pim_generate. Atomic text/json/image/video/audio/call/agent generations. workspaceId required. Image/video/audio send only caller prompt and explicit refs; resourceId is lineage only. Text/json/agent may load resource context. call: template + phone, returns QUEUED immediately. audio: approved batch TTS/music model + prompt (never Bolna); default voice generation to google/gemini-3.8-flash-tts, while music/SFX require their own model. Fal audio uses synced OpenAPI. Gemini 3.8 TTS uses AI SDK generateSpeech. voice, stability, timestamps, output_format, instructions, speed, and language forward as provider extras when that path accepts them. Image knobs: aspectRatio, size, seed, count. list accepts q (label search). Never writes a cell.
{
"op": "image",
"workspaceId": "<uuid>",
"prompt": "Studio packshot on white",
"resourceId": "<uuid>",
"aspectRatio": "1:1"
}text(write) — Generate text. refs attach as vision imageUrls; empty text with refs is an error.json(write) — Generate JSON. Pass schema as a JSON Schema object (wrapped for generateObject). refs become imageUrls.image(write) — Generate image(s)video(write) — Generate video (async). Pass refs as https src or assetId; provider fetches them.audio(write) — Generate batch audio / TTS (never Bolna). Default voice generation to google/gemini-3.8-flash-tts; music/SFX keep their explicit models. Gemini 3.8 uses generateSpeech: prompt plus optional voice, output_format, instructions, speed, and language. Fal models need synced OpenAPI; Fal extras voice, stability, timestamps, and output_format forward only when that model's schema declares them.call(write) — Queue a voice call (template + phone)agent(write) — Run a tool-loop agentlist(read) — List generationsget(read) — Get one generation. Returns full prompt from invocationInput when present; label stays a snippet. invocationInput may include aspectRatio, size, seed, count when stamped on image/video create. Old rows with null invocationInput do not invent a prompt.cancel(write) — Cancel a running generation
voice_agents
MCP pim_generate. Workspace-authored Bolna voice agents. Template for generate.call / column voiceTemplate is key or id (never Bolna agent id). Member/admin write; not available on generate_only keys.
{
"op": "create",
"workspaceId": "<uuid>",
"key": "demo_qualifier",
"name": "Demo qualifier",
"systemPrompt": "Qualify interest in a product demo."
}list(read) — List workspace VoiceAgentsget(read) — Get one by id or keycreate(write) — Create + provision on Bolnaupdate(write) — Update + re-provision when neededdelete(write) — Delete workspace VoiceAgent row
models
MCP pim_generate. APPROVED catalog models + per-model invocation schema. list modality: text|image|video|audio|embedding. list includes invocationHints for image/video/audio. schema: catalogEntryId or externalModelId. Call schema before writing program.invocationValues. Same data as session GET /accounts/:accountKey/models.
{
"op": "list",
"modality": "image"
}list(read) — List APPROVED models. Image/video/audio items include invocationHints (required, enums, speechField).schema(read) — Safe invocation schema for one catalog entry. catalogEntryId UUID or externalModelId pin. Use before program.invocationValues.
research
MCP pim_tools. One-shot research. JSON only — never writes a cell. Apify (Pinterest / Meta / any actor, APIFY_TOKEN), Exa search (EXA_API_KEY, type=fast|deep|auto, optional outputSchema). Page scrape / browser: pim_tools browser_*. Prefer this over skills.fetch for Apify (300s vs 30s).
{
"op": "pinterest",
"workspaceId": "<uuid>",
"queries": [
"niacinamide serum flat lay"
],
"limit": 12
}apify(write) — Run any Apify actorpinterest(write) — Pinterest search scrapermeta_ads(write) — Meta Ad Library scraperexa(write) — Exa web search. query required. type=fast|deep|auto (default fast). Optional numResults (1–25), outputSchema + systemPrompt for structured output.
tools
MCP pim_tools. External action tools. v1 type=browser (Browserbase). MCP ops are browser_* (injects type=browser). Prefer agent_run (returns runId immediately — never wait) then poll agent_get. Sessions are the escape hatch for a parked browser (live debugger URL, goto, screenshot). Never returns CDP connectUrl. Needs BROWSERBASE_API_KEY; sessions also need BROWSERBASE_PROJECT_ID. JSON only — never writes a cell.
{
"type": "browser",
"op": "agent_run",
"workspaceId": "<uuid>",
"task": "Scrape products on this page",
"url": "https://example.com/products"
}agent_run(write) — Start a Browserbase agent. type=browser. task required; optional url, outputSchema, agentId. Returns { runId, status } immediately. Do not loop agent_run — poll agent_get.agent_get(read) — Poll a Browserbase agent by runId. Running → { runId, status }. Terminal → includes result.agent_stop(write) — Stop is not supported by the Browserbase SDK; poll agent_get until a terminal status.session_create(write) — Create a keep-alive Browserbase session. Returns sessionId + debugger live URLs (no CDP).session_get(read) — Session status + debugger live URLs. No CDP connectUrl.session_goto(write) — Navigate a session. sessionId + url required.session_screenshot(write) — PNG screenshot as dataUrl. sessionId required.session_close(write) — REQUEST_RELEASE the Browserbase session.
seo
MCP pim_tools. DataForSEO proxy. JSON only — never writes a cell. op=docs then op=api. Host pinned to api.dataforseo.com; server injects Basic from DATAFORSEO_LOGIN+PASSWORD. No per-endpoint ops. Prefer over skills.fetch.
{
"op": "docs",
"workspaceId": "<uuid>",
"q": "serp"
}docs(read) — Curated DataForSEO endpoint cards. Optional q (substring) or path (exact /v3/...).api(write) — POST a /v3/... path with JSON body (usually a task array). path required.
messaging
MCP pim_messaging. Outbound messages. v1 op=send channel=email via platform Resend (RESEND_API_KEY). No caller from (spoof). Secret keys only — never publishable or generate_only. channel=whatsapp is a stub (501). Never writes a cell. Site magic-link / Next API uses this.
{
"op": "send",
"workspaceId": "<uuid>",
"channel": "email",
"to": "user@gmail.com",
"subject": "Sign in",
"html": "<p>Click to continue</p>"
}send(write) — Send one email. channel=email required for v1. to + subject + html (≤64KB). Optional text. From is AUTH_EMAIL_FROM / MESSAGING_EMAIL_FROM. whatsapp → 501.
ugc
MCP pim_ugc. Hardcoded UGC reel pipeline. Always lands in workspace Brand Reachout 1. op=run needs brandName + store url (Shopify assumed). Returns a run id immediately; poll op=get until succeeded or failed. First synced product only. Denied on publishable / generate_only / resource_writer keys.
{
"op": "run",
"brandName": "Asopalav",
"url": "https://asopalav.com"
}run(write) — Queue brand UGC for brandName + url. Workspace is Brand Reachout 1 (not in the body). Returns the {slug}_products type id. Reuses that type and any in-flight Shopify sync.get(read) — Poll by the id returned from run (the product type). Returns phase, first product, per-column cell states, terminal succeeded/failed.
generic_ugc
MCP . HTTP only (not MCP). One Shopify product → existing Generic UGC Video type (never create_type). Fetches products.json?limit=10 (last product) or /products/{handle}.json, creates one authored row, kicks published ugc_video.* on that row. Workspace is Generic UGC Video (not in the body). Poll get until videoUrl is set. Denied on publishable / generate_only / resource_writer keys.
{
"op": "run",
"url": "https://www.wforwoman.com"
}run(write) — Queue one product from url. Workspace Generic UGC Video and type generic_ugc_video must already exist (404 if missing). Returns the new resource id. Each run inserts a new row.get(read) — Poll by the id from run (the product row). Returns phase, per-column cell states, and videoUrl (HTTPS CDN) when ugc_video.video is fresh.
image_search
MCP . HTTP only. Text query searches Pinterest and Serper in parallel; imageUrl retrieves visually similar images through native Serper Google Lens, not generated keywords. Optional query with imageUrl is ranking context only. Source URL/exact-byte copies are excluded. Native Clef ranks actual pixels with a conservative photographic-appearance bias in the same decision call. Synthetic, uncertain and weak-photo decisions are excluded before either mode. self returns up to five; auto chooses one survivor, or no_match. This is not verified AI detection. Secret keys and workspaceId required. No catalog writes or image generation.
{
"op": "run",
"workspaceId": "00000000-0000-4000-8000-000000000000",
"query": "Diwali festive background with diyas",
"usecase": {
"text": "Background for a product-video frame; leave space for the product."
},
"mode": "self",
"settings": {
"limit": 20
}
}run(write) — Queue a search with query or public HTTPS imageUrl, plus usecase and mode. usecase needs text and/or up to three imageUrls; image input allows only two additional usage images. Visual retrieval uses the existing worker SERPER_API_KEY and has no text fallback. settings.limit caps each provider (default 20, max 50); Lens caps one native response locally. The shortlist stays at most five. Returns runId; poll get without resubmitting.get(read) — Read a scoped run: queued, running, completed (result), or failed (error). Results expire within 24 hours or sooner under retention caps. Returned scores 0–100 include an AI-look penalty; native fit confidence 0–1 is separate and is not calibrated correctness or authenticity. Filtering can yield fewer than five images or no_match. Source rights remain unknown.
video_flows
MCP pim_video. External-harness video creation. MP4 -> folder template -> project -> hosted batch -> final film uses pim/video/folder-editor: folder_* discovery, explicit push/publish/init, folder_run, folder_select_take, and folder_status. Existing-folder feedback, shot repair and post-processing additionally use pim/video/folder-editing: concrete text/style, timing/framing, sound and take-reuse examples, then one deploy and review. Separate RecipeDocument APIs use pim/video/authoring for recipe_draft_*, directing for story adaptation, copy for declared replacements and editing for saved recipe-project edits. Conditional production skills: production-patterns, scene-consistency, talking-model, concise-prompts and long-form under pim/video/. Generate distinct shots separately from matching crops; trim supported longer generations for short cuts rather than grouping angles/actions to save jobs. Full recipe-document adaptation uses HTTP project_save/execute; MCP never carries RecipeDocument bytes. create and recipe_author_* remain HTTP-only. Observation never resubmits. Read the matching job skill before planning.
{
"op": "run",
"workspaceId": "<uuid>",
"templateKey": "media-first-10s",
"idempotencyKey": "demo-1",
"inputs": {
"script": "A short product walkthrough for this run.",
"presenterImageUrl": "https://cdn.example.com/presenter.jpg",
"narrationAudio": {
"mode": "supplied",
"url": "https://cdn.example.com/narration.mp3"
},
"presenterVideo": {
"mode": "supplied",
"url": "https://cdn.example.com/presenter.mp4"
},
"evidenceVideo": {
"mode": "supplied",
"url": "https://cdn.example.com/evidence.mp4"
},
"environmentVideo": {
"mode": "supplied",
"url": "https://cdn.example.com/environment.mp4"
},
"macroVideo": {
"mode": "supplied",
"url": "https://cdn.example.com/macro.mp4"
}
}
}list(read) — List active templates with version numbers and statuses plus a small capability summary (supportedModes/defaultMode when the latest published version declares execution policy). Idempotently registers code-owned built-ins.get(read) — Get one template version: public input JSON schema, defaults, UI hints (schema-keyed labels/help/mediaKind plus optional clone source thumbnails), inputRequirements, discovery readiness (target slots, optional brand/logo assets, supported audio/overlay choices, and recipe dependency verification state), execution supportedModes/defaultMode when the published document declares them, optional preservationSummary and sourceSlotPreviews, and a read-only timeline preview for known implementations (placement ranges, track/layer order, media-input bindings). Defaults to the latest published version; pass integer version to pin or roll back to a prior published artifact (draft/retired are not served). get does not return recipe document bytes — use document op or recipe_versions hashes plus versionId for identity. Preview never includes filesystem paths, bucket/key, or credentials.context(read) — Bounded discovery: selected identities, skill pointers, next ops. Omit templateKey to list templates. Full documents load via document.document(read) — MCP: outline of the published recipe (documentHash, beat/overlay ids, per-section byte lengths) plus optional section selector. HTTP /v1 and session REST return exact published recipe document bytes, documentHash, versionId, and workspace draftRevision when a JSON draft exists. Never substitutes the latest draft for a pinned published version.run(write) — Validate inputs, admit a durable run, then execute the registered host adapter in this request. Optional top-level mode clone|normal (not a public input key): explicit request wins, else the version execution.defaultMode, else legacy routing. Clone binds declared public inputs only — no director, overrides, or productionOptions. Requires idempotencyKey and inputs. Same key + same normalized input returns reused=true and does not re-execute; same key + different inputs is 409. Poll get_run for the signed MP4.execute(write) — Direct normal admission: pinned template version + resolved inputs. Freezes the instance without a hosted Director/specialist loop. MCP must not send RecipeDocument; adapt via project_create → project_patch → project_execute. HTTP may still pass document. Default wait:false admits then produces in the background; poll get_run. wait:true awaits produce. Clone callers should use run. Invalid documents fail before production. Same idempotency rules as run.create(write) — Three intake choices: Copy Manual (mode clone + complete schema inputs, no topic), Copy Agent (mode clone + inputResolution assistant + topic + supplied image references/optional presenterImageUrl, no typed inputs or creative overrides), and Director (mode normal + brief). Copy Agent uses only image analysis and the published input schema, freezes resolved inputs, then executes the same clone pipeline; it cannot edit the recipe. Modes must be supported by the pinned template version. Omitted inputResolution retains direct typed-clone behavior; omitted mode follows recipe defaultMode, otherwise legacy director. Director accepts references, presenterImageUrl, instructions, voice, audioTracks and productionOptions as supported by that template. Requires idempotencyKey; same key and original request reuses, conflicting input is 409. Default wait:false admits before model work (SSE/poll get_run). wait:true awaits resolution and generation and returns get_run with signed output.url; a reused in-progress run returns its current snapshot. Failed copy-agent retries with saved inputs skip the agent and reuse the frozen instance. Upload media first; bytes never enter this op. Paid generation is implied by create. Inspect get for the selected version's schema, capabilities and requirements.cancel_run(write) — Cooperatively cancel admitted JSON recipe production by runId. Stops queued work and final publication; already-submitted provider requests settle and retain their media. Director planning and legacy adapters are not supported. A disconnected client is not a cancellation request.get_run(read) — Poll one run by runId (UUID or 12-char publicId): status, stage, steps, error, signed output URL once the MP4 is published, director events[] / recipe when origin is create, pinned referenceReelProfile / profileVersionId when the recipe or run has an original-reel pin (signed URLs are refreshable and are not pin identity), groundedAssets / filmDirectionPlan / shotProductionSpecs / productionOptions when grounded pipeline is used, and the path-free timeline preview (caption cues from this run's script). Each step also projects an HTTPS-safe produce snapshot in steps[].inputs (prompt, model, duration, image/video refs from the persisted provider identity). Storage bucket/key never leave the server.list_runs(read) — Workspace run history, newest first. Filterable by templateKey/status with keyset cursor paging (limit max 200).recipe_draft_create(write) — Create a workspace JSON recipe draft (VideoTemplateVersion status draft). Requires slug. Optional forkTemplateKey/forkVersion copies a published recipe server-side. HTTP may also send document. MCP must omit document — use fork, recipe_draft_patch, or recipe_draft_import. Returns templateKey json.{workspaceId}.{slug} plus draftRevision.recipe_draft_get(read) — Read the mutable JSON recipe draft for templateKey. MCP returns outline (hash, beat/overlay ids, section byte lengths, optional section). HTTP returns the full document and draftRevision.recipe_draft_update(write) — HTTP-only whole-document draft replace. Requires templateKey, document, and expectedRevision. Revision mismatch is 400. MCP uses recipe_draft_patch or recipe_draft_import.recipe_draft_patch(write) — Apply 1-32 unique oldText/newText replacements against canonical pretty JSON of the draft. Requires templateKey, expectedRevision, and edits. Missing or non-unique oldText is 400. Stale revision is 400 revision_mismatch.recipe_draft_import(write) — Replace the draft from pim_generate upload (documentAssetId after upload_finish, max 20 MB) XOR an HTTPS documentUrl. Server fetches JSON. Requires templateKey and expectedRevision. Response is hash/draftRevision/diagnostics, not bytes on MCP.recipe_validate(read) — Validate the current draft (templateKey) with parse + hosted compile. HTTP may also send a body document. MCP requires templateKey only. No media generation. Returns ok plus structured diagnostics.recipe_publish(write) — Publish the current draft as an immutable version. Requires templateKey, expectedRevision, and idempotencyKey. Duplicate document hash returns reused=true. Hosted compile rejects unsupported required blocks. No media generation.recipe_versions(read) — List draft and published versions for templateKey with content hashes. Generation-only keys may read versions but cannot publish.project_create(write) — Create a workspace-scoped project draft with a required templateKey pin. Writes revision 0. Authored beats are derived from document.composition.beats.project_list(read) — List projects in the workspace, newest first.project_get(read) — Read project identity, draftRevision, and authored state. Requires projectId (UUID or 12-char publicId).project_save(write) — Atomically save authored document/inputs with expectedRevision. HTTP-only RecipeDocument replace. MCP uses project_patch. Beats are derived from document.composition.beats. Stale heads reject. Does not start production.project_patch(write) — Atomic typed project edits (E1 graphics plus E2 replace_placement_media, retake_producer, select_placement_take, remove_placement, reorder_placement, set_placement_source, set_placement_gain, restore_revision, and overlay/placement motion) with expectedRevision and idempotencyKey. Returns producer impact (retained/derivative/generated plus render). this_placement media replace splits a producer so other uses stay. Independent composition.audio / audio placements are not close-gap rippled. Motion is local-clock keyframes (not source rate). Hold transition handles fail closed. Stale heads and incomplete batches do not persist. validate:true dry-runs impact without saving. Does not publish a catalog recipe. Then project_execute the frozen revision.project_execute(write) — Execute the frozen current revision snapshot. Draft mutations during the run do not alter admitted work. Default wait:false admits then produces in the background; poll get_run. wait:true awaits produce.project_import_run(write) — Import an existing clone-bound or normal-adapted run into a project without generation. Copies document, inputs, selected result bindings, and lastOutputRunId when the source run has output; otherwise unsupported lists the gap.folder_templates_list(read) — List published folder templates for the workspace. scope all|global|workspace. Literal query on name, description, and slug. Cursor pagination, limit 1-100, default 20. Does not unzip archives or generate.folder_templates_get(read) — Get one published folder template by id or publicId. Optional version pin. Missing and private templates are not_found. Returns the archive pin, not ZIP bytes.folder_projects_list(read) — List folder projects in the workspace, including empty drafts. Literal query, cursor pagination. Does not unzip or generate.folder_projects_get(read) — Get one folder project by id or publicId. Optional folderRevision returns that revision and the current head separately. Other workspaces are not_found.folder_project_files(read) — Return the text of one folder revision for review. Unzips that archive only. Does not generate, push, or change the head. Other workspaces and missing revisions are not_found.folder_template_files(read) — Return the text of one published folder template version. Unzips that archive only. Does not generate or change the template. Missing and private templates are not_found.folder_push(write) — Put one authored ZIP on S3 and record a Postgres revision. Same operationKey plus the same bytes returns the existing revision. Same key plus different bytes is conflict. List/get do not download the ZIP.folder_pull(read) — Materialize one revision. Rejects a destination whose authored hash differs from its checkout. Writes results.lock.json and status.json from the stored projection. Those files stay out of the ZIP.folder_publish(write) — Publish the pushed head as a workspace template by default. Set folderPrivate false explicitly for a global template (workspace_id null). Empty drafts cannot be published. Existing template scopes and version pins are unchanged.folder_init(write) — Start a project from an exact published template version. Retry identity is workspace + operation key + template id + version.folder_run(write) — Admit one folder batch for the pinned revision, return the run id, and continue waves (cap 20). Disconnect is not cancellation. Poll folder_status.folder_select_take(write) — Pin one block to a ready assetId or an HTTPS url (imported into a workspace asset), then re-render the film. Other current blocks stay selected. folderOperationKey identifies that pin: the same key returns the existing run, and the same key with a different assetId is a conflict. Authored files stay unchanged. Poll folder_status.folder_timeline(read) — Compact folder film clock: revision, selection token, duration, each shot and graphic id with timing, source start, prompt and text, plus selected take asset ids. Does not return every section file or start a run.folder_edit(write) — Apply the dashboard folder edit list once. Requires projectId, expectedRevision, selectionToken, folderOperationKey, and folderEdits. validate true returns the change receipt and does not save. The same folderOperationKey returns the existing run. Delete mode close_gap pulls later shots forward; omitted mode leaves the gap. Custom HyperFrames files still use folder_push.folder_status(read) — Read one video_folder_runs row and its steps. Does not generate.folder_history(read) — Read projectId revision history with every film run, fresh preview URLs, headRevision and selectionToken. cursor pages older revisions. Choose an exact completed runId, not just a revision that may contain multiple films.folder_restore(write) — Restore projectId's exact completed runId as a NEW revision, retaining its authored archive, clip/audio selections and existing MP4. Requires folderRevision=current head, folderSelectionToken from folder_history, stable folderOperationKey. No generation, render, paid repair or history deletion. Same key/request recovers the result. Refresh your checkout afterward; copying old files then folder_run does NOT restore old takes.recipe_author_start(write) — Start automated dual-mode template authoring from a reference video (asset ID or HTTPS URL) and author brief. Returns a durable authoring job ID and initial status/stage (pending/inspecting). Idempotent on idempotencyKey.recipe_author_get(read) — Read durable lifecycle status of an authoring job: stage (inspecting, authoring, validating, registering, ready, needs-input, failed), checkpoints, diagnostics, questions, or result template key/version.recipe_author_list(read) — List template authoring jobs in this workspace with keyset pagination and optional status filtering.recipe_author_continue(write) — Provide a correction or clarification to an authoring job in needs-input stage, resuming execution from the saved checkpoint revision.
video_media
MCP pim_video_media. Inspect source/target media before production or optionally review consistency/quality with pim/video/quality-review. Open a workspace scope. Mechanical ops are unpaid; semantic analysis is paid and receipt-cached. Caption cues consume measured words only. Folder films load pim/video/folder-editor; recipe-draft authoring loads pim/video/authoring. Reuse pim_generate for import/upload. No automatic repair or generation gate.
{
"op": "scope_open",
"workspaceId": "<uuid>"
}scope_open(write) — Create or reuse a workspace media-prep scope. Receipts survive reload without a Director run.analyze_image(write) — Grounded image observations. Requires scopeId and url or assetId. Cached by checksum.analyze_video(write) — Native video analysis. Requires scopeId. Probe first with media_utils. No hidden footage generation.review_checklist(write) — Consistency & quality review for completed-film QC. Requires scopeId + typed checklist: 1–4 video/image candidates, up to 12 role references (original video, product/model images, scene/style), brief and allowedChanges. Explicit video windows <=120s each/480s combined. Returns reportMarkdown: a freeform review with timestamps, defects, required fixes and notes/inspection-gap footnotes, not fixed checks or JSON judgments. Source/usage/receipt metadata stays separate. Paid, agent-invoked; no automatic repair or generation gate.media_utils(write) — Ecommerce survey options.mode author_template (default) or review_generated. Returns a free-flowing Markdown report, timed cuts/scene switches, moments with open-ended notes, and verbatim speech with timings when words are audible (voiceover, on-camera, mixed, or unknown; empty when none). Measured metadata, contact sheets and durable evidence are included. Default 24 FPS. Optional category/productFocus/brief/allowedChanges, review referenceVideo and up to four keyed targetImages (HTTPS url XOR scoped assetId). Original and generated clocks remain separate. No recipe write or automatic repair. Individual probe/contact_sheet/detect_cuts/extract_frame/trim/crop/extract_audio/measure_loudness operations are deterministic and provider-free.caption_cues(read) — Map measured word timestamps to caption frames. Does not transcribe.receipt_get(read) — Read a durable receipt by scopeId + receiptId. Delivery URLs are not identity.
keys
MCP pim_organisations. Org API keys for /v1 (not /mcp). HTML mini-app: kind=publishable then pim_skills({ op: "get", skillId: "pim/js-client" }) — do not raw-fetch /v1. Curl: pim/http-api. create returns next hint + raw key once.
{
"op": "list",
"organisationId": "<id>"
}list(admin) — List org keysget(admin) — Get key metadatacreate(admin) — Mint a key (raw shown once). HTML: kind=publishable then load pim/js-client. Response includes next.revoke(admin) — Revoke a key