Skip to content

API reference

One REST API over everything the product does: upload a recording, read what the AI concluded, share it, export it, search across it, and receive the reports your own visitors file. JSON in, JSON out, cursor pagination, and RFC 7807 problem responses.

Authentication

Create a key under Dashboard → Developers (Pro and above). Keys are shown once, hashed at rest, scoped to the workspace that created them, and prefixed sr_live_. Send it as a bearer token on every request:

curl https://api.scenerecap.com/v1/recordings \
  -H "Authorization: Bearer sr_live_…"
The key is shown once, at creation. It is stored only as a hash, so a lost key cannot be recovered — revoke it and issue another. Treat it like a password: it is a workspace-wide credential, not a per-user one.

Conventions

Base URLhttps://api.scenerecap.com
VersioningPath-prefixed /v1. Additive changes ship without a version bump; removals do not.
PaginationCursor. Pass limit (1–100, default 30) and cursor (the ISO timestamp from nextCursor). A null nextCursor means the last page.
Rate limit300 requests per minute per key. Over that you get 429; retry after a short backoff.
ErrorsRFC 7807 application/problem+json with status, title and detail. A 402 means a plan limit, not a payment failure.
TimestampsISO 8601, UTC. Timeline offsets are seconds from the start of the recording.

Endpoints

Recordings

The core object: media, AI outputs, chapters, transcript and playback URLs.
GET/v1/recordings
List recordings, newest first.Filters: workspace, folder, q. Cursor pagination.
GET/v1/recordings/:id
One recording with chapters, transcript, AI outputs and signed playback URLs.
POST/v1/recordings
Create a recording from a completed upload.Accepts eventLogUploadId and redactionUploadId sidecars.
PATCH/v1/recordings/:id
Rename, move to a folder, change mode.
DELETE/v1/recordings/:id
Delete a recording.Cascades to storage — originals and derived assets both go.
POST/v1/recordings/:id/reanalyze
Run another AI mode over the same media.
POST/v1/recordings/:id/retry
Retry a failed pipeline run.
GET/v1/recordings/:id/events
The interaction event log used as evidence.
POST/v1/recordings/:id/voiceover
Generate a narrated variant.Metered in voiceover minutes.
POST/v1/recordings/:id/repro
Re-drive a bug report headlessly and report whether it reproduces — see the Repro Agent docs.Pro+ and metered. Verified origins only, and not available for widget reports — they carry evidence but no click trail.
POST/v1/recordings/:id/perform
Ask the agent to re-perform this recording's flow and record a fresh take — see the Takes docs.Pro+ and metered from the same agent-run allowance. Verified origins only; needs an interaction event log.
GET/v1/recordings/:id/takes
List your take drafts for a recording (drafts are private to the requesting user).
POST/v1/takes/:id/approve
Approve a finished take into a real recording; the result is permanently labelled as performed by the agent.
DELETE/v1/takes/:id
Discard a draft take. Its stored video is deleted immediately; approved takes are refused.
PATCH/v1/outputs/:id
Correct an AI output in place.

Uploads

Multipart, presigned, and the same path the extension and the web uploader use.
POST/v1/uploads
Open a session; returns presigned part URLs.kind: media | eventlog | redaction_manifest
POST/v1/uploads/:id/complete
Finish the upload with the ETag of every part.

Shares and comments

Five access levels, from public to email-restricted, with timestamped comments.
GET/v1/recordings/:id/shares
List share links for a recording.
POST/v1/recordings/:id/shares
Create a share link.
DELETE/v1/shares/:id
Revoke a share link.
POST/v1/shares/:slug/comments
Comment on a shared recording, anchored to a timestamp.
POST/v1/shares/:slug/view
Record a view.Fires the share_viewed lifecycle signal once.
POST/v1/shares/:slug/report
Report a share for abuse.
POST/v1/shares/:slug/resolve
Exchange a password or email grant for access.

Exports and search

POST/v1/recordings/:id/exports
Queue an export.format: markdown | html | pdf | docx | gif — exactly these values. Plan-gated; poll for the signed URL.
GET/v1/recordings/:id/exports
Poll export status and collect the download URL.
GET/v1/search
Hybrid search: title, full-text and vector, fused with RRF.Results carry timestamps you can deep-link to with ?t=.

Reporting widget and Inbox

Your own visitors record bugs on your site; the reports arrive here already written up.
GET/v1/workspaces/:id/site-keys
List site keys.
POST/v1/workspaces/:id/site-keys
Create a site key.origins is an allowlist (up to 10); retentionDays is opt-in and null means keep forever.
PATCH/v1/site-keys/:id
Rename, change origins, set retention, activate or pause.
DELETE/v1/site-keys/:id
Revoke a site key.
GET/v1/workspaces/:id/reports
The Inbox. Duplicates are collapsed to one row with a clusterCount.Filter by status: new, triaged, closed.
PATCH/v1/reports/:id
Triage a report or attach the issue URL you filed.

