Brand UGC
Queue a Shopify brand UGC reel with curl. Poll until the video cell is fresh.
Hardcoded pipeline: brand name + Shopify storefront URL → workspace Brand Reachout 1 → {slug}_products → first synced product → ugc_video.* DAG → 9:16 reel.
Do not pass workspaceId. Do not call columns.author. Secret org key only (pim_sk_…, preset org_admin or workspace_admin).
- Prod:
https://intelligence-backend.gethelium.co - Local:
http://localhost:3001 - Catalog:
GET /v1/catalog/ugc - MCP:
pim_ugc— sameop+ body. Skillpim/recipes/brand-ugc.
runId is the {slug}_products resource type id. There is no separate run table.
1. Queue
curl -sS https://intelligence-backend.gethelium.co/v1/ugc \
-H "Authorization: Bearer pim_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"op": "run",
"brandName": "Asopalav",
"url": "https://asopalav.com"
}'{
"ok": true,
"module": "ugc",
"op": "run",
"data": {
"id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"status": "queued",
"phase": "syncing",
"workspaceId": "11111111-2222-4333-8444-555555555555",
"hostname": "asopalav.com",
"resourceTypeKey": "asopalav_products"
}
}HTTP returns immediately. A second run for the same brand reuses that type (and any in-flight Shopify sync); status may already be "running".
Save data.id — that is runId for get.
2. Poll
curl -sS https://intelligence-backend.gethelium.co/v1/ugc \
-H "Authorization: Bearer pim_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"op": "get",
"runId": "a1b2c3d4-e5f6-4789-a012-3456789abcde"
}'Stop when data.status is succeeded or failed. Sync + video is typically 15–30+ minutes (sync timeout ~15m, generate ~40m). Poll every 8s.
RUN_ID="a1b2c3d4-e5f6-4789-a012-3456789abcde"
while true; do
BODY=$(curl -sS https://intelligence-backend.gethelium.co/v1/ugc \
-H "Authorization: Bearer pim_sk_live_..." \
-H "Content-Type: application/json" \
-d "{\"op\":\"get\",\"runId\":\"$RUN_ID\"}")
STATUS=$(printf '%s' "$BODY" | jq -r '.data.status')
printf '%s' "$BODY" | jq '{status: .data.status, phase: .data.phase, product: .data.product, error: .data.error}'
case "$STATUS" in succeeded|failed) printf '%s' "$BODY" | jq '.data'; break ;; esac
sleep 8
doneIn progress (generating)
{
"ok": true,
"module": "ugc",
"op": "get",
"data": {
"id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"status": "running",
"phase": "generating",
"workspaceId": "11111111-2222-4333-8444-555555555555",
"brandName": "Asopalav",
"url": "https://asopalav.com",
"hostname": "asopalav.com",
"resourceTypeKey": "asopalav_products",
"resourceTypeId": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"connectorInstanceId": "c0c0c0c0-1111-4222-8333-444444444444",
"syncRunId": "d1d1d1d1-2222-4333-8444-555555555555",
"resourceId": "bbbbbbbb-cccc-4ddd-8eee-ffffffffffff",
"product": {
"id": "bbbbbbbb-cccc-4ddd-8eee-ffffffffffff",
"title": "Banarasi Silk Saree"
},
"columnIds": {
"ugc_video.audience": "01010101-0000-4000-8000-000000000001",
"ugc_video.vibe": "01010101-0000-4000-8000-000000000002",
"ugc_video.concept": "01010101-0000-4000-8000-000000000003",
"ugc_video.script": "01010101-0000-4000-8000-000000000004",
"ugc_video.product_stills": "01010101-0000-4000-8000-000000000005",
"ugc_video.avatar_description": "01010101-0000-4000-8000-000000000006",
"ugc_video.avatar_stills": "01010101-0000-4000-8000-000000000007",
"ugc_video.environment_description": "01010101-0000-4000-8000-000000000008",
"ugc_video.environment_stills": "01010101-0000-4000-8000-000000000009",
"ugc_video.video": "01010101-0000-4000-8000-00000000000a"
},
"cells": {
"ugc_video.audience": { "state": "fresh", "hasValue": true },
"ugc_video.vibe": { "state": "fresh", "hasValue": true },
"ugc_video.concept": { "state": "fresh", "hasValue": true },
"ugc_video.script": { "state": "pending", "hasValue": false },
"ugc_video.product_stills": { "state": "fresh", "hasValue": true },
"ugc_video.avatar_description": { "state": "idle", "hasValue": false },
"ugc_video.avatar_stills": { "state": "idle", "hasValue": false },
"ugc_video.environment_description": { "state": "idle", "hasValue": false },
"ugc_video.environment_stills": { "state": "idle", "hasValue": false },
"ugc_video.video": { "state": "idle", "hasValue": false }
},
"error": null,
"createdAt": "2026-09-02T11:00:00.000Z",
"updatedAt": "2026-09-02T11:12:00.000Z",
"finishedAt": null
}
}Success is ugc_video.video fresh with a value — not merely status: "running".
Succeeded
{
"ok": true,
"module": "ugc",
"op": "get",
"data": {
"id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"status": "succeeded",
"phase": "succeeded",
"workspaceId": "11111111-2222-4333-8444-555555555555",
"brandName": "Asopalav",
"url": "https://asopalav.com",
"hostname": "asopalav.com",
"resourceTypeKey": "asopalav_products",
"resourceTypeId": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"connectorInstanceId": "c0c0c0c0-1111-4222-8333-444444444444",
"syncRunId": "d1d1d1d1-2222-4333-8444-555555555555",
"resourceId": "bbbbbbbb-cccc-4ddd-8eee-ffffffffffff",
"product": {
"id": "bbbbbbbb-cccc-4ddd-8eee-ffffffffffff",
"title": "Banarasi Silk Saree"
},
"columnIds": {
"ugc_video.audience": "01010101-0000-4000-8000-000000000001",
"ugc_video.vibe": "01010101-0000-4000-8000-000000000002",
"ugc_video.concept": "01010101-0000-4000-8000-000000000003",
"ugc_video.script": "01010101-0000-4000-8000-000000000004",
"ugc_video.product_stills": "01010101-0000-4000-8000-000000000005",
"ugc_video.avatar_description": "01010101-0000-4000-8000-000000000006",
"ugc_video.avatar_stills": "01010101-0000-4000-8000-000000000007",
"ugc_video.environment_description": "01010101-0000-4000-8000-000000000008",
"ugc_video.environment_stills": "01010101-0000-4000-8000-000000000009",
"ugc_video.video": "01010101-0000-4000-8000-00000000000a"
},
"cells": {
"ugc_video.audience": { "state": "fresh", "hasValue": true },
"ugc_video.vibe": { "state": "fresh", "hasValue": true },
"ugc_video.concept": { "state": "fresh", "hasValue": true },
"ugc_video.script": { "state": "fresh", "hasValue": true },
"ugc_video.product_stills": { "state": "fresh", "hasValue": true },
"ugc_video.avatar_description": { "state": "fresh", "hasValue": true },
"ugc_video.avatar_stills": { "state": "fresh", "hasValue": true },
"ugc_video.environment_description": { "state": "fresh", "hasValue": true },
"ugc_video.environment_stills": { "state": "fresh", "hasValue": true },
"ugc_video.video": { "state": "fresh", "hasValue": true }
},
"error": null,
"createdAt": "2026-09-02T11:00:00.000Z",
"updatedAt": "2026-09-02T11:28:00.000Z",
"finishedAt": "2026-09-02T11:28:00.000Z"
}
}The reel is the ugc_video.video cell on data.product.id in Brand Reachout 1. Fetch it with POST /v1/cells { "op": "get", "workspaceId", "resourceId", "columnDefinitionId": data.columnIds["ugc_video.video"] }.
Failed (HTTP 200)
A finished failure is still ok: true. Read data.error.
{
"ok": true,
"module": "ugc",
"op": "get",
"data": {
"id": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"status": "failed",
"phase": "failed",
"workspaceId": "11111111-2222-4333-8444-555555555555",
"brandName": "Asopalav",
"url": "https://asopalav.com",
"hostname": "asopalav.com",
"resourceTypeKey": "asopalav_products",
"resourceTypeId": "a1b2c3d4-e5f6-4789-a012-3456789abcde",
"connectorInstanceId": "c0c0c0c0-1111-4222-8333-444444444444",
"syncRunId": "d1d1d1d1-2222-4333-8444-555555555555",
"resourceId": null,
"product": null,
"columnIds": {},
"cells": {},
"error": "Shopify sync finished with no products",
"createdAt": "2026-09-02T11:00:00.000Z",
"updatedAt": "2026-09-02T11:04:00.000Z",
"finishedAt": "2026-09-02T11:04:00.000Z"
}
}Other error strings: Shopify sync failed / timed out, UGC generate timed out, Column ugc_video.script failed.
Errors (HTTP)
403 — publishable, generate_only, or resource_writer on run. get is read.
{
"ok": false,
"error": {
"code": "forbidden",
"message": "Key cannot ugc.run",
"module": "ugc",
"op": "run"
}
}404 — org has no workspace named exactly Brand Reachout 1 (never auto-created), or runId is not that workspace's product type.
{
"ok": false,
"error": {
"code": "not_found",
"message": "Workspace \"Brand Reachout 1\" was not found in this organisation",
"module": "ugc",
"op": "run"
}
}What run kicks
- Resolve Brand Reachout 1 in the key's org.
- Ensure type
{slug}_products(≤48 chars, e.g.asopalav_products). Never SYSTEMproduct. - Ensure
shopify_publicfor that hostname + type; synccreate_all_new. - Publish
ugc_video.*if not already live. - Generate the first active product only (
resourceIds: [thatId],onlyMissing: true).
| Key | Output | Depends on |
|---|---|---|
ugc_video.audience | text | — |
ugc_video.vibe | text | audience |
ugc_video.concept | text | audience, vibe |
ugc_video.script | text | audience, vibe, concept |
ugc_video.product_stills | image multi | row images |
ugc_video.avatar_description | text | audience, concept, script |
ugc_video.avatar_stills | image multi | avatar_description |
ugc_video.environment_description | text | audience, vibe, concept, script |
ugc_video.environment_stills | image multi | environment_description |
ugc_video.video | video | script, vibe, three stills |
Video model: alibaba/wan-3.0/reference-to-video (9:16, 15s, 720p, audio). Out of scope: ElevenLabs, multi-model video A/B, non-Shopify, caller-chosen workspace.
Statuses: queued · running · succeeded · failed.
Phases: provision · syncing · ensuring_columns · generating · succeeded · failed.