Reeltopus

Reeltopus API and MCP server

The Reeltopus REST API and MCP server: turn long videos into ranked, captioned 9:16 clips, export MP4s, caption files and editor timelines, and post them, from code, automations or AI agents.

Quickstart

Create an API key under Settings → API, then go from a long video to export links in five calls. Base URL: https://reeltopus.com/api/v1.

# 1. Start a project from a YouTube link (hours are held for its length)
curl -X POST https://reeltopus.com/api/v1/projects \
  -H "Authorization: Bearer $REELTOPUS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"url": "https://www.youtube.com/watch?v=VIDEO_ID", "rightsConfirmed": true}'

# 2. Poll until "status": "ready" (or subscribe to the project.ready webhook)
curl https://reeltopus.com/api/v1/projects/PROJECT_ID -H "Authorization: Bearer $REELTOPUS_API_KEY"

# 3. Ranked clips, best first
curl https://reeltopus.com/api/v1/projects/PROJECT_ID/clips -H "Authorization: Bearer $REELTOPUS_API_KEY"

# 4. Optional edits: style, trim, silence removal
curl -X PATCH https://reeltopus.com/api/v1/clips/CLIP_ID \
  -H "Authorization: Bearer $REELTOPUS_API_KEY" -H "Content-Type: application/json" \
  -d '{"captionStyle": "karaoke", "removeSilences": true}'

# 5. Export, then fetch the links once "status": "ready"
curl -X POST https://reeltopus.com/api/v1/clips/CLIP_ID/export \
  -H "Authorization: Bearer $REELTOPUS_API_KEY" -H "Content-Type: application/json" \
  -d '{"resolution": "1080p"}'
curl https://reeltopus.com/api/v1/clips/CLIP_ID/export -H "Authorization: Bearer $REELTOPUS_API_KEY"

Processing spends your workspace's hours exactly like an upload in the app: the video's length is held when processing starts, charged on the transcribed length when it succeeds, and refunded in full if it fails. Archive mode costs half. Exports, caption files, editor timelines and posts are free.

Keys, limits, idempotency and errors

Uploading files

For files on your side, upload straight to storage in parts. durationMs is optional: Reeltopus measures the file when the upload completes and holds hours for its real length. Files up to 20 GB.

const api = (path, init = {}) =>
  fetch(`https://reeltopus.com/api/v1${path}`, {
    ...init,
    headers: { Authorization: `Bearer ${process.env.REELTOPUS_API_KEY}`, "Content-Type": "application/json", ...init.headers },
  }).then((r) => r.json());

const file = await fs.promises.readFile("episode.mp4");
const { project, upload } = await api("/uploads", {
  method: "POST",
  body: JSON.stringify({ filename: "episode.mp4", sizeBytes: file.length, mimeType: "video/mp4" }),
});

const parts = [];
for (const { partNumber, url } of upload.parts) {   // > 100 parts: POST /uploads/{id}/parts for the rest
  const chunk = file.subarray((partNumber - 1) * upload.partSize, partNumber * upload.partSize);
  const res = await fetch(url, { method: "PUT", body: chunk });
  parts.push({ partNumber, etag: res.headers.get("etag") });
}
await api(`/uploads/${project.id}/complete`, { method: "POST", body: JSON.stringify({ parts }) });

Video links: POST /projects takes YouTube links today, for videos you own or have the rights to (rightsConfirmed: true records that). For anything else, upload the file.

Webhooks

Add an endpoint under Settings → API or with POST /webhooks. Reeltopus POSTs a JSON event and expects any 2xx within 10 seconds; anything else is retried with backoff for about a day. Events:

Payloads look like { "id": "evt_…", "type": "project.ready", "createdAt": "…", "data": { "project": {…} } }, where data holds the same objects the API returns. The event id stays the same on retries, so use it to de-duplicate. Signatures follow Standard Webhooks:

import { Webhook } from "standardwebhooks"; // npm i standardwebhooks (Python, Go, Ruby… exist too)

const wh = new Webhook(process.env.REELTOPUS_WEBHOOK_SECRET.replace(/^whsec_/, ""));

export async function POST(request) {
  const body = await request.text();               // the raw body, before any JSON parsing
  const event = wh.verify(body, {
    "webhook-id": request.headers.get("webhook-id"),
    "webhook-timestamp": request.headers.get("webhook-timestamp"),
    "webhook-signature": request.headers.get("webhook-signature"),
  });                                               // throws if the signature or timestamp is wrong
  if (event.type === "clip.exported") console.log(event.data.export.files.mp4.url);
  return new Response(null, { status: 204 });
}

