Skip to content

Understanding Tasks in FFmate ​

A task in FFmate represents an FFmpeg command execution such as transcoding a video, extracting audio, or applying filters.

When you submit a task, FFmate triggers FFmpeg under the hood to perform the media processing. Tasks can be submitted on their own or grouped into batches to handle multiple files efficiently in one go.

Every task follows a structured lifecycle, progressing from submission to execution and ultimately reaching completion or failure.

Before diving into task execution, let's first go through the lifecycle of tasks and their corresponding statuses in FFmate.

StatusDescription
QUEUEDThe task is waiting in the processing queue
PRE_PROCESSINGThe task's pre-processing script is running
RUNNINGThe main FFmpeg command is currently executing
POST_PROCESSINGThe task's post-processing script is running
DONE_SUCCESSFULThe task completed successfully
DONE_ERRORThe task encountered an error and failed
DONE_CANCELEDThe task was manually canceled before completion

Task Flow: ​

The diagram below shows how a task progresses through its lifecycle in FFmate

Next, let's explore how to trigger and manage single tasks in FFmate

Creating a Task ​

To create a task, send a POST request to the FFmate API:

sh
curl -X POST http://localhost:3000/api/v1/tasks \
     -H "Content-Type: application/json" \
     -d '{
       "name": "Final Render for Summer Ad Campaign",
       "command": "-y -i ${INPUT_FILE} -c:v libx264 -preset fast -crf 23 -vf \"drawtext=text='${METADATA_project_name}':x=10:y=10:fontsize=24:fontcolor=white\" -c:a aac -b:a 128k ${OUTPUT_FILE}",
       "inputFile": "/media/source/client_project_final_v1.mov",
       "outputFile": "/media/deliverables/${METADATA_client_id}/final_ad_spot.mp4",
       "priority": 10,
       "metadata": {
         "project_name": "Summer Ad Campaign",
         "client_id": "CUST-12345",
         "editor": "jane.doe"
       },
       "preProcessing": {
         "scriptPath": "/opt/ffmate/scripts/verify_source.sh --input ${INPUT_FILE} --sidecar /var/tmp/ffmate_sidecar_${UUID}.json",
         "sidecarPath": "/var/tmp/ffmate_sidecar_${UUID}.json",
         "importSidecar": true
       },
       "postProcessing": {
         "scriptPath": "/opt/ffmate/scripts/upload_to_s3.sh --file ${OUTPUT_FILE} --client ${METADATA_client_id}"
       },
       "webhooks": [
         {
           "event": "task.updated",
           "url": "https://my-project-manager.com/api/hooks/ffmate-status"
         }
       ]
     }'

FFmate responds with a JSON object that contains the newly created task, including its uuid. This uuid is used to monitor the task’s progress in the next section. A task.created event is also fired via Global webhooks and Direct webhooks.

Task Properties ​

These are the properties that can be set when creating a task in FFmate:

  • name [mandatory] - A short, descriptive name to help identify and track the task in the web UI and API (e.g., "Final Render for Summer Ad Campaign"). Requests without a name are rejected with 422.

  • command — The custom command FFmate will use to run FFmpeg. This field is mandatory unless a preset is set. When a preset is set, the preset's command is always used and the task's command is ignored.

    ⚠️ Important details about how command works:

    • You don’t need to add ffmpeg at the start of the command. FFmate automatically prepends it. By default, FFmate uses the ffmpeg binary in your system’s PATH. If you want to use a different version, you can override the default with the --ffmpeg <path> command-line flag.

    • FFmate also implicitly adds the -stats_period 1 option to every command, which limits FFmpeg’s progress output to one update per second.

      You can override this by explicitly adding your own -stats_period x to the command.

      • This setting directly affects:

      • Wildcards like ${INPUT_FILE} and ${OUTPUT_FILE} can be used inside the command string. FFmate replaces them with the actual file paths when the task runs.

      • The command field also supports chaining several FFmpeg commands with &&, for example for two-pass encoding. Start every command after an && with the ${FFMPEG} wildcard (see FFmpeg Path).

  • inputFile [optional] – The path to the input media file that will be processed.

  • outputFile [optional] – The path where the transcoded file should be saved. If the specified directory does not exist, FFmate will create it automatically.

