Skip to main content

Installation

npm install @framelane/sdk

Quick start

Upload local media via POST /v1/uploads first, then pass the returned source_url below.
import Framelane from "@framelane/sdk";

const client = new Framelane({
  apiKey: process.env.FRAMELANE_API_KEY,
});

// Submit a render
const render = await client.renders.create({
  width: 1920,
  height: 1080,
  duration: 10.0,
  frameRate: 30,
  outputFormat: "mp4",
  elements: [
    {
      type: "video",
      id: "clip1",
      sourceUrl: process.env.SOURCE_URL!,
      time: 0,
      inPoint: 0,
      outPoint: 10,
    },
  ],
});

// Wait for completion (polls with exponential backoff)
const completed = await client.renders.waitForCompletion(render.id);
console.log(completed.output?.url);

API coverage

ResourceMethods
client.renderscreate, get, list, cancel, download, waitForCompletion
client.taskscreate, get, list, cancel, download, waitForCompletion
client.webhookscreate, get, list, update, delete, test, rotateSecret, listDeliveries
client.apiKeyscreate, list, revoke
client.workspaceget, getUsage, update, delete

Webhook signature verification

import { verifyWebhookSignature } from "@framelane/sdk";

app.post("/hooks/framelane", (req, res) => {
  const isValid = verifyWebhookSignature(
    req.body,                              // raw body string
    req.headers["framelane-signature"],    // signature header
    process.env.FRAMELANE_WEBHOOK_SECRET
  );
  if (!isValid) return res.status(400).send("Invalid signature");

  const event = JSON.parse(req.body);
  // handle event...
  res.sendStatus(200);
});

TypeScript types

All request and response types are fully typed and exported:
import type {
  RenderJob,
  TaskJob,
  WebhookEvent,
  JobStatus,
  TaskType,
} from "@framelane/sdk";