Filing to your tracker

GET/v1/integrations
Which providers are configured, connected, or need reconnecting.
GET/v1/integrations/:provider/resources
Pickable targets: channels, repos, teams, projects, pages.
PATCH/v1/integrations/:provider
Set the destination for filed issues.
POST/v1/recordings/:id/create-issue
File the AI bug report to GitHub, Linear or Jira.
POST/v1/recordings/:id/notion-export
Export a tutorial or SOP into Notion.
DELETE/v1/integrations/:provider
Disconnect a provider.

Workspaces, folders and people

GET/v1/me
The caller, their workspaces and per-workspace flags.
POST/v1/workspaces
Create a workspace.
GET/v1/workspaces/:id/members
List members and roles.
POST/v1/workspaces/:id/invites
Invite by email.Tokens are bound to the invited address.
POST/v1/invites/accept
Accept an invite.
GET/v1/workspaces/:id/folders
List folders.
POST/v1/workspaces/:id/folders
Create a folder.
GET/v1/workspaces/:id/billing
Plan, seats and usage against the monthly allowance.

Keys and webhooks

GET/v1/workspaces/:id/api-keys
List API keys (prefix and last use only — never the key).
POST/v1/workspaces/:id/api-keys
Create a key.The only response that ever contains the secret.
DELETE/v1/api-keys/:id
Revoke a key immediately.
GET/v1/workspaces/:id/webhooks
List webhook endpoints.
POST/v1/workspaces/:id/webhooks
Register an endpoint and pick events.
GET/v1/webhooks/:id/deliveries
Every attempt, with status and response.
DELETE/v1/webhooks/:id
Remove an endpoint.

Worked example: upload and analyse

Three calls. Open a session, PUT the parts, then create the recording — the pipeline starts on its own.

# 1. open a multipart session
curl -sX POST https://api.scenerecap.com/v1/uploads \
  -H "Authorization: Bearer $SR_KEY" -H "content-type: application/json" \
  -d '{"kind":"media","filename":"session.webm","contentType":"video/webm","sizeBytes":8123456}'
# -> { "uploadId": "…", "partSize": 8388608, "parts": [{ "n": 1, "url": "https://…" }] }

# 2. PUT each part to its presigned url, keeping the ETag each one returns
curl -sX PUT "$PART_URL" --data-binary @part-1.bin -D - | grep -i etag

# 3. complete, then create the recording
curl -sX POST https://api.scenerecap.com/v1/uploads/$UPLOAD_ID/complete \
  -H "Authorization: Bearer $SR_KEY" -H "content-type: application/json" \
  -d '{"parts":[{"n":1,"etag":"abc123"}]}'

curl -sX POST https://api.scenerecap.com/v1/recordings \
  -H "Authorization: Bearer $SR_KEY" -H "content-type: application/json" \
  -d '{"uploadId":"'$UPLOAD_ID'","title":"Checkout fails","mode":"bug_report"}'

Poll GET /v1/recordings/:id until status is ready, then read outputs for the bug report, tutorial, explanation or recap.

Worked example: triage the widget Inbox

Duplicates arrive already grouped, so one row can stand for many reports.

curl -s "https://api.scenerecap.com/v1/workspaces/$WS/reports?status=new" \
  -H "Authorization: Bearer $SR_KEY"
# -> reports[0].clusterCount === 5  (five visitors, one bug, one row)

# file it, then mark it triaged with the issue you created
curl -sX POST https://api.scenerecap.com/v1/recordings/$REC/create-issue \
  -H "Authorization: Bearer $SR_KEY" -H "content-type: application/json" \
  -d '{"provider":"linear"}'

curl -sX PATCH https://api.scenerecap.com/v1/reports/$REPORT \
  -H "Authorization: Bearer $SR_KEY" -H "content-type: application/json" \
  -d '{"status":"triaged","issueUrl":"https://linear.app/…"}'

Webhooks

Register a URL under Developers and choose your events: recording.ready, recording.shared, comment.created. Each delivery is a JSON POST carrying X-SceneRecap-Event, X-SceneRecap-Delivery and X-SceneRecap-Signature: sha256=<hex> — an HMAC-SHA256 of the raw body using the secret shown once at creation.

Verify against the raw body, before any JSON parsing. A re-serialised body will not match the signature, and comparing with === instead of a timing-safe compare leaks the secret a byte at a time.
import crypto from "node:crypto";

export function verify(rawBody: Buffer, header: string, secret: string): boolean {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(header);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Non-2xx responses are retried with exponential backoff up to three attempts in total (the first delivery plus two retries), and every attempt — status, response body, timing — is visible in the Deliveries panel.

Plan limits

Limits are enforced server-side and return 402 with a message naming the limit. API keys require Pro; the reporting widget is a paid add-on; export formats, AI analyses and agent runs (Repro Agent verdicts and Takes draw from one pool) each have their own monthly allowance. See pricing for the current numbers.