Handling Input and Output Files

  • The inputFile and outputFile properties are optional and should only be used if your command includes the placeholders ${INPUT_FILE} and ${OUTPUT_FILE}.
  • FFmate automatically replaces these placeholders with the actual file paths during execution.
  • If your command directly specifies input and output paths, you do not need to provide these properties separately.
  • priority [optional] – Sets the task's priority in the processing queue. Higher numbers mean higher priority — for example, a task with priority 100 will be processed before one with 10. Tasks with the same priority run in the order they were created.

  • preset - The UUID of a pre-configured Preset to use for this task. This field is mandatory unless a command is set. See Using a Preset for which settings the task takes from the preset.

  • labels [optional] – Up to 5 labels, each 1 to 32 characters long. Only an FFmate instance with at least one matching label picks up the task. A task without labels runs on any FFmate instance. Labels can use * as a wildcard, for example gpu-*. See --labels.

  • retries [optional] – How many times FFmate retries the task if it fails (DONE_ERROR). Each retry starts 3 seconds after the failure and puts the task back into QUEUED. The response field retried shows how many retries have run so far. Canceled tasks are not retried. Default: 0.

  • preProcessing [optional] – Defines a Pre-Processing Script to run before the task starts. Useful for preparing files, validating input, or setting up the environment.

    • scriptPath: The full path to the script or executable to run.
    • sidecarPath: The full path to the JSON file that contains all task data.
    • importSidecar: Defines if the task will re-import the sidecar JSON after the pre-processing script finishes.
  • postProcessing [optional] – Defines a Post-Processing Script to run after the task completes. Useful for cleanup, moving output files, or triggering follow-up actions.

    • scriptPath: The full path to the script or executable to run.
    • sidecarPath: The full path to the JSON file that contains all task data.
  • webhooks [optional] – Direct webhook targets tied only to this task, for example to notify a project management tool whenever the task's status changes. Each entry needs an event and a url. Only task.created, task.updated and task.deleted are sent for direct task webhooks.

  • metadata [optional] — Any JSON object you want to attach to the task. Common uses include adding context, referencing source files, or integrating with external systems.

Example:

A sample metadata object containing useful context about the source file, provided as key-value pairs:

json
"metadata": {
  "original_filename": "interview_session_03_cam_A.mxf",
  "project_code": "PROJ-SUMMER2025",
  "editor_notes": "Needs color correction pass after this transcode."
}

This is a powerful feature for:

Example 1: ​
  1. Your upstream system (CMS/PAM/DAM/MAM/workflow manager) creates a task in FFmate and includes its own identifiers in metadata (e.g., assetId, jobId).
  2. FFmate queues the task, then starts processing it.
  3. When the task finishes, FFmate sends a task.updated webhook whose status is DONE_SUCCESSFUL, DONE_ERROR or DONE_CANCELED.
  4. The original metadata you sent is returned in the webhook payload, so your system can correlate it back to the assetId / jobId that originated the task.
Example 2: ​
  1. A file is dropped into a watchfolder.
  2. FFmate creates a task and adds watchfolder file metadata to the task’s metadata JSON object.
  3. In the task, use the Task Metadata wildcard ${METADATA_<json-path>} to read those values, for example, to recreate the input folder structure in your outputFile.
json
"outputFile": "/volumes/ffmate/processed/${METADATA_ffmate.watchfolder.relativeDir}/${INPUT_FILE_BASENAME}.mp4"

Using a Preset ​

When a task sets a preset, FFmate fills in the task from the preset as follows:

SettingResult
commandAlways taken from the preset. The task's own command is ignored.
inputFile, name, metadataAlways taken from the task.
outputFile, priority, preProcessing, postProcessingTaken from the preset only if the task doesn't set them.
labels, retriesThe task inherits them from the preset only if it doesn't set them.
webhooksPreset and task webhooks are combined. Only task.* events are kept.

Monitoring a Task ​

After submitting a task, you can check its current status by sending a GET request to the FFmate API:

sh
curl -X GET 'http://localhost:3000/api/v1/tasks/{taskId}'

