Developers

API reference

Everything the app does, over REST. Available on Scale and Enterprise.

The DemoRiff API is a REST interface over the whole pipeline: upload a recording, create a project, render outputs, manage locales and read analytics. Everything the app does, the API can do.

Base URL and authentication

All requests go to https://api.demoriff.com and authenticate with a workspace API key as a bearer token. Keys are created in workspace settings, scoped to a role, and rotatable without downtime.

bash
curl https://api.demoriff.com/v1/projects \
  -H "Authorization: Bearer $DEMORIFF_API_KEY"

Rate limits

1,000 requests per minute per workspace for read operations, 60 per minute for render creation. Limits are returned in X-RateLimit-* headers. Render jobs queue rather than fail when you exceed concurrency.

Idempotency

Pass an Idempotency-Key header on any POST. Replaying the same key within 24 hours returns the original response rather than creating a duplicate render.

Endpoints

POST/v1/recordingsCreate a recording and get a resumable upload URL.

REQUEST

{
  "filename": "shipment-walkthrough.mp4",
  "bytes": 482103448,
  "source": "upload",
  "masking_policy": "pol_production_safeguards"
}

RESPONSE

{
  "id": "rec_8f2c1a",
  "status": "awaiting_upload",
  "upload_url": "https://uploads.demoriff.com/…",
  "expires_at": "2026-09-20T18:00:00Z"
}
POST/v1/projectsCreate an editable project from one or more recordings.

REQUEST

{
  "recording_ids": ["rec_8f2c1a"],
  "name": "Create a shipment",
  "brand_kit": "kit_meridian_primary",
  "voice": "avery-warm-us",
  "auto_edit": true
}

RESPONSE

{
  "id": "prj_4b91de",
  "status": "processing",
  "transcript_ready_at": null,
  "estimated_seconds": 44
}
POST/v1/rendersRender one or more outputs from a project.

REQUEST

{
  "project_id": "prj_4b91de",
  "outputs": ["video", "guide", "interactive", "clips"],
  "video": { "resolution": "2160p", "fps": 60, "aspect": ["16:9", "9:16"] },
  "locales": ["en-US", "de-DE", "ja-JP"],
  "webhook_url": "https://hooks.meridian.app/demoriff"
}

RESPONSE

{
  "id": "ren_c17a02",
  "status": "queued",
  "minutes_billed": 1.8,
  "outputs": { "video": "pending", "guide": "pending",
               "interactive": "pending", "clips": "pending" }
}
GET/v1/assets/{id}/analyticsPer-second retention, hotspot clicks and identified viewers.

RESPONSE

{
  "asset_id": "ast_9f21c8",
  "period": { "from": "2026-08-01", "to": "2026-09-01" },
  "views": 8412,
  "completion_rate": 0.71,
  "retention": [1.0, 0.98, 0.96, 0.95, 0.93, 0.90, …],
  "cta": { "impressions": 5960, "clicks": 1033, "rate": 0.173 },
  "accounts": [{ "domain": "cardinal.com", "viewers": 4, "max_depth": 0.94 }]
}
POST/v1/localesCreate or refresh a localized variant. Never consumes video minutes.

REQUEST

{
  "project_id": "prj_4b91de",
  "locales": ["fr-FR", "es-ES", "pt-BR"],
  "lip_sync": true,
  "preserve_pinned": true
}

RESPONSE

{
  "created": ["loc_fr_1a", "loc_es_2b", "loc_pt_3c"],
  "status": "queued",
  "minutes_billed": 0
}

Webhooks

Delivered with an HMAC-SHA256 signature in the DemoRiff-Signature header. Retried with exponential backoff for 24 hours.

recording.processedTranscription and interaction analysis complete.
project.readyAuto-edit finished; the transcript is editable.
render.completedOne or more outputs finished. Payload carries signed URLs.
render.failedA render failed. Payload carries a machine-readable reason.
locale.staleA source project changed, invalidating this locale.
asset.thresholdA viewer crossed a watch-depth threshold you configured.
usage.warningWorkspace reached 80% of its monthly video minutes.