Reference · Processing

# POST/ffmpeg/process

Runs one task and answers when it has finished. For a job that may take more than a couple of minutes, use [POST /ffmpeg/process/async](https://media.logicboostkit.com/docs/post-ffmpeg-process-async). It answers at once, and its `job_id` is the request id.

## Request body

Request body

- `task` (object): Required. What to run.
- `task.inputs[]` (array): Required. The files to read, in order: 1 to 100. Each input is one file.
- `inputs[].file_path` (string): Required. dir_id/file_name of an uploaded file, or a public HTTPS URL. Uploaded inputs must all be in one directory.
- `inputs[].options[]` (string[]): FFmpeg options placed before this input.
- `task.outputs[]` (array): Required. The files to write: 1 to 50.
- `outputs[].file` (string): Required. The output’s file name. It must differ from every input’s name and from the other outputs. A numbered pattern such as `frame_%03d.png` returns every file it produces.
- `outputs[].options[]` (string[]): FFmpeg options for this output.
- `outputs[].maps[]` (string[]): Streams to map into this output, each passed as `-map`.
- `task.filter_complex` (string): A filter graph across the inputs.
- `task.output_dir_id` (string): Where the outputs go. By default the inputs’ directory, or a new one when every input is a URL.

Some options and filters are refused; see [Options and filters we refuse](https://media.logicboostkit.com/docs/refused-options). A URL input is fetched into the outputs’ directory before the task runs, and stays there until the directory expires.

## Example

Request

```bash
curl https://media.logicboostkit.com/ffmpeg/process \
  -H "Authorization: Basic $MEDIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "task": {
      "inputs": [{ "file_path": "dir_pi23jgy1yxlmigi873bz/source.mp4" }],
      "outputs": [{
        "file": "thumb.jpg",
        "options": ["-ss", "5", "-vframes", "1"]
      }]
    }
  }'
```

Response

```http
HTTP/1.1 200 OK
X-Request-Id: job_0mv6hqvpqkiwproi518azpod

{
  "ok": true,
  "result": [
    {
      "file_name": "thumb.jpg",
      "size_bytes": 84213,
      "download_url": "https://…"
    }
  ],
  "usage": {
    "time_sec": 0.62,
    "input_size_gb": 1.804199982,
    "output_size_gb": 0.000078429,
    "gb_sec": 1.118652615
  },
  "request_id": "job_0mv6hqvpqkiwproi518azpod",
  "amount_usd": 0.014900453
}
```

## Response fields

Response fields

- `ok` (boolean): true when the task finished.
- `result[]` (array): One entry per output file: file_name, size_bytes and download_url. A download_url works for 1 hour.
- `usage.time_sec` (number): Processing seconds, measured on the reference machine.
- `usage.input_size_gb` (number): Total size of the inputs.
- `usage.output_size_gb` (number): Total size of the outputs.
- `usage.gb_sec` (number): What the request is charged on.
- `request_id` (string): The request’s id, also sent as the X-Request-Id header.
- `amount_usd` (number): What the request was charged, in USD.

Only the files named in outputs[], or produced by a numbered pattern, are returned. Files a muxer writes beside them, such as the segments of a playlist, are not.

## Status codes

Status codes

- **200**: The task finished. Charged.
- **400**: The body or the task is malformed, a name breaks the naming rules, an option or filter is refused, an input is a playlist or manifest, or a URL input could not be fetched.
- **401**: The `Authorization` header is missing, or the key is invalid, revoked or expired.
- **403**: The account isn’t active, or a file is over 5 GB. The error says what to do.
- **404**: `Directory not found` or `File not found in directory`: an input or the output directory isn’t in your account, or has expired.
- **429**: More than 300 requests in a minute on this key, or 50 of the account’s jobs already in progress. Wait for the number of seconds in `Retry-After`.
- **500**: FFmpeg failed, or the job ran longer than 60 min. The error carries FFmpeg’s last message. Not charged.
- **503**: Too busy to start the job now. Retry after the seconds in Retry-After, or use the async endpoint, which queues it.

Every error has the shape `{"ok": false, "error": "…"}` and is never charged.

## Guides

Guides that use this endpoint

- **[Convert video to MP4](https://media.logicboostkit.com/docs/convert-video-to-mp4)**: MOV, MKV, AVI or WebM to an MP4 that plays everywhere.
- **[Compress a video](https://media.logicboostkit.com/docs/compress-video)**: A smaller file, at a quality you choose.
- **[Trim a video](https://media.logicboostkit.com/docs/trim-video)**: A clip from a start time and a length.
- **[Extract audio as MP3](https://media.logicboostkit.com/docs/extract-audio-mp3)**: The soundtrack of a video, as an MP3.
- **[Make a video thumbnail](https://media.logicboostkit.com/docs/video-thumbnail)**: A JPEG from any moment of a video.
- **[Convert video to GIF](https://media.logicboostkit.com/docs/video-to-gif)**: An animated GIF from part of a video.
- **[Burn subtitles into a video](https://media.logicboostkit.com/docs/burn-subtitles)**: An SRT, VTT or ASS file drawn onto the picture.
- **[Add a watermark to a video](https://media.logicboostkit.com/docs/watermark-video)**: A logo in a corner of a video.
- **[Resize a video](https://media.logicboostkit.com/docs/resize-video)**: 720p or any other size, proportions kept.
