Referencia de la API · Platform
Flows
Chain renders, Clap's writing, posts and deliveries — start them by hand, by API, after a render, on a schedule or from a webhook (Zapier, Make, n8n).
A flow is a graph of steps — renders, Clap's words, a post, a webhook, a folder — drawn in the studio's Flows editor or sent here as JSON. Every render a run makes goes through its own endpoint (images, videos, speech): same prices, same plan gates, same refunds; Clap's writing is included. Flows belong to the workspace: teammates share them.
Several ways to start one — a flow carries up to one trigger of each kind, each with its own line into the steps: trigger.manual (« When I run it »: the studio's Run, or POST /v1/flows/{id}/runs; it can ask for a prompt and a picture at every run), trigger.render (« After a render »: a render that names the flow with flow_id on POST /v1/images/generations, /v1/videos/generations, /v1/videos/edits or /v1/audio/speech, a run with inputs.creation_id, « Run a flow » on a creation — and, when its folderId is set, everything saved or moved into that folder), trigger.schedule (every day or week at at, read in the tz time zone), trigger.webhook (« When a webhook is called »: a secret URL any app can POST to, Zapier, Make, n8n, a form, a shop; see below). A run starts from ONE trigger and runs what its lines reach.
Runs happen on the server. POST /v1/flows/{id}/runs answers 202 with the run; poll GET /v1/flows/{id}/runs/{run_id} — every look moves the run on, and runs nobody watches are moved on every minute — or pass callback_url and the finished run is POSTed there once, in the flow.run.* event shape (see Webhooks; flow.run.stopped when someone stopped it). Each step reports its status, what it made (creationId and a fresh signed url), its text, its credits and, when it failed, error. A post is never sent by the API: the « Post to socials » step makes the run wait (status: "waiting", waiting names the clip, caption and platforms) until someone posts it — or lets it go — from the studio (TikTok and YouTube want a person's click per post); a post left waiting for 7 days is let go and the run carries on. POST …/runs/{run_id}/stop stops a run: steps not started are skipped, a render already sent still finishes and lands in the library.
The graph: nodes — { id, n, type, x, y, config }, where n is the step's number ({{#n}} inserts what step n wrote, or the link of what it rendered, into any text) — and edges — { from, to }, the ORDER (a step runs once every step leading to it is done). {{#n.field}} reads one field of a webhook's body ({{#1.customer.name}}). Types and their config: trigger.manual (askPrompt, askImage), trigger.render (kind: video · image · audio, folderId), trigger.schedule (every, at "HH:MM", day 0–6, tz), trigger.webhook (promptField: the field read as {{#1}}, empty = the whole body; imageField: a field holding an https picture; salt: a new value is a new URL), generate.image (prompt, model, aspect), generate.video (prompt, model, seconds, aspect, startFrom = an earlier image step), generate.voice (prompt = the words, model, voice), clap.write (instruction, about = an earlier step), publish.social (platforms, clip = an earlier clip step, caption), send.webhook (url, message — Discord and Slack show the message, other endpoints get the run as JSON), library.folder (folderId). The server re-sanitizes every graph it stores; send the one GET returns to keep what you do not change.
Plan, draft or published. Every plan builds flows. Running one, the studio's Run once included, and publishing it (published: true) come with the Studio plan or higher (403 plan_required below it). A draft runs only from the studio's editor; a published flow also starts by its schedule, its watched folder, flow_id, its webhook URL and POST /v1/flows/{id}/runs (a draft answers 409 flow_not_published there). Limits: 24 steps and 100 flows per workspace, 6 runs a minute per person, 50 automatic runs a day per flow (watched folder + schedule), 30 a minute and 500 a day from its webhook, the last 30 runs kept. A scheduled or webhook run runs as the person who made the flow, on the workspace's credits. A run that needs credits it does not have fails at that step with the endpoint's own 402 message.
The webhook URL (trigger.webhook): hookUrl on GET /v1/flows/{id}, https://eroq.ai/hooks/flows/{id}/{token}. No key: the URL is the key, keep it private (a new salt replaces it). POST any JSON, a form, or plain text (up to 64 KB): it is step #1, {{#1}} reads its promptField (or all of it), {{#1.field}} any field. It answers 202 { "ok": true, "run_id", "flow_id", "status": "running" }; 404 for an unknown or replaced URL, 409 flow_not_published, 403 plan_required, 429 with Retry-After, 400 content_blocked. A GET only describes the URL, so a link preview never starts a run. ?callback_url= (or an X-Eroq-Callback-Url header) gets the finished run. From Zapier: Webhooks by Zapier › POST; from Make: HTTP › Make a request; from n8n: the HTTP Request node.
Endpoints
Selecciona un verbo para cargar su solicitud, su playground y su respuesta.
List the workspace's flows: their triggers, their chain, their last run, the next scheduled run and a run waiting on a post.
Create a flow from a graph, a template, or blank, starting with the trigger you pick.
Up to 80 characters.
{ nodes, edges } — see the notes. Sanitized: unknown steps, loops and lines into a trigger are dropped.
Start from a template instead: caption-every-clip, clip-to-tiktok, daily-clip, still-to-reel, clip-to-discord, webhook-to-clip, scripted-voiceover.
Without graph or template: the trigger a blank flow starts with, manual (default), render, schedule or webhook.
With trigger: "schedule": the IANA time zone its hour is read in. Default UTC.
Put it online at once (its schedule, watched folder, webhook URL and API runs start it). Studio plan or higher. Default false: a draft.
One flow — its graph, its webhook URL when it has the trigger — and its last 10 runs.
Rename it, replace its graph, publish it or take it back to a draft. A run underway keeps the graph it started with.
New name, up to 80 characters.
The whole graph, replaced (sanitized). Omit to keep it.
Online (true, Studio plan or higher) or a draft (false, never refused).
Delete the flow and its runs — everything it rendered stays in the library.
Run it now: 202 with the run, which moves on in the background — poll it. Refused (400) before anything is spent when a step is not set up or an input the trigger asks for is missing.
Where it starts: manual (default), render (needs inputs.creation_id), schedule (try a scheduled flow now), webhook (with inputs.payload).
prompt (asked by askPrompt, read as {{#1}}), creation_id (a creation of yours: the render to run on, or the picture askImage wants), image_url (an https picture, for askImage), payload (the body a « When a webhook is called » trigger reads, as if its URL had been called), locale (the language Clap writes in).
An https URL that gets the finished run, once, as a flow.run.* event body (Zapier callbacks, n8n's Wait node « On webhook call »).
The flow's runs, newest first (the last 30) — source says how each started: studio, api, attach, folder, schedule, webhook.
Where a run stands, step by step — looking moves it on. waiting names the post it waits on.
Stop a run: steps not started are skipped, a post it waits on is let go; a render already sent still finishes (and is paid).
curl https://eroq.ai/v1/flows \
-H "Authorization: Bearer $EROQ_API_KEY"Respuesta
{
"object": "list",
"flows": [{
"id": "1e45…", "name": "Prompt to Discord",
"triggers": ["trigger.manual"], "renderKind": null, "published": true, "nextRunAt": null,
"steps": ["trigger.manual", "generate.video", "send.webhook"],
"lastRun": { "status": "done", "at": "2026-10-02T14:05:00Z", "source": "api" }, "waiting": null
}]
}