Skip to main content
Workflows let you chain multiple models together into a single endpoint, creating complex pipelines that run as one API call. Instead of orchestrating individual model requests yourself, you define the steps and fal handles the execution, passing outputs from one model as inputs to the next. Unlike standard model calls that return a single result, workflows emit streaming events as each step progresses, giving you access to intermediate results along the way. This makes them ideal for multi-step generation tasks where you want real-time feedback. For more on consuming streaming responses, see streaming inference.

Workflow as an API

Workflow APIs work the same way as other model endpoints, you can simply send a request and get a response back. However, it is common for workflows to contain multiple steps and produce intermediate results, as each step contains their own response that could be relevant in your use-case. Therefore, workflows benefit from the streaming feature, which allows you to get partial results as they are being generated. If you submit a workflow to the queue and get the result with a webhook, you do not get the streaming events. To get the endpoint and the request ID of each step in the result, see Step request IDs.

Workflow Events

The workflow API will trigger a few events during its execution, these events can be used to monitor the progress of the workflow and get intermediate results. Below are the events that you can expect from a workflow stream:

The submit Event

This event is triggered every time a new step has been submitted to execution. It contains the app_id, request_id and the node_id.

The completion Event

This event is triggered upon the completion of a specific step.

The output Event

The output event means that the workflow has completed and the final result is ready.

The error Event

The error event is triggered when an error occurs during the execution of a step. The error object contains the error.status with the HTTP status code, an error message as well as error.body with the underlying error serialized.

The recovery Event

The workflow sends this event when a step fails and the workflow starts the fallback of that step.
  • reason is the failure type that started the fallback: server_error, policy, or forced.
  • outcome is submitted when the fallback started. It is submit_failed when fal could not start the fallback.
  • After a submitted recovery event, a submit event gives the request ID of the fallback.

The warning Event

The workflow sends this event when the configuration of a step has a problem, but the workflow can continue. For example, fal ignores a fallback configuration that it cannot use. The step then runs without a fallback.

Fallbacks

A step can have one fallback. If the step fails, fal runs the fallback endpoint for that step. The workflow then continues with the output of the fallback. Add the fallback to the config of the node:
The failure types are:
  • policy: the endpoint returned HTTP 422.
  • server_error: the endpoint returned a different 4xx or 5xx status.
The fallback must give an output with the same fields that the next steps use. In the example, both endpoints return video, so a next step can use $node-k3TqP9xL2a.video.url for both. Fallback rules:
  • fal tries the fallback one time. If the fallback also fails, the workflow stops with an error event.
  • fal does not start the fallback when the input of the step is not valid. For example, a $ reference that does not resolve stops the workflow.
  • If fallbacks has more than one step, fal ignores the configuration and sends a warning event. The same occurs when the fallback step is not valid.
  • When a step has a fallback, fal disables the automatic model fallbacks of the endpoint for that step.

Test the Fallbacks

To test the fallbacks of a workflow, add fal_fallbacks=1 to the request URL. fal then runs the fallback of each step that has one, instead of the endpoint of the step. The reason of the recovery event is forced.

Step Request IDs

When you submit a workflow to the queue, the result and the webhook payload contain only the final output. To get the endpoint and the request ID of each step, send X-Fal-Workflow-Envelope: true with the request. Use the request IDs to get the cost of each step from billing events. You can also find each step in your request history.
The result then has two fields. output is the result that you get without the header. nodes has one entry for each step that fal submitted. The keys of nodes are the node IDs of your workflow.
To get the total cost of a run:
  1. Collect all request IDs in nodes. Include each failed_request_id.
  2. Get the billing events with the request_id filter. One call accepts up to 50 request IDs.
  3. Set start and end to cover the time of the run. If you do not set start, you get only the last 24 hours.
  4. Add the cost of the billing events.
If a request ID is not in the billing events for that time window, fal did not charge for it per request. Steps that run on your own deployed apps are the exception. fal bills these steps by runner time, so billing events do not list them.

When a Step Fails

If the workflow stops with an error, the error body also contains nodes. The HTTP status code does not change. The steps that were still running when the workflow stopped are also in nodes, because they continue to run.

Limits

  • Without the header, the result does not change.
  • The header does not change the streaming events. In a stream, use the submit and recovery events.
  • nodes shows only the fallback that you configured. It does not show the retries that fal does on the platform.
  • If the workflow stops without a result, for example after a timeout, you do not get nodes.

Example

A cool and simple example of the power of workflows is workflows/fal-ai/sdxl-sticker, which consists of three steps:
1
Generates an image using fal-ai/fast-sdxl.
2
Remove the background of the image using fal-ai/imageutils/rembg.
3
Converts the image to a sticker using fal-ai/face-to-sticker.
What could be a tedious process of running and coordinating three different models is now a single endpoint that you can call with a single request.

Type Definitions

Below are the type definition in TypeScript of events that you can expect from a workflow stream:
The result that you get when you send the X-Fal-Workflow-Envelope: true header: