Apex27 Developer Services
Private API
Render service · API reference

FFmpeg rendering,
without the ceremony.

Submit a validated FFmpeg task, poll its job status, then retrieve the finished MP4 from a short-lived signed URL.

Base URLhttps://ffmpeg.apex27.co.uk

Overview

The renderer is asynchronous. A successful submission returns immediately with a job ID while a background worker downloads the approved inputs and renders the video.

1

Submit

POST a validated task and retain the returned job ID.

2

Poll

GET job status every five seconds until it completes or fails.

3

Download

Use the signed URL returned in the completed result.

Authentication

Every API endpoint except signed downloads requires the service key in the Authorization header. Both Basic and Bearer prefixes are accepted.

Authorization: Basic YOUR_API_KEY
Content-Type: application/json
Keep the key server-side. Do not expose it in browser JavaScript or commit it to a repository. n8n credentials or environment variables are appropriate.

Submit a render

POST/submit.php

The body contains one task with 2–40 HTTPS inputs, a filter graph, and exactly one MP4 output.

curl -X POST "https://ffmpeg.apex27.co.uk/submit.php" \
  -H "Authorization: Basic YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "task": {
      "inputs": [
        {
          "file_path": "https://fs-06.apex27.co.uk/example/photo.jpg",
          "options": ["-loop", "1", "-framerate", "30", "-t", "3"]
        },
        {
          "file_path": "https://forms.apex27.co.uk/music/1.mp3",
          "options": ["-stream_loop", "-1"]
        }
      ],
      "filter_complex": "[0:v]scale=1080:1920,fps=30,format=yuv420p[video];[1:a]atrim=duration=3,volume=0.18[audio]",
      "outputs": [{
        "file": "property-preview.mp4",
        "maps": ["[video]", "[audio]"],
        "options": [
          "-c:v", "libx264", "-preset", "fast",
          "-crf", "20", "-c:a", "aac", "-b:a", "192k",
          "-pix_fmt", "yuv420p", "-movflags", "+faststart", "-shortest"
        ]
      }]
    }
  }'

Accepted response · HTTP 202

{
  "ok": true,
  "job_id": "f4d85a9d99ea40b8aa835c621843ed83",
  "status": "pending"
}
FieldTypeDescription
task.inputs requiredarrayDirect HTTPS media URLs with optional allow-listed input options.
task.filter_complex requiredstringThe FFmpeg filter graph. File-reading filters are rejected.
task.outputs requiredarrayExactly one output definition with a safe .mp4 name, maps and approved encoding options.

Check job status

GET/status.php?job_id={job_id}
curl "https://ffmpeg.apex27.co.uk/status.php?job_id=JOB_ID" \
  -H "Authorization: Basic YOUR_API_KEY"
pending

Waiting

The task is queued for a worker.

processing

Rendering

Inputs are downloading or FFmpeg is running.

completed

Ready

The response contains the result and usage metadata.

failed

Stopped

The response contains a concise error message.

Completed response

{
  "ok": true,
  "job_id": "f4d85a9d99ea40b8aa835c621843ed83",
  "status": "completed",
  "result": [{
    "size_bytes": 18439220,
    "download_url": "https://ffmpeg.apex27.co.uk/download.php?...",
    "file_name": "property-preview.mp4"
  }],
  "usage": {
    "time_sec": 72.14,
    "input_size_gb": 0.0124,
    "output_size_gb": 0.0172,
    "gb_sec": 2.135
  }
}

Health check

GET/health.php

Returns runtime readiness, PHP version, FFmpeg availability, active jobs, and the configured parallel-job limit.

curl "https://ffmpeg.apex27.co.uk/health.php" \
  -H "Authorization: Basic YOUR_API_KEY"

Signed downloads

A completed job includes a signed download_url. It needs no Authorization header and supports byte ranges, so browsers can seek within the video.

Link lifetime

Signed URLs expire after approximately six hours.

File retention

Completed jobs and their media are retained for 48 hours.

If Apex27 must permanently retain a video, copy it from the signed URL before either window expires.

Validation and limits

AreaLimit
Parallel renders2
Inputs per task2–40
Maximum downloaded input750 MB per input
Filter graph200,000 characters; file-reading filters are blocked
OutputOne safe .mp4 filename
Input protocolsDirect HTTPS URLs only
Input hostsAny public internet host. Private, loopback, link-local, and reserved network addresses are blocked.
Input options-loop 1, -stream_loop -1, -framerate 1…60, -t 0.1…3600
EncodingH.264 via libx264, CRF 18–22; AAC at 128, 192, or 256 kbps

Errors

HTTPMeaningAction
400Invalid JSON, task, URL, filter, or FFmpeg option.Correct the request; do not retry unchanged.
401Missing or invalid API key.Check the Authorization header.
404Unknown job or expired/missing download.Verify the ID or submit a new render.
405Wrong HTTP method.Use POST for submit and GET for status/health.
429Both render slots are occupied.Wait briefly, then retry with backoff.
500Internal service or render failure.Inspect the error and retry only if transient.
{
  "ok": false,
  "error": "Renderer is busy; please retry shortly"
}

Using the API from n8n

Submit workflow

HTTP Request · POST
https://ffmpeg.apex27.co.uk/submit.php
JSON body: {{ $json.ffmpegRequest }}

Status workflow

HTTP Request · GET
https://ffmpeg.apex27.co.uk/status.php
Query: job_id={{ $json.query.job_id }}

Add Authorization: Basic YOUR_API_KEY using an n8n credential. Poll about every five seconds and stop when the status is completed or failed.