Mobidoo

Live Commerce API

Call mobidoo/live-commerce — Intro/Mid/Fin scripts, per-clip delivery, and thread-based clip retry.

mobidoo/live-commerce is the Format that Mobidoo uses for host-led live commerce video. You get a full cut and the individual clips in that cut. When one clip is wrong, continue the same thread and ask for only that clip. You do not start a new production from the start.

The Format needs only a product URL. If you have a host image, a tagged Korean script, and your own prices, send them. Your values have priority. If you send none of them, the Format gets each one from the product page: a host generated to match the tone of the product, a script written from the page, and a Korean voice preset.

Use a Mobidoo team workspace API key (a key created under the Mobidoo team, not a personal key). If you use a personal key to call mobidoo/live-commerce, the call fails with 403 workspace_key_required. Refer to Team Formats need a team key.

If you are not in the Mobidoo workspace yet, ask 허채원 (Chase Huh) for an invite on Slack. You can also send an email to chase@sume.com. Refer to Workspace access.

Create a run

When you complete the fields, the page rewrites the cURL, JavaScript, and Python snippets.

Run the live-commerce Format

POST /v1/formats/{handle}/{slug}/runs

Required

The call returns a Format run. To get the result, poll status_url / result_url, use a run webhook (format.run.terminal), or use the poll loop in TypeScript or Python. Before you put the call behind user traffic, read Errors and rate limits.

What to send

FieldNotes
instructionShort prose: tone, “use Intro/Mid/Fin as written”, no BGM / no captions, vertical 9:16.
inputStructured caller data — product, host, price, tagged script.
output_schemaBind mobidoo/live-commerce/v1, so that the receipt is typed for your ingest.
primary_output_key"full_video" — the assembled cut is the primary media field.
generation_spend_cap_creditsThe generation ceiling for each run, in credits. The API accepts a value above the Format’s own cap, up to the platform maximum. Above the platform maximum, the API returns 400.

The API has no separate “JSON mode.” instruction is guidance. input is data. This is the same shape as an LLM turn. For one worked create → receipt → clip-retry loop, refer to Best practices.

keys the recipe recognises

input is free-form JSON that Sume concatenates into the prompt. It is not a fixed request schema. You can use the shape that is convenient for your backend. Full rules: Call a Format — what is carried and Structured output.

The HTTP API does not require any of the keys below. Extra keys go into the run as data. A missing key is not an error.

KeyEffect
product_urlThe page to crawl for specs, copy, and product photos. Treat this one field as required.
host_image_urlThe person to use as the host (identity for each talk shot). Alias: avatar_image_url. If you omit it, the Format generates a host that matches the tone of the product.
script.segmentsYour script as few long tagged blocks, usually Intro / Mid / Fin. Do not pre-split it into dozens of cuts. If you omit it, the Format writes a script from the page.
vo_languageThe spoken language. The default is Korean.
on_card_nameThe exact product-name spelling that is permitted on an on-screen card.
priceList / sale / discount label, if you want those numbers on a card.
banner_reference_image_urlsLayout references for on-screen cards (media.sume.com URLs).
variants_per_nCandidate images for each card. The default is 1.

The length of the delivered video is exactly the length of its voice track. To change the length, change the script. The API has no duration parameter.

Script tags → clip arrays

Your tagReceipt array
Introopening[]
Mid (or Mid · …)middle[]
Finclosing[]

Send few, long segments (approximately 3–5), not one object for each cut. The Format decides where the cuts occur. If you pre-split the script into ~45 cut objects, you waste the input size budget. Usually, the edit is also worse. For details, refer to Size limits below.

Threads: continue the same production

A Format run is one agent turn. The first successful run starts a conversation. The receipt has these fields:

FieldMeaning
idThe run id of this turn (arun_…). Use this id for polls and webhooks.
thread_idThe durable conversation id for the whole production. Response-only. Never put it in a request body. The API rejects it with unknown_parameter.
previous_run_idThe API returns it when this turn continued an earlier run. If not, it is null.

To make a revision, create a new run on the same Format. Set previous_run_id to the finished turn. For a partner, this is the same as “send another message on the same thread” (like an LLM previous_response_id). Platform detail: Continue a run.

Important practices:

  • Continue with previous_run_id. Never post thread_id. If a body has thread_id, the API rejects it with unknown_parameter. It is a response field on both turns, not an input.
  • A continuation is a new run, with a new id, its own credits, and its own single terminal webhook. The old run stays completed permanently.
  • Send the same output_schema on each turn. The schema applies to one run only. A new run does not inherit it.
  • Use the shared thread_id to group turns in your DB.

Get the clips you asked for

When you bind the partner schema (mobidoo/live-commerce/v1), you receive:

  • full_video — the assembled vertical cut
  • opening[] / middle[] / closing[] — each scene is its own file (scene.video), with a stable scene.id

Thus, you can publish the full cut or select individual clips for your own editor / QA. Scene ids do not change for the life of that production. Store them. Do not use the array index as the key.

Treat scene.id as an opaque string. Current productions return sc_0, sc_1, …, but earlier productions returned other shapes. Thus, if you validate or construct ids with a pattern, your code will break. Store the scene.id that the receipt gives you, and send that value back on the retry.

A realistic body for the first turn (a short Samsung Q9000 sample — replace the URL / copy with your catalog):

For a complete Q9000 call, the receipt that it returns, and the clip-retry turn, refer to Best practices.

