RenderIO
Concepts

Command Types

RenderIO supports three command types - single, chained, and multiple - for different FFmpeg processing workflows.

Command Types

RenderIO supports three types of commands, each suited to different processing workflows.

Single command

A single FFmpeg command that runs once. This is the most common type.

  • Type: FFMPEG_COMMAND
  • Endpoint: POST /api/v1/run-ffmpeg-command
  • Field: ffmpeg_command (string)
  • Returns: { "command_id": "..." }

Use this when you need to perform one FFmpeg operation, such as converting a format, resizing a video, or extracting audio.

curl -X POST https://renderio.dev/api/v1/run-ffmpeg-command \
  -H "X-API-KEY: ffsk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input_files": {
      "in_video": "https://example.com/video.mov"
    },
    "output_files": {
      "out_video": "converted.mp4"
    },
    "ffmpeg_command": "-i {{in_video}} -c:v libx264 -c:a aac {{out_video}}"
  }'
const response = await fetch("https://renderio.dev/api/v1/run-ffmpeg-command", {
  method: "POST",
  headers: {
    "X-API-KEY": "ffsk_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input_files: {
      in_video: "https://example.com/video.mov",
    },
    output_files: {
      out_video: "converted.mp4",
    },
    ffmpeg_command: "-i {{in_video}} -c:v libx264 -c:a aac {{out_video}}",
  }),
});

const { command_id } = await response.json();
import requests

response = requests.post(
    "https://renderio.dev/api/v1/run-ffmpeg-command",
    headers={"X-API-KEY": "ffsk_your_api_key"},
    json={
        "input_files": {
            "in_video": "https://example.com/video.mov"
        },
        "output_files": {
            "out_video": "converted.mp4"
        },
        "ffmpeg_command": "-i {{in_video}} -c:v libx264 -c:a aac {{out_video}}"
    }
)

command_id = response.json()["command_id"]

Chained commands

Multiple FFmpeg commands that run sequentially in the same sandbox. The output of one step can be used as input to the next.

  • Type: CHAINED_COMMAND
  • Endpoint: POST /api/v1/run-chained-ffmpeg-commands
  • Field: ffmpeg_commands (array of strings, max 10)
  • Returns: { "command_id": "..." } (single ID for the whole chain)

Use this when your workflow requires multiple FFmpeg passes, such as transcoding followed by thumbnail extraction, or applying filters in stages.

curl -X POST https://renderio.dev/api/v1/run-chained-ffmpeg-commands \
  -H "X-API-KEY: ffsk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input_files": {
      "in_video": "https://example.com/raw-footage.mov"
    },
    "output_files": {
      "out_video": "compressed.mp4",
      "out_thumb": "thumbnail.jpg"
    },
    "ffmpeg_commands": [
      "-i {{in_video}} -c:v libx264 -crf 28 -c:a aac {{out_video}}",
      "-i {{out_video}} -ss 00:00:02 -vframes 1 {{out_thumb}}"
    ]
  }'
const response = await fetch("https://renderio.dev/api/v1/run-chained-ffmpeg-commands", {
  method: "POST",
  headers: {
    "X-API-KEY": "ffsk_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input_files: {
      in_video: "https://example.com/raw-footage.mov",
    },
    output_files: {
      out_video: "compressed.mp4",
      out_thumb: "thumbnail.jpg",
    },
    ffmpeg_commands: [
      "-i {{in_video}} -c:v libx264 -crf 28 -c:a aac {{out_video}}",
      "-i {{out_video}} -ss 00:00:02 -vframes 1 {{out_thumb}}",
    ],
  }),
});

const { command_id } = await response.json();
import requests

