Documentation

RenderSnap API

A REST API for everything the editor can do — create projects, manage assets, submit renders, batch export to every social platform, and automate your video workflow at any scale.

Base URLhttps://rendersnap.io/api/v1

Authentication

Every request sends the same header:

Authorization: Bearer <token>
Content-Type: application/json

RenderSnap accepts two token types. Use session tokens for browser and first-party app flows. Use workspace API keys for server-to-server workers, cron jobs, and backend automations.

Session Token

Use this for browser or first-party app flows. Sign in to RenderSnap and copy your session token from the Developer Dashboard under API Access. Tokens expire after 1 hour.

// Copy your session token from the Developer Dashboard → API Access
const token = "<session_token>";

await fetch("https://rendersnap.io/api/v1/projects", {
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
});

Workspace API Key

Use this for backend services. Keys stay valid until revoked and carry scoped permissions like renders:create.

Authorization: Bearer rs_your_workspace_api_key
Content-Type: application/json

Workspace API keys are created from an authenticated user session and are available on plans with API access enabled.

Create keys from the Developer Dashboard or programmatically:

POST https://rendersnap.io/api/v1/api-keys
Authorization: Bearer <session_token>
Content-Type: application/json

{
  "name": "production-worker",
  "scopes": [
    "projects:read",
    "assets:read",
    "assets:upload",
    "renders:create",
    "renders:read"
  ]
}

API Keys

Create scoped workspace API keys for worker processes, cron jobs, and backend integrations. API keys are available on plans with API access enabled.

GET/api-keysList active workspace API keys
POST/api-keysCreate a new scoped API key (secret shown once)
DELETE/api-keys/:idRevoke an API key

Projects

Projects contain a timeline JSON and link to workspace assets. All operations are scoped to your workspace.

GET/projectsList all projects (paginated)
POST/projectsCreate a new project
GET/projects/:idGet a single project with full timeline
PATCH/projects/:idUpdate project name, timeline, or status
DELETE/projects/:idArchive a project (soft delete)

Assets

Assets are video, audio, image, subtitle, font, or brand kit files stored in your workspace. Upload via a signed URL to avoid sending files through our API servers.

GET/assetsList workspace assets, filterable by kind and status
POST/assetsRequest an upload URL (returns assetId + signedUrl)
GET/assets/:idGet asset metadata and download URL
PATCH/assets/:idUpdate name, tags, or status (e.g. mark as ready)
DELETE/assets/:idDelete an asset and remove it from storage

Renders

Submit a render job to convert a project timeline into a finished video. Render jobs are async — poll the job endpoint or use webhooks to receive status updates.

POST/rendersSubmit a render job (returns 202 with renderId)
GET/rendersList render jobs, filterable by status
GET/renders/:idGet render job status, progress, and output URL

Batch Renders

Submit one project for rendering across multiple social media formats simultaneously. A single batch call fans out into individual render jobs — one per format — each with the canvas automatically resized to the target dimensions. Requires Pro plan or above.

POST/renders/batchSubmit a batch render (returns 202 with batchId + renderIds)
GET/renders/batchList batch render jobs (paginated)
GET/renders/batch/:idGet batch status and per-format render results

Supported formats — pass any combination as the formats array:

Format keyDimensionsPlatform
youtube1920 × 1080 (16:9)YouTube
tiktok1080 × 1920 (9:16)TikTok / Shorts
instagram_square1080 × 1080 (1:1)Instagram Square
instagram_story1080 × 1920 (9:16)Instagram Story
twitter1280 × 720 (16:9)Twitter/X
linkedin1200 × 628 (1.91:1)LinkedIn

Batch status is computed on read. Possible values: queued processing done failed mixed cancelled. mixed means some formats succeeded and some failed.

Templates

Templates are reusable timeline JSON presets with categories and thumbnail previews. Use them to scaffold new projects programmatically.

GET/templatesList available templates
POST/templatesCreate a template from an existing project
GET/templates/:idGet template details and timeline JSON
PATCH/templates/:idUpdate template metadata
DELETE/templates/:idDelete a template

Workspace

Read and update your workspace profile, plan, and usage stats.

GET/workspaces/meGet current workspace details and usage
PATCH/workspaces/meUpdate workspace name or slug
GET/workspaces/me/usageGet API usage, render counts, and recent audit activity

Team & Roles

Manage workspace members, invitations, and role-based access control for both humans and machine users.

GET/workspaces/me/membersList workspace members and current roles
PATCH/workspaces/me/members/:uidUpdate a member's role
DELETE/workspaces/me/members/:uidRemove a member from the workspace
GET/workspaces/me/invitesList pending workspace invites
POST/workspaces/me/invitesCreate and send a workspace invite
DELETE/workspaces/me/invites/:tokenRevoke a pending invite

Asset upload — full example

Assets are uploaded in three steps to keep binary data off the API servers. First register the file to get a signed URL, then PUT the file directly to then mark the asset ready. Once ready, use the assetId in any render job.

