> ## Documentation Index
> Fetch the complete documentation index at: https://docs.framelane.io/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Official TypeScript SDK for the Framelane API.

## Installation

```bash theme={null}
npm install @framelane/sdk
```

## Quick start

Upload local media via [`POST /v1/uploads`](/introduction/uploads) first, then pass the returned `source_url` below.

```typescript theme={null}
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

| Resource           | Methods                                                                               |
| ------------------ | ------------------------------------------------------------------------------------- |
| `client.renders`   | `create`, `get`, `list`, `cancel`, `download`, `waitForCompletion`                    |
| `client.tasks`     | `create`, `get`, `list`, `cancel`, `download`, `waitForCompletion`                    |
| `client.webhooks`  | `create`, `get`, `list`, `update`, `delete`, `test`, `rotateSecret`, `listDeliveries` |
| `client.apiKeys`   | `create`, `list`, `revoke`                                                            |
| `client.workspace` | `get`, `getUsage`, `update`, `delete`                                                 |

## Webhook signature verification

```typescript theme={null}
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:

```typescript theme={null}
import type {
  RenderJob,
  TaskJob,
  WebhookEvent,
  JobStatus,
  TaskType,
} from "@framelane/sdk";
```
