API Documentation

Render demo videos programmatically via the Democut REST API. Available on the Scale plan.

Getting Started

Base URL

https://democut.dev/api

Authentication

All API requests require an Authorization header with your API key. Find your key in the dashboard under Settings → API.

Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxx

Rate Limits

PlanRenders/monthConcurrent renders
Free31
Pro503
ScaleUnlimited10

Rate limit headers: X-RateLimit-Remaining and X-RateLimit-Reset are included in all responses.

Endpoints

POST/api/render

Start a new video render. Returns immediately with a render ID that you can poll for status.

Request Body

FieldTypeRequiredDescription
template_idstringYesTemplate identifier (see templates below)
input_dataobjectYesTemplate-specific input data (see schema below)
webhook_urlstringNoURL to POST when render completes

Response

{
  "id": "rnd_a1b2c3d4e5f6",
  "status": "queued",
  "template_id": "app-showcase",
  "created_at": "2026-03-21T10:00:00Z"
}
GET/api/render/{id}

Check the status of a render job. Poll this endpoint until status is done or failed. Recommended poll interval: 2 seconds.

Response

{
  "id": "rnd_a1b2c3d4e5f6",
  "status": "done",
  "template_id": "app-showcase",
  "output_url": "https://democut.dev/renders/rnd_a1b2c3d4e5f6.mp4",
  "created_at": "2026-03-21T10:00:00Z",
  "completed_at": "2026-03-21T10:00:08Z"
}

Status values: queued · rendering · done · failed

GET/api/templates

List all available templates and their required input schemas.

Response

{
  "templates": [
    {
      "id": "app-showcase",
      "name": "App Showcase",
      "description": "Animated screenshots with feature callouts",
      "duration_seconds": 6
    },
    {
      "id": "feature-announcement",
      "name": "Feature Announcement",
      "description": "New feature reveal with motion graphics",
      "duration_seconds": 5
    },
    {
      "id": "onboarding-welcome",
      "name": "Onboarding Welcome",
      "description": "Personalized welcome video with user data",
      "duration_seconds": 4
    }
  ]
}

Template Input Schemas

App Showcase

ID: app-showcase · 6 seconds · 1080p

{
  "app_name": "string",          // Your app name (required)
  "tagline": "string",           // Short tagline (required)
  "features": ["string"],        // Up to 4 feature bullet points (required)
  "screenshot_url": "string",    // HTTPS URL to a screenshot image (required)
  "primary_color": "string"      // Hex color, e.g. "#4d6fff" (optional, default: #4d6fff)
}

Feature Announcement

ID: feature-announcement · 5 seconds · 1080p

{
  "app_name": "string",          // Your app name (required)
  "feature_name": "string",      // Name of the new feature (required)
  "feature_description": "string", // One-sentence description (required)
  "badge_text": "string",        // Badge label, e.g. "New" or "v2.0" (optional)
  "primary_color": "string"      // Hex color (optional, default: #4d6fff)
}

Onboarding Welcome

ID: onboarding-welcome · 4 seconds · 1080p

{
  "app_name": "string",          // Your app name (required)
  "user_name": "string",         // Recipient's first name (required)
  "welcome_message": "string",   // Custom welcome line (optional)
  "cta_text": "string",          // Call-to-action button label (optional, default: "Get started")
  "primary_color": "string"      // Hex color (optional, default: #4d6fff)
}

Code Examples

cURL

# Start a render
curl -X POST https://democut.dev/api/render \
  -H "Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "app-showcase",
    "input_data": {
      "app_name": "Acme CRM",
      "tagline": "Close deals faster.",
      "features": ["Pipeline management", "Email integration", "Analytics"],
      "screenshot_url": "https://example.com/screenshot.png"
    }
  }'

# Check status
curl https://democut.dev/api/render/rnd_a1b2c3d4e5f6 \
  -H "Authorization: Bearer dk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

JavaScript

const API_KEY = "dk_live_xxxxxxxxxxxxxxxxxxxxxxxx";
const BASE_URL = "https://democut.dev/api";

async function renderDemo(inputData) {
  // Start render
  const res = await fetch(`${BASE_URL}/render`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      template_id: "app-showcase",
      input_data: inputData,
    }),
  });
  const { id } = await res.json();

  // Poll for completion
  while (true) {
    await new Promise((r) => setTimeout(r, 2000));
    const status = await fetch(`${BASE_URL}/render/${id}`, {
      headers: { "Authorization": `Bearer ${API_KEY}` },
    }).then((r) => r.json());

    if (status.status === "done") return status.output_url;
    if (status.status === "failed") throw new Error("Render failed");
  }
}

const url = await renderDemo({
  app_name: "Acme CRM",
  tagline: "Close deals faster.",
  features: ["Pipeline management", "Email integration", "Analytics"],
  screenshot_url: "https://example.com/screenshot.png",
});
console.log("Download:", url);

Error Codes

StatusCodeDescription
400invalid_inputMissing or malformed request body
401unauthorizedMissing or invalid API key
403plan_requiredAPI access requires Scale plan
404not_foundRender ID not found or not owned by you
429rate_limitedMonthly render limit reached
500render_failedRender job failed — contact support

Need help?

Scale plan customers get dedicated support. For all other questions, reach out via email.

Contact support →