response = requests.post(
    "https://renderio.dev/api/v1/run-chained-ffmpeg-commands",
    headers={"X-API-KEY": "ffsk_your_api_key"},
    json={
        "input_files": {
            "in_video": "https://example.com/raw-footage.mov"
        },
        "output_files": {
            "out_video": "compressed.mp4",
            "out_thumb": "thumbnail.jpg"
        },
        "ffmpeg_commands": [
            "-i {{in_video}} -c:v libx264 -crf 28 -c:a aac {{out_video}}",
            "-i {{out_video}} -ss 00:00:02 -vframes 1 {{out_thumb}}"
        ]
    }
)

command_id = response.json()["command_id"]

Notice how {{out_video}} from the first command is used as input in the second command. All commands share the same sandbox filesystem, so intermediate outputs are available to subsequent steps.

Multiple commands

Multiple independent commands that run in parallel. Each command gets its own sandbox and its own command_id.

  • Type: MULTIPLE_COMMAND
  • Endpoint: POST /api/v1/run-multiple-ffmpeg-commands
  • Field: commands (array of single command requests, max 10)
  • Returns: { "command_ids": ["...", "..."] }

Use this when you need to process several files independently at the same time, such as generating multiple renditions of different source videos.

curl -X POST https://renderio.dev/api/v1/run-multiple-ffmpeg-commands \
  -H "X-API-KEY: ffsk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "commands": [
      {
        "input_files": { "in_video": "https://example.com/video1.mov" },
        "output_files": { "out_video": "video1.mp4" },
        "ffmpeg_command": "-i {{in_video}} -c:v libx264 {{out_video}}"
      },
      {
        "input_files": { "in_video": "https://example.com/video2.mov" },
        "output_files": { "out_video": "video2.mp4" },
        "ffmpeg_command": "-i {{in_video}} -c:v libx264 {{out_video}}"
      }
    ]
  }'
const response = await fetch("https://renderio.dev/api/v1/run-multiple-ffmpeg-commands", {
  method: "POST",
  headers: {
    "X-API-KEY": "ffsk_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    commands: [
      {
        input_files: { in_video: "https://example.com/video1.mov" },
        output_files: { out_video: "video1.mp4" },
        ffmpeg_command: "-i {{in_video}} -c:v libx264 {{out_video}}",
      },
      {
        input_files: { in_video: "https://example.com/video2.mov" },
        output_files: { out_video: "video2.mp4" },
        ffmpeg_command: "-i {{in_video}} -c:v libx264 {{out_video}}",
      },
    ],
  }),
});

const { command_ids } = await response.json();
// command_ids = ["id-1", "id-2"]
import requests

response = requests.post(
    "https://renderio.dev/api/v1/run-multiple-ffmpeg-commands",
    headers={"X-API-KEY": "ffsk_your_api_key"},
    json={
        "commands": [
            {
                "input_files": {"in_video": "https://example.com/video1.mov"},
                "output_files": {"out_video": "video1.mp4"},
                "ffmpeg_command": "-i {{in_video}} -c:v libx264 {{out_video}}"
            },
            {
                "input_files": {"in_video": "https://example.com/video2.mov"},
                "output_files": {"out_video": "video2.mp4"},
                "ffmpeg_command": "-i {{in_video}} -c:v libx264 {{out_video}}"
            }
        ]
    }
)

command_ids = response.json()["command_ids"]

Each command in the array is validated independently and runs in its own isolated sandbox. You poll each command_id separately.

When to use which type

ScenarioCommand typeWhy
Convert a video to MP4SingleOne operation, one output
Transcode then extract thumbnailChainedSecond step depends on first step's output
Apply a two-pass encodeChainedSecond pass needs data from the first
Process a batch of user uploadsMultipleEach file is independent
Generate 720p and 1080p renditions of different videosMultipleNo dependencies between commands
Merge two videos then add watermarkChainedSequential operations on related files

Limits

  • Chained commands: Maximum of 10 commands in the ffmpeg_commands array
  • Multiple commands: Maximum of 10 commands in the commands array
  • Timeout: Command timeout is determined by your subscription plan

On this page