Generic UGC
Queue one Shopify product into a UGC reel. Poll until videoUrl is an HTTPS mp4.
One product from a Shopify URL → workspace Generic UGC Video → existing type generic_ugc_video → ugc_video.* DAG → 9:16 reel.
Do not pass workspaceId. Do not call columns.author or resources.create_type. Secret org key only (pim_sk_…, preset org_admin or workspace_admin).
This is not Brand UGC. Brand UGC syncs a whole {slug}_products catalog in Brand Reachout 1. This API inserts one row on the shared type.
- Prod:
https://intelligence-backend.gethelium.co - Local:
http://localhost:3001 - Catalog:
GET /v1/catalog/generic_ugc - HTTP only. Not on MCP. Skill
pim/recipes/generic-ugc.
runId is the new resource id. There is no separate run table.
1. Queue
curl -sS https://intelligence-backend.gethelium.co/v1/generic_ugc \
-H "Authorization: Bearer pim_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"op": "run",
"url": "https://www.wforwoman.com"
}'A product-page URL (https://www.wforwoman.com/products/some-handle) fetches that SKU via /products/{handle}.json. Any other URL takes the last product from /products.json?limit=10.
{
"ok": true,
"module": "generic_ugc",
"op": "run",
"data": {
"id": "ab7b6f5d-42a7-4c9c-9aea-750a7772db61",
"status": "queued",
"phase": "generating",
"workspaceId": "cb2a33f4-e96f-4871-8950-904d6296cf82",
"hostname": "wforwoman.com",
"resourceTypeKey": "generic_ugc_video",
"resourceId": "ab7b6f5d-42a7-4c9c-9aea-750a7772db61",
"title": "Blue Floral Printed Modal Straight Kurta with Pants Co-ord Set"
}
}HTTP returns immediately. Save data.id — that is runId for get. Each run creates a new row.
2. Poll
curl -sS https://intelligence-backend.gethelium.co/v1/generic_ugc \
-H "Authorization: Bearer pim_sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"op": "get",
"runId": "ab7b6f5d-42a7-4c9c-9aea-750a7772db61"
}'Stop when data.status is succeeded or failed. Stills ~1–2 min; video ~5–15 min (generate timeout ~40m). Poll every 8s.
RUN_ID="ab7b6f5d-42a7-4c9c-9aea-750a7772db61"
while true; do
BODY=$(curl -sS https://intelligence-backend.gethelium.co/v1/generic_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, videoUrl: .data.videoUrl, error: .data.error}'
case "$STATUS" in succeeded|failed) printf '%s' "$BODY" | jq '.data'; break ;; esac
sleep 8
done3. Get the video
When data.status is succeeded, data.videoUrl is an HTTPS mp4 on assets.gethelium.co. Play or download that URL.
{
"ok": true,
"module": "generic_ugc",
"op": "get",
"data": {
"id": "ab7b6f5d-42a7-4c9c-9aea-750a7772db61",
"status": "succeeded",
"phase": "succeeded",
"videoUrl": "https://assets.gethelium.co/workspaces/cb2a33f4-e96f-4871-8950-904d6296cf82/generative/.../0-….mp4",
"cells": {
"ugc_video.video": { "state": "fresh", "hasValue": true }
},
"error": null
}
}videoUrl is projected on read (AssetRefs stay in Postgres). Grid POST /v1/resources op=grid on the same type also returns cells["ugc_video.video"].value.src.