What is each::workflows?
A workflow is a saved recipe of AI steps that runs with one API call. You choose the models, prompts and post-processing once. Your app sends the inputs (usually a photo or a short text) and gets the finished result back.Why use a workflow?
Workflows are free. You pay only for the model steps that run.
Authoring rules
Follow these and a workflow runs on the first try.- Reference values with
$.paths:$.inputs.<name>for inputs,$.<step_id>.primaryor$.<step_id>.outputfor earlier steps, brackets for arrays ($.step.output[0]).{{inputs.prompt}}is not a reference; it is sent to the model as literal text. - A value that is exactly one reference keeps its type (URL, number, object). A reference
inside a longer string is inserted as text:
"A portrait of $.inputs.name in neon light". primaryis the main result. For image and video models it is the file URL. Foreachlabs-llm-routerit is the chat completion, so the text is at$.<step_id>.primary.choices[0].message.content. Foreachlabs-http-stepit is the response, so JSON fields are at$.<step_id>.primary.output.<field>.- Prompt fields quote whole references. If a
prompt-like field (prompt,text,content,message,caption,title,description) is exactly$.step.primaryor$.step.output, the value arrives wrapped in quotes. Reference a deeper field or embed it in a sentence. - Step types are
model,parallel,choiceandpass. HTTP requests and Python code are not step types; they run as model steps througheachlabs-http-stepandeachlabs-python-step(private beta). See HTTP steps. - Every step needs a unique
id, including steps inside branches. A step can only reference inputs and steps that ran before it. - Inputs live in
input_schema.properties. Each field takestype(string,number,boolean,image,video,voicefor audio,file),required(true/false) and an optionaldefault_value. Files are passed as public URLs. Give every optional input adefault_value, because a run fails if a step references an omitted input with no default. - Parallel: each branch is a list of
steps. Later steps reference branch steps by their own id. - Choice: a
condition, acondition_met_branchand adefault_branch, both non-empty. Afterwards,$.<choice_id>.primaryis the result of whichever branch ran. Operators:equals,not_equals,greater_than,greater_than_or_equal,less_than,less_than_or_equal,string_equals,string_matches(a*wildcard pattern such as"*.mp4"),exists,is_not_null, combined withand,orandnot. - Fallback is set per model step and has its own
params, because the second model may take different parameters. - The result of a run is the output of its last step. To return named values, add
"metadata": {"output_mapping": {"video": "$.final.primary"}}to the definition. - Models are checked when a step runs, not when you save. Read a model’s inputs with
GET /v1/models/{slug}and test the workflow once before shipping it.
Create, run and read
output (the last step’s result), workflow_output (your named outputs) and
step_outputs.<step_id> for every step. Add "webhook_url" to the run request to be notified
instead of polling. If creating returns 400 invalid argument, send the definition to
PUT /v1/workflows/{workflowID}/versions/v1 as {"definition": {...}} to see the exact error.
Examples
Each example is a completeworkflow.json for the create call. Replace the input URLs with your
own files, uploaded with each::storage if they are not public yet.
1. One-photo effect
Turn one photo into a finished clip. The prompt stays on Eachlabs, and a second model takes over if the first one fails.{"photo": "https://example.com/selfie.jpg"}
2. Restyle a photo, then animate it
Chain two models: edit the image, then pass the result to a video model.{"photo": "https://example.com/portrait.jpg", "style": "a watercolor illustration"}
$.restyle.primary is the edited image, from the fallback model if it ran. style is optional
because it has a default.
3. An LLM writes the prompt
A vision LLM looks at the product and writes the scene. The image and video models follow it.{"person": "https://example.com/creator.jpg", "product": "https://example.com/honey.png"}
4. Two photos, one clip, with music
Prepare both photos at the same time, put both people in one video, then resize it and add music.{"photo_a": "https://example.com/a.jpg", "photo_b": "https://example.com/b.jpg", "music": "https://example.com/track.mp3"}
Both edits run at the same time. To use the same music every time, replace $.inputs.music with a fixed URL.
5. A reliable vision call
Write alt text for a product photo. If the first provider fails, a second one answers.{"image": "https://cdn.dummyjson.com/product-images/groceries/honey-jar/1.webp"}
The run’s workflow_output.alt_text holds the sentence, whichever provider answered.
6. Call an API, then use its data
Fetch a product from an API and turn it into an ad image. This example calls the public DummyJSON test API; pointurl at your own API.
{"product_id": "27"}
eachlabs-http-steptakesurl,method,headers,query_params,body(a JSON object forPOST,PUTorPATCH),timeout_seconds(up to 30 recommended) andfail_on_status.- Set
fail_on_statusto"non_2xx"so an error response stops the run. - To run your own code, deploy it as an HTTPS endpoint (a serverless function is enough),
POSTthe inputs to it, and read its JSON reply in the next step. Organizations in the private beta can use theeachlabs-python-stepmodel instead. - Only public URLs are reachable. Definitions are stored, so use scoped, read-only tokens in
headers.
7. Let AI choose the path
Ask a vision model what the photo shows, then pick the matching recipe. The next step continues from whichever branch ran.{"photo": "https://example.com/dog.jpg"}
string_matches uses * wildcards, so *PET* also matches PET.. Use and, or and not to
combine conditions.
8. Several scenes in parallel, joined with music
Each branch builds one scene (image, then video). All scenes render at the same time, then the clips are joined and music is added.{"product": "https://cdn.dummyjson.com/product-images/groceries/honey-jar/1.webp", "product_name": "honey jar", "music": "https://example.com/track.mp3"}
Steps inside a branch run in order; the branches run at the same time, so three scenes take about
as long as one. merge-videos joins the clips in the listed order.
Checklist for agents
- Every step has a unique
id; every$.reference points to an input or an earlier step. - References use
$., never{{...}}. - Every optional input has a
default_value. - Model slugs and parameters come from
GET /v1/models/{slug}. - LLM text is read from
primary.choices[0].message.content; HTTP JSON fromprimary.output.<field>. - The last step produces the final result, or
metadata.output_mappingnames it. - You ran it once and checked
step_outputsbefore giving it to users.
Endpoints
All paths are relative tohttps://api.eachlabs.ai.