Freedam

Official SDKs

Freedam ships first-party client libraries so you don't have to hand-roll HTTP plumbing, retries, pagination, polling, or webhook signature verification.

TypeScript / JavaScript

@freedam/sdk — works in Node 18+, Bun, Deno, and modern browsers. The SDK is generated from the same OpenAPI spec served at /docs/api.json, so its request/response types stay aligned with the live API.

Install

npm install @freedam/sdk
# or
pnpm add @freedam/sdk
# or
yarn add @freedam/sdk

Construct a client

import { FreedamClient } from '@freedam/sdk';

const client = new FreedamClient({
    baseUrl: 'https://your-freedam-instance.com',
    token: process.env.FREEDAM_TOKEN!,
    // Optional — sensible defaults shown:
    maxRetries: 3, // retries on network errors and 5xx
    timeout: 30_000, // per-request timeout in ms
    // fetch: customFetch  // override the underlying fetch implementation
});

The client honours the Retry-After header on 429 responses and applies exponential back-off on retried requests — see Rate Limiting.

Resources

Every resource is exposed as a property on the client. Methods accept typed bodies and return typed responses.

Property API surface
client.assets list, listPages, listAll, get, update, delete
client.collections list, listPages, listAll, get, create, update, delete, addAssets, removeAssets
client.consents me, forUser, history, historyPages
client.embeds get, create, revoke — iframe codes for video assets
client.metadata definitions, vocabularies, vocabulary, terms, term
client.operations list, listPages, create, get, cancel, waitForCompletion
client.shares list, listPages, listAll, get, create, update, delete, revoke
client.tokens list, create, revoke
client.uploads createBatch, uploadFile, uploadFiles, getBatchStatus
client.webhooks list, listPages, get, create, update, delete, test, deliveries, rotateSecret

Common usage patterns

List with cursor-style pagination

// Single page
const { data, meta } = await client.assets.list({ per_page: 50 });

// Yield one page at a time (lazy)
for await (const page of client.assets.listPages()) {
    for (const asset of page) {
        console.log(asset.gaid, asset.title);
    }
}

// Eagerly collect every page (use only when total is bounded)
const all = await client.assets.listAll({ asset_class_id: 7 });

Upload assets

const batch = await client.uploads.createBatch({ name: 'Photoshoot Q3' });

// Single file
await client.uploads.uploadFile(batch.id, file);

// Multiple files in sequence
await client.uploads.uploadFiles(batch.id, [
    { file: file1 },
    { file: file2, filename: 'override.jpg' },
]);

// Poll for ingestion completion
const status = await client.uploads.getBatchStatus(batch.id);

Generate a video embed code

const embed = await client.embeds.create('A_01HXYZ', {
    width: 1280,
    height: 720,
    autoplay: true,
    muted: true,
    allowed_domains: ['example.com'],
});

// Drop the responsive snippet straight into the page
document.body.insertAdjacentHTML(
    'beforeend',
    embed.responsive_html ?? embed.iframe_html,
);

Run a long operation and wait for it

const op = await client.operations.create(
    {
        type: 'asset_bulk_update',
        params: { ids: [...gaids], values: { status: 'archived' } },
    },
    { idempotencyKey: crypto.randomUUID() },
);

// Polls /v1/operations/{id} until status is terminal (completed/failed/cancelled)
const finished = await client.operations.waitForCompletion(op.id, {
    intervalMs: 2_000,
    timeoutMs: 10 * 60_000,
});

Verify an incoming webhook

verifyWebhookSignature takes the raw request body, the signature header value, the timestamp header, and your webhook secret. It throws FreedamSignatureError on mismatch or stale timestamp; on success it returns void.

import { verifyWebhookSignature, FreedamSignatureError } from '@freedam/sdk';

try {
    await verifyWebhookSignature(
        rawBody,
        request.headers['x-freedam-signature-256'],
        request.headers['x-freedam-timestamp'],
        process.env.FREEDAM_WEBHOOK_SECRET!,
        { maxAgeSec: 300 },
    );
} catch (err) {
    if (err instanceof FreedamSignatureError) {
        return new Response('Invalid signature', { status: 401 });
    }
    throw err;
}

The header names are X-Freedam-Signature-256 (hex HMAC-SHA256) and X-Freedam-Timestamp (Unix seconds). See Webhooks for the full delivery contract.

Error handling

Every API failure raises a typed error:

  • FreedamApiError — non-2xx response from the server. Carries status, code, details, and the convenience getters isNotFound, isForbidden, isUnauthorized, isRateLimited, isValidationError.
  • FreedamTimeoutError — request or polling helper exceeded its timeout.
  • FreedamSignatureError — webhook signature or timestamp validation failed.
  • FreedamError — base class for the three above; catch this if you want to handle any SDK error generically.
import { FreedamApiError } from '@freedam/sdk';

try {
    await client.assets.get('does-not-exist');
} catch (err) {
    if (err instanceof FreedamApiError && err.isNotFound) {
        // 404 — handle missing asset
    } else {
        throw err;
    }
}

Versioning policy

The SDK is currently 0.x. While we are pre-1.0, minor versions may include breaking changes — pin a tilde-range (~0.2.0) and read the changelog before upgrading. Once we release 1.0.0 we will switch to strict semver: patch for fixes, minor for additive changes, major for breaking changes.

The API itself is versioned independently: the current major is v1 and endpoint paths are stable within v1. Future breaking changes will land under v2 and the two will run side-by-side for at least one release cycle.

show.relatedDocs.heading

show.relatedDocs.subheading