Replace {taskId} with the actual task UUID returned in the response when the task was created.

FFmate responds with a JSON object containing the full details of the task.

💡 Tip: You can also check the status of each task directly in the FFmate Web UI FFmate Web UI

Monitoring All Tasks ​

FFmate lets you retrieve a list of all tasks, no matter their current state—queued, processing, completed, or failed.

To get a list of all tasks, send a GET request to the FFmate API:

sh
curl -X GET 'http://localhost:3000/api/v1/tasks?page=0&perPage=100'

FFmate returns a JSON array containing all configured tasks. The X-Total response header provides the total number of tasks.

Query Parameters:

  • page [optional] – Specifies which page of results to retrieve. Default: 0.
  • perPage [optional] – Defines how many tasks should be included in each page. Default: 100.
  • status [optional] – Only returns tasks with this status, e.g. ?status=DONE_ERROR. Use one of the statuses from the table above.

💡 Tip: You can also check the status of all tasks: queued, processing, completed, or failed directly in the FFmate Web UI

Canceling a Task ​

FFmate lets you to cancel a task that is currently queued or processing. Once canceled, the task will not be executed or will be stopped if already in progress.

To cancel a task, send a PATCH request to the FFmate API by including the task's taskID in the path:

sh
curl -X PATCH 'http://localhost:3000/api/v1/tasks/{taskId}/cancel'

FFmate responds with a JSON object containing the updated details of the task. The task's status will be changed to DONE_CANCELED, and the progress will be set to 100. A task.updated event is also fired via Global webhook and Direct webhook, with status set to DONE_CANCELED. There is no separate cancel event. If this was the last unfinished task of a batch, batch.finished is fired too.

If FFmpeg is already running, FFmate stops it. A pre- or post-processing script that is already running isn't stopped. It runs to the end, and the task stays DONE_CANCELED.

💡 Tip: You can also cancel a running task directly from the FFmate Web UI with a single click—no API call needed.

Restarting a Task ​

If a task has failed or been canceled, FFmate allows you to restart it without needing to resubmit the job manually.

To restart a task, send a PATCH request to the FFmate API by including the task's ID in the path:

sh
curl -X PATCH 'http://localhost:3000/api/v1/tasks/{taskId}/restart'

FFmate responds with a JSON object containing the updated details of the task. The task's status will be reset to QUEUED, progress to 0, error cleared, startedAt/finishedAt timestamps reset, and retried set back to 0. The task will then be re-added to the processing queue according to its priority.

NOTE

  • Restarting a task will re-run the exact same command using the original input and output paths.
  • If the task was previously processing, it will start from the beginning.

Once restarted, the task will move back into the queued state and follow the standard task lifecycle. A task.updated event is also fired via Global webhook and Direct webhook, with status set to QUEUED.

💡 Tip: Need to rerun a task? You can restart it directly in the FFmate Web UI

Deleting a Task ​

Once a task is completed, canceled, or no longer needed, you can permanently remove it from FFmate.

To delete a task, send a DELETE request to the FFmate API by including the task's ID in the path:

sh
curl -X DELETE 'http://localhost:3000/api/v1/tasks/{taskId}'

FFmate responds with a 204 No Content status. The task will be removed from the system. A task.deleted event is also fired via Global webhook and Direct webhook.

Important

  • Deleting a task removes the database entry from FFmate but does not delete the input or output files.
  • Deleting a task doesn't stop it. To remove a running task, cancel it first and then delete it.

💡 Tip: Tasks can also be deleted from the FFmate Web UI

Submitting Multiple Tasks as a Batch ​

FFmate allows you to submit multiple transcoding tasks in a single request, referred to as a batch. This is ideal when processing a set of files—whether they use the same settings or different ones—as it simplifies submission and keeps related tasks grouped together.

Each batch is automatically assigned a unique batch ID, making it easy to monitor, manage, and reference the entire group of tasks as a single unit. While a batch groups multiple task submissions together, each task within it remains fully independent.

Every task in the batch is submitted as a standalone task in FFmate. This means:

  • Each task follows its own lifecycle (Queued, Running, Done).
  • Each is executed independently by ffmpeg, based on its own command or preset.
  • Each task maintains its own progress, status, and error reporting.
  • A task's success or failure does not affect others in the same batch.

