Common Workflows
Short examples for the loops agents usually need: discover state, prepare content, confirm the action, then track the result.
Discover workspace state
reelsfarm agent status
reelsfarm social connected --agent
reelsfarm assets list --category products --agent
reelsfarm posts list --status SCHEDULED --agentconst account = await rf.account.get();
const connected = await rf.social.listConnected();
const products = await rf.assets.list("products", { limit: 10 });
const posts = await rf.posts.list({ status: "SCHEDULED", limit: 10 });Generate an avatar
reelsfarm avatars generate \
--prompt "Creator selfie style, bright room, holding a phone" \
--model nano-banana-pro \
--agent
reelsfarm confirm conf_123 --agentconst preparedOrJob = await rf.avatars.generate({
prompt: "Creator selfie style, bright room, holding a phone",
model: "nano-banana-pro",
});
if ("wait" in preparedOrJob) {
const result = await preparedOrJob.wait();
}Generate slideshow text
reelsfarm slideshows generate-text \
--prompt "Summer serum launch for TikTok" \
--slide-count 6 \
--agentconst slideshowText = await rf.slideshows.generateText({
prompt: "Summer serum launch for TikTok",
slideCount: 6,
});Upload product images from an agent
These calls are composable primitives, not a fixed campaign workflow. The create call reserves the shared product-assets quota in request order. In Review mode, confirm it once; completion is an idempotent continuation that must use the same MCP connection and needs no second confirmation.
create_product_upload_sessions
{
"idempotencyKey": "summer-products-upload-001",
"files": [
{ "clientId": "front", "filename": "front.webp", "contentType": "image/webp", "size": 481233, "displayName": "Serum front" },
{ "clientId": "detail", "filename": "detail.jpg", "contentType": "image/jpeg", "size": 732190 }
]
}
PUT each sessions[].uploadUrl
Use every returned header and the exact declared file bytes.
complete_product_upload_sessions
{ "sessionIds": ["session_uuid_1", "session_uuid_2"] }Partial quota fill
The response accepts as many files as fit, in input order, and returns the rest under skipped. Sessions expire after 15 minutes; each file is limited to 100 MB and must be PNG, JPEG, or WebP.
Finalize and export a slideshow video
prepare_finalize_slideshow
{ "slideshowId": "slideshow_uuid", "slides": [/* strict finalized slide objects */], "idempotencyKey": "finalize-summer-001" }
get_slideshow_export_job_status
{ "jobId": "finalize_job_id" }
prepare_export_slideshow_video
{ "slideshowId": "slideshow_uuid", "idempotencyKey": "video-summer-001" }
get_slideshow_video_export_job_status
{ "jobId": "video_export_job_id" }Video export uses the slideshow-video credit cost. If the finalized slideshow has not changed, the prepare call can return a cached normalized video artifact immediately instead of a new job.
Reuse videos in UGC and schedule the result
list_videos
{ "sourceType": "SLIDESHOW", "limit": 20 }
prepare_generate_ugc_video
{
"idempotencyKey": "ugc-summer-001",
"parts": [
{ "videoUrl": "/api/assets/user-uploads?key=user/hooks/hook.mp4", "sourceType": "my-hooks", "assetCategory": "hooks" },
{ "videoId": "slideshow_video_uuid", "sourceType": "my-videos", "assetCategory": "videos" }
],
"quality": "high"
}
get_video_job_status
{ "jobId": "ugc_job_id" }
prepare_schedule_post
{
"contentType": "UGC_VIDEO",
"contentId": "completed_ugc_video_uuid",
"scheduledFor": "2026-07-20T15:00:00Z",
"platforms": [{ "platform": "TIKTOK", "connectionId": "conn_123" }],
"idempotencyKey": "schedule-summer-001"
}Ordered parts
Part order is composition order, so placing a reusable slideshow video after a hook produces the intended hook-then-slideshow UGC output. A part must provide exactly one of videoId or videoUrl.
Generate a product scene
const scene = await rf.productScenes.generate({
avatarUrl: "https://example.com/avatar.png",
productImageUrl: "https://example.com/product.png",
prompt: "Natural UGC kitchen counter shot, creator holding the product",
});Product scene generation prepares an async Product Studio composition. Confirm the prepared action, then poll the product scene job status or wait through the SDK job wrapper.
Schedule content
reelsfarm posts schedule \
--content-type SLIDESHOW \
--content-id sl_123 \
--when 2026-07-01T15:00:00Z \
--platforms tiktok:conn_123 \
--caption "Launch day" \
--agent
reelsfarm confirm conf_123 --agentconst prepared = await rf.posts.schedule({
contentType: "SLIDESHOW",
contentId: "sl_123",
scheduledFor: "2026-07-01T15:00:00Z",
caption: "Launch day",
platforms: [{ platform: "TIKTOK", connectionId: "conn_123" }],
});Create an automation
reelsfarm automations create \
--json-definition '{"name":"Daily TikTok","status":"PAUSED","targetConnectionId":"conn_123","schedule":{"slots":[{"days":["mon"],"timeLocal":"09:00"}]},"content":{"topic":"mindset","slidesCount":5}}' \
--agentAutomation creation defaults to a prepared action. Keep new automations paused until the user has reviewed content rules, account target, and schedule.
Track the result
reelsfarm posts status --id post_123 --agent
reelsfarm events recent --limit 20 --agentconst status = await rf.posts.getStatus("post_123");
const events = await rf.events.recent({ limit: 20 });