Code examples
Copy-paste snippets in curl, JavaScript and Python.
JavaScript / TypeScript
const res = await fetch("https://reeloop.ai/api/v1/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.REELOOP_API_KEY}`,
"Content-Type": "application/json",
// Optional but recommended: safe retries without double-charging.
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
topic: "3 psychology tricks that make videos go viral",
style: "viral-story",
voice: "charlotte",
language: "en",
// "instant" starts the render right away.
// Omit it to create a free Director Mode draft instead (see below).
mode: "instant",
}),
});
const { jobId } = await res.json();Python
import os, requestsr = requests.post( "https://reeloop.ai/api/v1/generate", headers={"Authorization": f"Bearer {os.environ['REELOOP_API_KEY']}"}, json={ "topic": "3 psychology tricks that make videos go viral", "style": "viral-story", "voice": "charlotte", "language": "en", # "instant" starts the render right away. # Omit it to create a free Director Mode draft instead (see below). "mode": "instant", }, ) job_id = r.json()["jobId"] ```
Create a free Director Mode draft
Pass "mode": "director" (or simply omit mode). No credits are charged: you get the script, scene prompts and the exact credit quote, and the job waits at status: "awaiting_approval" until you approve it.
const res = await fetch("https://reeloop.ai/api/v1/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.REELOOP_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
topic: "5 facts about the ocean nobody knows",
style: "documentary",
voice: "charlotte",
language: "en",
"mode": "director", // free draft; omitting "mode" does the same
}),
});
const { jobId } = await res.json();
// GET /api/v1/status/{jobId} -> review the script, scenes and credit quote
// POST /api/v1/jobs/{jobId}/approve -> charge the quote and start the renderPoll for completion
Watch renderStatus, not status. A job whose assembly failed keeps status: "completed" (scenes finished, credits refunded) - only renderStatus tells you whether a video file exists.
async function waitForVideo(jobId: string) {
for (;;) {
const r = await fetch(`https://reeloop.ai/api/v1/status/${jobId}`, {
headers: { Authorization: `Bearer ${process.env.REELOOP_API_KEY}` },
});
const job = await r.json();
if (job.renderStatus === "done" && job.finalVideoUrl) {
return job.finalVideoUrl;
}
if (job.renderStatus === "failed") {
// Credits were refunded automatically - safe to retry.
throw new Error("render failed");
}
await new Promise((s) => setTimeout(s, 5000));
}
}