INFO

FFmate processes batch tasks concurrently (up to the max-concurrent-tasks limit) or sequentially, based on priority and queue order.

How to Submit a Batch of Tasks ​

You submit a batch by sending a POST request to the /api/v1/batches endpoint.

The request body must be a JSON object with a single key, tasks, which contains an array of standard task objects (the same object you'd use for creating a single task via /api/v1/tasks.

To submit multiple tasks as a batch, send a POST request to the FFmate API:

bash
curl -X POST http://localhost:3000/api/v1/batches \
     -H "Content-Type: application/json" \
     -d '{
       "tasks": [
         {
           "name": "Convert Episode 1 to WebM",
           "inputFile": "/mnt/source_videos/seriesA/episode_01.mov",
           "preset": "uuid-of-webm-720p-preset",
           "priority": 20
         },
         {
           "name": "Convert Episode 2 to WebM",
           "inputFile": "/mnt/source_videos/seriesA/episode_02.mov",
           "preset": "uuid-of-webm-720p-preset",
           "priority": 20
         },
         {
           "name": "Extract Thumbnail for Promo Image",
           "command": "-i ${INPUT_FILE} -frames:v 1 -q:v 2 ${OUTPUT_FILE}",
           "inputFile": "/mnt/source_videos/seriesA/promo_material.mp4",
           "outputFile": "/mnt/output_images/promo_thumb.jpg",
           "priority": 50
         }
       ]
     }'

The server will respond with a JSON object containing the unique uuid of the batch and a tasks array with the full details of each newly created task.

json
{
"uuid": "c4e8f12a-3b7d-4c9f-a1e8-5d0f2b3c4a9e",
"tasks": [
  {
    "uuid": "task-uuid-1",
    "batch": "c4e8f12a-3b7d-4c9f-a1e8-5d0f2b3c4a9e",
    "name": "Convert Episode 1 to WebM",
    "status": "QUEUED",
    // ... other task details
  },
  {
    "uuid": "task-uuid-2",
    "batch": "c4e8f12a-3b7d-4c9f-a1e8-5d0f2b3c4a9e",
    "name": "Convert Episode 2 to WebM",
    "status": "QUEUED",
    // ... other task details
  }
]
}

A batch.created event is fired when the batch is submitted, and a batch.finished event is fired once the last task in the batch is complete. See batch webhook events

Managing and Monitoring Batches ​

While FFmate treats each task in a batch individually for processing, the batch ID allows you to group and monitor them as a unit.

Listing Tasks by Batch ID

You can retrieve all tasks that belong to a specific batch by sending a GET request with the batch's uuid.

sh
curl -X GET 'http://localhost:3000/api/v1/batches/{batch_uuid}?page=0&perPage=10'

FFmate returns a JSON object containing the batch uuid and a paginated tasks array. The X-Total response header provides the total number of tasks in the batch.

Query Parameters:

  • page [optional] – Specifies which page of results to retrieve. Default: 0.
  • perPage [optional] – Defines how many tasks should be included in each page. Default: 100.

💡 Webhook Notifications for Batches

Webhooks Aren’t Just for single Tasks — Use Them to Track Batches Too

  • batch.created – Triggered once when a batch of tasks is successfully submitted. The payload includes an array of the created task objects.

  • batch.finished – Triggered when all tasks in the batch have finished processing (either successfully, with errors, or canceled).

    The payload is the task that finished last, not a summary of the batch. To get the final status of every task, call GET /api/v1/batches/{batch_uuid} with the batch value from that task.

Common Use Cases for Batch Submission ​

  • Bulk Transcoding – Convert an entire folder of videos to a new format or resolution in one go.

  • Multi-Renditions – Generate multiple versions of the same source file (e.g., different bitrates or resolutions). Each rendition is submitted as an individual task within the batch.

  • Sequential Asset Processing – Submit tasks that represent different steps in a media pipeline (e.g., clean audio, transcode video, apply watermark). While FFmate handles each task independently based on queue rules, you can still track them together as part of a single batch. While FFmate processes them based on queue rules, you can monitor them as a batch.