Quickstart

Base URL https://quantumplations.ai/api/v1. Everything speaks JSON, your plan decides what you may order, and your key is the only credential.

1

Mint a key

In your account settings, under API keys. It's shown once, so keep it on a server: a secret key in a browser is a leaked key.

2

Order a video

Only prompt is required.

curl -X POST https://quantumplations.ai/api/v1/videos \
  -H "Authorization: Bearer $QP_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"prompt": "Explain how a Kalman filter works.", "duration_seconds": 60}'

You get 202 and a render:

{
  "id": "425e4bbe-5d63-4343-b0ad-8d90dc5805b4",
  "status": "queued",
  "duration_seconds": 60,
  "videos_left": null,
  "video": null
}

The Idempotency-Key is optional but worth sending. If the reply never reaches you, repeating the call with the same key hands back the render you already bought instead of ordering a second one.

3

Collect it

Poll the render, or give callback_url on step 2 and let a webhook tell you.

curl https://quantumplations.ai/api/v1/videos/$RENDER_ID \
  -H "Authorization: Bearer $QP_API_KEY"

status runs queued to processing to one of succeeded, failed or canceled. On success video arrives on a paid plan, and its URLs are signed and expire in an hour, so fetch rather than store them. On the free plan there is nothing to fetch: video stays null, download_locked comes back true, and the video is watched signed in on the site.

"video": {
  "url": "https://…/425e4bbe….mp4?token=…",
  "poster_url": "https://…/425e4bbe….jpg?token=…",
  "duration_seconds": 59.8,
  "expires_in": 3600
}

Endpoints

MethodPathWhat it does
POST/videosOrder a video, under your plan's length, concurrency and allowance limits.
GET/videos/{id}One render, with signed URLs once it's done on a paid plan.
GET/videosYour renders, newest first. ?limit= 1–100, ?before= a timestamp.
DELETE/videos/{id}Cancel one that hasn't started. A free video it took comes back.
GET/optionsEvery voice, language and look you can ask for, and your plan's limits.
GET/creditsYour plan and what is left on it.

Render options

Everything but prompt has a default. Anything else you send is ignored.

FieldDefaultAccepts
prompt required–Up to 8,000 characters.
duration_seconds120A whole number, 10 to 1800, and no longer than your plan allows.
lookwhiteboardwhiteboard, technical, sketch.
voiceFinnA voice id from /options, or "none" for a silent video.
languageen74 languages, listed in /options.
scopestandardstandard, or socratic for a two-voice dialogue.
student_voiceJanetWho plays the student in a socratic dialogue. A voice id from /options, never the same as voice. Ignored on a standard video.
formalityneutralcasual, neutral or formal. How the narrator talks. Never changes the length. Set for you on a plan without fine-tuning (see Plans).
focusbalancedtight, balanced or exploratory. How far the video may range from the question. Set for you on a plan without fine-tuning (see Plans).
captionsfalseBurns the narration into the frames. Not with "none".
personalizedtrueShapes the video around your saved profile: how you learn, what you already know, and your first name. Send false when the video is for someone else.
aspect_ratio16:916:9 or 9:16.
callback_urlnullAn https URL on a public host.

Errors

Every failure is {"error": "<code>", "message": "…"} with a matching status.

CodeHTTPWhen
auth_required401No key.
invalid_api_key401The key isn't ours, or it's been revoked.
free_videos_used402The free videos on this account are gone. Subscribe for unlimited.
duration_over_plan400Longer than your plan allows. The plan's ceiling is in /options.
too_many_in_flight429This account has as many videos open as your plan allows. One waiting on your answers counts as open, so answer it or wait for a video to finish.
forbidden403A browser tried to use a key.
invalid_request400A field is missing or out of range. The message names it.
render_not_found404No render with that id on your account.
render_not_cancelable409It already started, or it started once and is queued for another try.
rate_limited429Past 60 calls a minute on one key, or 240 from one address. Carries Retry-After.
upstream_error502Our side. Safe to repeat everywhere except POST /videos, which is what Idempotency-Key is for.

Webhooks

Give callback_url and we post once, when the render settles: { event, id, status, error, completed_at }, with X-Quantumplations-Signature: t=<unix>,v1=<hex>. There's no retry, so keep polling as your fallback.

The signature is an HMAC-SHA256 of "<t>.<raw body>" keyed with the webhook secret shown beside your key. Verify against the raw bytes, before parsing:

import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyWebhook(rawBody, header, secret,
                              nowS = Math.floor(Date.now() / 1000)) {
  const parts = Object.fromEntries(String(header || '').split(',').map((p) => {
    const i = p.indexOf('=');
    return i < 0 ? ['', ''] : [p.slice(0, i).trim(), p.slice(i + 1).trim()];
  }));

  // Reject a replay of anything older than five minutes.
  const t = Number(parts.t);
  if (!/^[0-9]+$/.test(parts.t || '') || Math.abs(nowS - t) > 300) return false;

  const expected = createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest();
  const given = Buffer.from(String(parts.v1 || ''), 'hex');
  // timingSafeEqual throws on a length mismatch, so check length first.
  return given.length === expected.length && timingSafeEqual(given, expected);
}

Answer with a 2xx quickly. Nothing you return is read.

Use it from an agent

There's an MCP server at https://quantumplations.ai/api/mcp, so any agent or editor that speaks MCP can order a video without leaving the conversation. It's the same API and the same key.

{
  "mcpServers": {
    "quantumplations": {
      "type": "http",
      "url": "https://quantumplations.ai/api/mcp",
      "headers": { "Authorization": "Bearer qp_live_…" }
    }
  }
}

Five tools: generate_video, answer_questions, get_video, list_videos and get_credits. The one worth knowing about is answer_questions: the agent making your video stops and asks when a brief is ambiguous, and get_video reports awaiting_answers with the questions and how long is left to answer. Only generate_video makes a video, and it's annotated so your client asks before it does. There's deliberately no cancel tool: an agent that can cancel renders it didn't order is a footgun, and cancelling stays on the REST surface where a person presses the button.

A key in an MCP config is still a secret key. It sits on the machine running the client, which is a server-side place, but treat the config file the way you'd treat any file holding a credential.

API keys

Keys belong to your Quantumplations account and carry your plan and your beta access. Mint one per application, so you can revoke or roll one without breaking the rest. Twenty live keys is the ceiling.

Managed in your account

Minting, rolling and revoking live behind your sign-in, not on this page: open Create, click your account, and choose API keys. A key is shown once, at mint, and never again; we store a hash, not the key.

Open your API keys

Revoking is immediate and can't be undone. Renders already queued with that key still finish, and their webhooks still arrive.

Plans

An API key orders under the same plan as the website, and the plan decides four things: how long a video may run, how many renders you may have going at once, on the free plan how many videos you get in total, and which of the render options above you may set at all. GET /options publishes those limits for the key that calls it, and GET /credits reports what is left. A video longer than the plan allows is refused with duration_over_plan before anything is queued, so nothing is half-ordered. On the free and starter plans, tone, focus, web images and clarifying questions are set for you, and so is personalizing; on the free plan captions are set for you too. An order that sends one of them is accepted all the same and the video is made with the standard value, so read plan.locked from GET /options, which names them, before you rely on one. The free plan gives three videos in total; a render that fails or is cancelled puts its video back. Downloading the finished video, its transcript and its subtitles is part of the paid plans; a free key renders and reports progress, and answers download_locked: true with no file. See the plans.