Rendley docs

API access

An MCP client is the easiest way to use Rendley, but you do not need one. The same agent is available over plain HTTP, so you can drive it from a script, a backend job, or a workflow. You start a job, get an id back, and poll until the video is ready.

Every request authenticates with a Rendley API key as a bearer token. The Bearer prefix is required. See Get an API key for how to create and copy one.

Start a job

POST https://mcp.rendley.com/v1/agent

Send a prompt, and optionally a project to edit and files to bring in. It returns a job_id right away.

curl -X POST https://mcp.rendley.com/v1/agent \
-H "Authorization: Bearer YOUR_RENDLEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "prompt": "Edit this interview into a 3-minute reel with captions and music.",
  "files": [{ "url": "https://cdn.example.com/interview.mp4" }]
}'
const res = await fetch("https://mcp.rendley.com/v1/agent", {
method: "POST",
headers: {
  Authorization: "Bearer YOUR_RENDLEY_API_KEY",
  "Content-Type": "application/json",
},
body: JSON.stringify({
  prompt: "Edit this interview into a 3-minute reel with captions and music.",
  files: [{ url: "https://cdn.example.com/interview.mp4" }],
}),
});
const { job_id } = await res.json();
import requests

res = requests.post(
  "https://mcp.rendley.com/v1/agent",
  headers={"Authorization": "Bearer YOUR_RENDLEY_API_KEY"},
  json={
      "prompt": "Edit this interview into a 3-minute reel with captions and music.",
      "files": [{"url": "https://cdn.example.com/interview.mp4"}],
  },
)
job_id = res.json()["job_id"]

Body fields:

FieldTypeNotes
promptstring, requiredWhat you want done, in plain language.
project_idstring, optionalEdit an existing project. A new one is created when omitted.
filesarray, optionalMedia to bring in, each { url } pointing at a public https file.
thread_idstring, optionalContinue a previous job’s conversation.

The response gives you the job to poll:

{
  "job_id": "job_8f2c...",
  "status": "pending",
  "project_id": "prj_...",
  "thread_id": "thr_..."
}

Poll the job

GET https://mcp.rendley.com/v1/jobs/{job_id}

Fetch the job every few seconds until status is completed or failed.

curl https://mcp.rendley.com/v1/jobs/job_8f2c... \
-H "Authorization: Bearer YOUR_RENDLEY_API_KEY"
async function waitForJob(jobId, apiKey) {
while (true) {
  const res = await fetch(`https://mcp.rendley.com/v1/jobs/${jobId}`, {
    headers: { Authorization: `Bearer ${apiKey}` },
  });
  const job = await res.json();
  if (job.status === "completed" || job.status === "failed") return job;
  await new Promise((r) => setTimeout(r, 3000));
}
}
import time, requests

def wait_for_job(job_id, api_key):
  while True:
      res = requests.get(
          f"https://mcp.rendley.com/v1/jobs/{job_id}",
          headers={"Authorization": f"Bearer {api_key}"},
      )
      job = res.json()
      if job["status"] in ("completed", "failed"):
          return job
      time.sleep(3)

A completed job carries the project link:

{
  "job_id": "job_8f2c...",
  "status": "completed",
  "result": {
    "project_id": "prj_...",
    "project_url": "https://app.rendley.com/...",
    "thread_id": "thr_..."
  },
  "error": null
}

To get a downloadable file, export the project. From an MCP client, ask it to export. From your own backend, hit the Rendley API’s export endpoint. See Render a video for the full flow. Or open the project_url and export from the editor.

Good to know

  • Jobs run asynchronously. The first call returns in well under a second; the render happens while you poll.
  • A finished job is kept for about an hour, then evicted. Save the project_url when the job completes.
  • If the queue is busy you may get 429. Respect the Retry-After header and try again.

For interactive use inside an AI client instead, connect Claude, Codex, or another client.