// Without a library: HMAC-SHA256 over `${id}.${timestamp}.${body}`, keyed with the
// base64-decoded secret (after whsec_), base64-encoded, compared to each "v1,<sig>"
// in webhook-signature. Reject timestamps more than 5 minutes off.

MCP server

Agents can drive the whole workflow through the remote MCP server at https://reeltopus.com/api/mcp (Streamable HTTP, stateless). It accepts two kinds of bearer token:

claude mcp add --transport http reeltopus https://reeltopus.com/api/mcp --header "Authorization: Bearer rt_live_…"

Cursor, the OpenAI Agents SDK, LangChain and most MCP clients take the URL and header in their config:

{
  "mcpServers": {
    "reeltopus": {
      "type": "http",
      "url": "https://reeltopus.com/api/mcp",
      "headers": {
        "Authorization": "Bearer rt_live_…"
      }
    }
  }
}

What the server tells the agent:

Reeltopus turns long videos into short vertical clips with captions, reframed for 9:16, and posts them.

Typical workflow:
1. get_account: check the hours left (processing a video spends its length in hours; exports and posts are free).
2. create_project_from_url with a YouTube link (or start_upload + complete_upload for a file you can upload over HTTP).
3. get_status every 30-60 seconds until status is "ready" (or "failed"; failed projects are refunded).
4. get_clips: clips ranked best first, with title, hook, score, transcript.
5. Optionally edit_clip (caption style, trim, silence removal, title, hook, word-level edits).
6. export_clip, then get_export until status is "ready": it returns the MP4 link. Caption files (SRT/VTT/ASS) and the editor timeline links work right away.
7. Optionally list_connections and schedule_post to publish to a connected account.

Rules: only import videos the user owns or has the rights to, and confirm with the user before posting anything publicly. Download links expire after an hour; call get_export again for fresh ones.

Tools:

Reference

Every operation below is in the OpenAPI 3.1 document with full request and response schemas, ready for code generators, Postman or an agent's tool loader.

GET/api/v1/me

Get the workspace, its hours and rate limits

POST/api/v1/uploads

Start a file upload

Creates a project and a multipart upload. PUT each part (partSize bytes; the last one smaller) to its presigned URL, keep each response's ETag header, then call complete. Presigned URLs last an hour.

POST/api/v1/uploads/{projectId}/parts

Get presigned URLs for more parts

POST/api/v1/uploads/{projectId}/complete

Finish an upload and start processing

Reeltopus measures the file, holds hours for its length (half in archive mode) and starts transcribing. Hours are settled on the transcript's length and refunded in full if processing fails, exactly as for uploads in the app.

GET/api/v1/projects

List projects, newest first

POST/api/v1/projects

Create a project from a video link

Checks the YouTube video (length, availability), holds hours for its length and queues the download, then processing. Only for videos the workspace owns or has the rights to; set rightsConfirmed to true.

GET/api/v1/projects/{projectId}

Get a project's status

GET/api/v1/projects/{projectId}/clips

List a project's clips, best first

GET/api/v1/clips/{clipId}

Get a clip

PATCH/api/v1/clips/{clipId}

Edit a clip

Fields become edit operations, applied before `edits`; the whole request is one undo step in the app. A finished export whose picture, sound or captions changed goes back to idle.

GET/api/v1/clips/{clipId}/export

Get a clip's export status and download links

POST/api/v1/clips/{clipId}/export

Export a clip as MP4

Free. Poll GET until status is ready (or subscribe to clip.exported). An export already under way is left alone.

GET/api/v1/caption-styles

List caption styles

GET/api/v1/connections

List connected social accounts

Accounts are connected by a person in the app (Connections), never through the API.

GET/api/v1/posts

List posts, newest first

POST/api/v1/posts

Post or schedule an exported clip

GET/api/v1/posts/{postId}

Get a post

DELETE/api/v1/posts/{postId}

Cancel a scheduled post

GET/api/v1/webhooks

List webhook endpoints

POST/api/v1/webhooks

Subscribe a URL to events

The response includes the signing secret, once. Up to 10 endpoints per workspace.

DELETE/api/v1/webhooks/{webhookId}

Delete a webhook endpoint

POST/api/v1/webhooks/{webhookId}/test

Send a test event now