Retry only the clips you want

This flow is for a dashboard “retry this clip” control. Store the create run.id and each receipt scene.id. Then continue the thread with a fixed instruction and the selected id(s). Do not start a fresh run with the same script, unless you want a new production (new ids, full credits).

If the operator rejects a take (not a stand-in repair), put their note in instruction. Write which scene, what is wrong, and how to change it. Refer to Prefer concrete per-scene feedback.

Example — one Mid talk clip

Example — two clips that came back stand-in / failed

The two bodies do not have thread_id. previous_run_id is the full continuation contract.

The receipt is again a full opening / middle / closing list. It is not a delta and not a patch. Regenerated scenes get new media URLs. All the other scenes keep the URL from the previous turn. The two runs have the same thread_id. The API re-assembles full_video and gives it a new URL.

We measured one sc_7 retry on an 11-scene cut, from the production pair in Best practices. The receipt returned all 11 rows. 10 of 11 scene URLs stayed byte-identical, and only sc_7 changed. The API re-assembled full_video at the same 73.360 s. After the retry, the previous URL of the scene still resolves 200. Thus, a create receipt that you stored stays valid, and you can keep the two takes.

What clip retry can and cannot change

AskAnswer
Different take, framing, lighting, or B-roll for named scene ids✅ re-render those clips + re-assemble
Finalize a scene that returned stand-in or failed✅ same
Different words, price read, or longer/shorter line❌ new full production (the voice spine changes)
Different host, script, or product❌ new full production

The voice track sets the limit. A change to the looks → clip retry. A change to the words → new production and new scene ids.

A retry is a new generation, not a re-encode. The retry re-rolls all the generative parts of the frame. On the measured pair, structured overlay facts stayed exactly the same: price, discount label, spec badges, and set composition. But decorative copy in the generated product art changed its words between takes. Tell operators that they get another take, not the same frame with one detail corrected.

Budgeting a retry

Plan for approximately a twentieth of the credits of the create run for each single-clip retry. This applies when the retry uses the script, VO, host stills, and all other clips again. We measured this on production, on a retry of one under_banner scene on an 11-scene cut (2m53s wall).

This number is a guide for budgets, not a guarantee. A short production divides its fixed work across fewer clips. An earlier 8-scene cut measured nearer to a fifth. Use your own first runs to set the size of a dashboard budget. Keep generation_spend_cap_credits on each retry.

Size: two limits, and only one of them tells you

Know these limits before you send a full broadcast script. The two limits fail in opposite ways.

  • The API rejects input above 2 MiB (2097152 UTF-8 bytes) (and above 64 top-level properties), as measured on the compact JSON → loud 400. Below that limit, the API carries all of input into the run, as a file.
  • The API cuts instruction at ~4 000 characters when it carries it into the run. It keeps the start of the text → no error. The tail is missing.

Thus, put the broadcast script in input, not in instruction. Keep instruction short.

input must be a JSON object (a stringified blob gets 400). attachments carries only images (up to 30). Thus, send the script in input.

Partner FAQ: webhooks

These are direct answers to the usual integration questions:

QuestionAnswer for Formats API
(A) Does a webhook fire per scene as each clip finishes?No for the Format run webhook. Formats does not emit a Formats response for each scene.
(B) Does one webhook fire when all scenes for the turn are done?Yes. When the agent turn completes, you get the final structured receipt and one format.run.terminal webhook.

Formats calls an AI agent. Under the turn, tool calls (TTS, clip renders, assemble) can finish at different times. But the partner contract is turn-final: one receipt, one Format run webhook. A scene-regen continuation is a new run. It fires its own single terminal webhook.

Job-layer events (one for each media job) exist for internal progress. They are not the published partner scene webhook yet. If you need that mapping, ask us.

More detail: Run webhooks.

Webhooks: two layers

LayerUnitFires
Format runone agent turnonce, format.run.terminal, when the turn ends
Generation jobone media jobper job, as each completes

Build on the Format layer. A clip retry fires exactly one new terminal webhook for the new run id.

Partner FAQ: scene regeneration

QuestionAnswer
Can I regenerate one scene in a finished production?Yes. Continue the same thread with previous_run_id, and name the scene id(s). Refer to Retry only the clips you want.
Must I run the whole video again?Only when the words / host / product / VO spine must change. For fixes to the looks only, use clip retry.
How do I continue the conversation?Send previous_run_id (not thread_id). The two runs have the same thread_id on the receipt.

Platform contract: Continue a run.

Copy these links into Slack / email.

TopicLink
Webhook FAQ (A vs B)https://docs.sume.com/enterprise/mobidoo/live-commerce#partner-faq-webhooks
Scene regeneration FAQhttps://docs.sume.com/enterprise/mobidoo/live-commerce#partner-faq-scene-regeneration
Threads / continuehttps://docs.sume.com/enterprise/mobidoo/live-commerce#threads-continue-the-same-production
Clip retry recipeshttps://docs.sume.com/enterprise/mobidoo/live-commerce#retry-only-the-clips-you-want
Best practices + exampleshttps://docs.sume.com/enterprise/mobidoo/best-practices
KO: webhook FAQhttps://docs.sume.com/ko-KR/enterprise/mobidoo/live-commerce#파트너-faq-웹훅
KO: scene regen FAQhttps://docs.sume.com/ko-KR/enterprise/mobidoo/live-commerce#파트너-faq-씬-재생성

Next