// Step 1 — Register the asset; response contains assetId + a signed uploadUrl
POST https://rendersnap.io/api/v1/assets
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "intro.mp4",
  "mimeType": "video/mp4",
  "sizeBytes": 10485760
}

// 201 Created
{
  "ok": true,
  "data": {
    "assetId": "ast_abc123",
    "uploadUrl": "https://storage.googleapis.com/...",
    "uploadHeaders": { "Content-Type": "video/mp4" },
    "expiresAt": "2026-06-20T12:15:00Z"
  }
}

// Step 2 — PUT the file directly to data.uploadUrl
//           Use Content-Type from data.uploadHeaders
//           No Authorization header — access is encoded in the signed URL
PUT <data.uploadUrl>
Content-Type: video/mp4
(binary file body)

// 200 OK — upload confirmed

// Step 3 — Mark the asset ready so it can be used in render jobs
PATCH https://rendersnap.io/api/v1/assets/ast_abc123
Authorization: Bearer <token>
Content-Type: application/json

{ "status": "ready" }

// 200 OK
{
  "ok": true,
  "data": { "id": "ast_abc123", "status": "ready", "name": "intro.mp4", ... }
}

The signed uploadUrl expires after 15 minutes. The uploadHeaders field in the response contains the exact headers to send with the PUT — typically just Content-Type matching the mimeType you sent in step 1.

Submit a render — full example

POST https://rendersnap.io/api/v1/renders
Authorization: Bearer <token>

{
  "projectId": "proj_abc123",
  "resolution": "1080p",
  "format": "mp4",
  "fps": 30,
  "webhookUrl": "https://yoursite.com/webhooks/renders"
}

// 202 Accepted
{
  "ok": true,
  "data": {
    "renderId": "rnd_xyz789",
    "jobId": "rnd_xyz789",
    "status": "queued",
    "message": "Rendering started — you'll receive an email notification when it's ready."
  }
}

Batch render — full example

Submit one project and receive separate output files for every social format in a single API call. Each format is rendered in parallel as an independent child job. Requires Pro plan or above.

POST https://rendersnap.io/api/v1/renders/batch
Authorization: Bearer <token>

{
  "projectId": "proj_abc123",
  "formats": ["youtube", "tiktok", "instagram_square", "instagram_story"],
  "resolution": "1080p",
  "format": "mp4",
  "fps": 30,
  "webhookUrl": "https://yoursite.com/webhooks/renders"
}

// 202 Accepted
{
  "ok": true,
  "data": {
    "batchId": "bat_def456",
    "renderIds": ["rnd_001", "rnd_002", "rnd_003", "rnd_004"],
    "status": "queued",
    "message": "Batch render queued — 4 formats submitted."
  }
}

// Poll for results
GET https://rendersnap.io/api/v1/renders/batch/bat_def456

{
  "ok": true,
  "data": {
    "id": "bat_def456",
    "projectId": "proj_abc123",
    "status": "done",
    "formats": ["youtube", "tiktok", "instagram_square", "instagram_story"],
    "renders": [
      { "socialFormat": "youtube",          "status": "done", "outputUrl": "https://…/out_001.mp4" },
      { "socialFormat": "tiktok",           "status": "done", "outputUrl": "https://…/out_002.mp4" },
      { "socialFormat": "instagram_square", "status": "done", "outputUrl": "https://…/out_003.mp4" },
      { "socialFormat": "instagram_story",  "status": "done", "outputUrl": "https://…/out_004.mp4" }
    ]
  }
}

Webhooks

Pass a webhookUrl when submitting a render job. We will POST to that URL when the job completes, fails, or is cancelled. Verify authenticity by checking the x-render-signature header (HMAC-SHA256 of the payload, signed with your webhook secret).

// Payload sent to your webhookUrl on completion
x-render-signature: sha256=<hmac_of_raw_body>

{
  "event": "render.done",
  "renderJobId": "rnd_xyz789",
  "projectId": "proj_abc123",
  "workspaceId": "ws_abc123",
  "status":   "done",
  "outputUrl": "https://rendersnap.io/api/v1/renders/rnd_xyz789/content",
  "durationSeconds": 42,
  "completedAt": "2026-03-01T14:22:05Z"
}

Rate limits

Free60 / min1 concurrent
Pro300 / min3 concurrent
Team1,000 / min10 concurrent
EnterpriseCustomCustom

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Error codes

All errors return a consistent JSON envelope:

401UNAUTHORIZEDMissing or invalid token
403FORBIDDENAuthenticated but lacks permission
404NOT_FOUNDResource does not exist
422VALIDATION_ERRORRequest body failed validation
402QUOTA_EXCEEDEDRender minutes quota exhausted
403PLAN_LIMITFeature not available on current plan
429RATE_LIMITEDToo many requests
500INTERNAL_ERRORSomething went wrong on our end