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

# JavaScript SDK

> Use the official Convertly JavaScript and TypeScript SDK for media conversion, compression, media tools, transfers, async jobs, and polling.

The Convertly SDK wraps multipart uploads, media tool source URLs, async job polling, and file transfers.

<Note>
  **CDN vs API:** This SDK is for the **media REST API** (convert, compress, trim, jobs, etc.). For **on-the-fly image delivery** (resize, WebP/AVIF, smart crop, Next.js loader), use [`@convertly-sh/image`](/docs/image-cdn/sdks) and configure an [origin source](/docs/image-cdn/operations#origin-sources) or Convertly Storage file id first.
</Note>

```bash theme={"system"}
npm install @convertly-sh/sdk
```

## Create a client

```ts theme={"system"}
import { Convertly } from "@convertly-sh/sdk";

const apiKey = process.env.CONVERTLY_API_KEY;
if (!apiKey) {
  throw new Error("Missing CONVERTLY_API_KEY");
}

const convertly = new Convertly({
  apiKey,
});
```

For staging or a custom API origin, pass a `baseUrl`:

```ts theme={"system"}
const convertly = new Convertly({
  apiKey: process.env.CONVERTLY_API_KEY!,
  baseUrl: "https://staging.convertly.sh",
});
```

You can also provide a custom `fetch` implementation for testing or middleware:

```ts theme={"system"}
const convertly = new Convertly({
  apiKey: process.env.CONVERTLY_API_KEY!,
  fetch: (url, init) => {
    console.log("Convertly request:", url);
    return fetch(url, init);
  },
});
```

## Convert a file

```ts theme={"system"}
const buffer = await fs.readFile("./photo.png");

const result = await convertly.media.convert({
  file: buffer,
  filename: "photo.png",
  format: "webp",
  compression: "balanced",
  resizeWidth: 1600,
});
```

Accepted file inputs for conversion and compression: `Blob`, `ArrayBuffer`, `Uint8Array`, or `Buffer`.

The synchronous `media.convert` and `media.compress` helpers send multipart file bytes to `/api/convert` and `/api/compress`. Remote HTTP(S) `sourceUrl` inputs are supported by media tools, signed transforms, and transfer jobs. Keep API keys on your server, worker, or trusted automation. For browser apps, call your own backend first and let that backend call Convertly.

### Conversion options

| Option          | Type      | Description                                                                                                                             |
| --------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `format`        | `string`  | **Required.** Target format: `jpg`, `png`, `webp`, `avif`, `svg`, `mp4`, `webm`, `mov`, `mp3`, `wav`, `ogg`, `m4a`, `flac`, `pdf`, etc. |
| `compression`   | `string`  | Image compression preset: `high`, `balanced`, `ultra`.                                                                                  |
| `resize`        | `string`  | Resize strategy: `fit`, `fill`, `cover`, `contain`.                                                                                     |
| `resizeWidth`   | `number`  | Target width in pixels.                                                                                                                 |
| `resizeHeight`  | `number`  | Target height in pixels.                                                                                                                |
| `autoOrient`    | `boolean` | Auto-rotate based on EXIF. Default `true`.                                                                                              |
| `mono`          | `boolean` | For SVG tracing: `true` for monochrome, `false` to preserve color.                                                                      |
| `saveToStorage` | `boolean` | Save the output to Convertly Storage.                                                                                                   |

API-key conversion requests do not save files by default. Set `saveToStorage: true` only when your app needs Convertly to keep a durable stored-file record.

For raster-to-SVG conversion, color is preserved by default. Set `mono: true` only for monochrome tracing:

```ts theme={"system"}
const svg = await convertly.media.convert({
  file: logoBuffer,
  filename: "logo.png",
  format: "svg",
  mono: false,
});
```

## Compress a file

```ts theme={"system"}
const result = await convertly.media.compress({
  file: buffer,
  filename: "hero.jpg",
  quality: 82,
  stripMetadata: true,
});
```

### Compression options

| Option          | Type                         | Description                                                                 |
| --------------- | ---------------------------- | --------------------------------------------------------------------------- |
| `mode`          | `"quality" \| "target-size"` | `quality` uses a 1-100 level. `target-size` aims for a specific byte count. |
| `quality`       | `number`                     | 1-100 quality level. Higher is better quality, larger file.                 |
| `targetBytes`   | `number`                     | Target file size in bytes when `mode` is `target-size`.                     |
| `lossless`      | `boolean`                    | Use lossless compression where supported.                                   |
| `stripMetadata` | `boolean`                    | Remove EXIF and metadata.                                                   |
| `saveToStorage` | `boolean`                    | Save the output to Convertly Storage.                                       |

Compression follows the same storage rule as conversion: results are returned immediately unless you opt in with `saveToStorage: true`.

## Media tools

All media tools accept the same file input pattern (`file`, `sourceUrl`, or string URL) and support `async: true` for long-running operations.

### Background removal

```ts theme={"system"}
const cutout = await convertly.media.removeBackground({
  sourceUrl: "https://cdn.example.com/product.jpg",
  format: "png",
  model: "medium",
  async: true,
});
```

### Thumbnails and poster frames

```ts theme={"system"}
const thumb = await convertly.media.thumbnail({
  sourceUrl: "https://cdn.example.com/video.mp4",
  time: 5.0,
  width: 320,
  height: 180,
});
```

### Watermark

```ts theme={"system"}
const watermarked = await convertly.media.watermark({
  file: imageBuffer,
  filename: "photo.jpg",
  text: "Convertly",
  position: "bottom-right",
  opacity: 0.5,
});
```

### PDF tools

```ts theme={"system"}
// Generate a preview image from a PDF
const preview = await convertly.media.pdfPreview({
  sourceUrl: "https://cdn.example.com/document.pdf",
  page: 1,
  width: 800,
});

// Convert images to a PDF
const pdf = await convertly.media.imageToPdf({
  file: imageBuffer,
  filename: "scan.png",
});
```

### Metadata and inspection

```ts theme={"system"}
// Strip EXIF and metadata
const clean = await convertly.media.stripMetadata({
  file: imageBuffer,
  filename: "photo.jpg",
});

// Inspect file properties
const info = await convertly.media.inspect({
  sourceUrl: "https://cdn.example.com/video.mp4",
});
```

### Signed transforms

Generate a time-limited signed URL for on-the-fly image transforms without uploading:

```ts theme={"system"}
const signed = await convertly.media.signedTransform({
  sourceUrl: "https://cdn.example.com/product.jpg",
  preset: "ecommerce",
  width: 800,
  height: 800,
  fit: "cover",
  format: "webp",
  quality: 85,
  expiresIn: 3600,
});

// signed.url contains the time-limited transform URL
// signed.expiresAt is the ISO expiration timestamp
```

### Full tool list

* `thumbnail`
* `pdfPreview`
* `imageToPdf`
* `stripMetadata`
* `posterFrame`
* `extractAudio`
* `watermark`
* `inspect`
* `trim`
* `gif`
* `storyboard`
* `transform`
* `removeBackground`
* `signedTransform`
* `transfer`

## Transfer and download files

Download a remote file through Convertly, optionally extracting archives:

```ts theme={"system"}
// Download as ArrayBuffer
const fileBuffer = await convertly.media.transfer({
  sourceUrl: "https://cdn.example.com/archive.zip",
});

// Extract archive to Convertly Storage
const result = await convertly.media.transfer({
  sourceUrl: "https://cdn.example.com/archive.zip",
  destination: "convertly-storage",
  extract: true,
  extractOptions: {
    preservePaths: true,
    maxFiles: 100,
    maxTotalBytes: 100 * 1024 * 1024,
  },
});
```

Single-file transfers to `destination: "convertly-storage"` are queued by default and return a `jobId`. Poll with `convertly.jobs.get(jobId)` or wait with `convertly.jobs.wait(jobId)` to read the stored-file result.

## Async jobs

Long-running operations (video conversion, bulk processing, etc.) return a job you can poll.

### Queue a video trim

```ts theme={"system"}
const job = await convertly.media.trim({
  sourceUrl: "https://cdn.example.com/video.mp4",
  start: 12,
  duration: 8,
  format: "mp4",
  async: true,
});

const completed = await convertly.jobs.wait(job.jobId);
```

### Job management

```ts theme={"system"}
// Get a single job
const job = await convertly.jobs.get(jobId);

// List recent jobs
const jobs = await convertly.jobs.list();

// Cancel a pending job
await convertly.jobs.cancel(jobId);

// Wait with custom timeout and abort signal
const controller = new AbortController();
const completed = await convertly.jobs.wait(jobId, {
  intervalMs: 3000,
  timeoutMs: 300000,
  signal: controller.signal,
});
```

## Convertly Storage

List, upload, update, and delete files and folders in Convertly Storage. API keys with storage disabled return `403`; use a workspace API key or a WordPress site token with isolated storage when needed.

### List files and folders

```ts theme={"system"}
const { files, pagination } = await convertly.storage.files.list({
  folderId: null,
  limit: 50,
  offset: 0,
});

const { folders } = await convertly.storage.folders.list({ parentId: null });
```

Pass `folderId: null` or `parentId: null` for workspace root.

### Upload files

The SDK picks a strategy automatically: multipart for files under 8 MiB, presigned direct-to-storage above that threshold.

```ts theme={"system"}
const buffer = await fs.readFile("./hero.jpg");

const { file } = await convertly.storage.files.upload({
  file: buffer,
  filename: "hero.jpg",
  contentType: "image/jpeg",
  folderId: null,
});
```

Force a strategy when you need explicit control:

```ts theme={"system"}
await convertly.storage.files.upload({
  file: largeBuffer,
  filename: "course.mp4",
  contentType: "video/mp4",
  strategy: "presigned",
});
```

### Presigned upload sessions

For resumable or custom upload flows, use the lower-level session API:

```ts theme={"system"}
const session = await convertly.storage.uploads.createSession({
  filename: "archive.zip",
  contentType: "application/zip",
  sizeBytes: buffer.byteLength,
  folderId: folderId ?? null,
});

await convertly.storage.uploads.putObject(session, buffer, "application/zip");

const { file } = await convertly.storage.uploads.complete(session.complete.body);
```

### Update and delete

```ts theme={"system"}
await convertly.storage.files.update(fileId, {
  filename: "hero-final.jpg",
  cdnSlug: "hero-final",
  description: "Homepage hero",
  tags: ["marketing", "homepage"],
});

await convertly.storage.files.delete(fileId);

const { files, facets } = await convertly.storage.files.search({
  q: "sunset",
  tags: ["editorial", "vertical"],
  tagMode: "all",
  orientation: "vertical",
  facets: ["tags", "orientation"],
});

const { tags, addedTags } = await convertly.ai.tagFile(fileId, { maxTags: 8 });

await convertly.library.taxonomy.create({
  slug: "editorial",
  label: "Editorial",
  synonyms: ["magazine"],
});

const { folder } = await convertly.storage.folders.create({
  name: "Client uploads",
  parentId: null,
});

await convertly.storage.folders.delete(folder.id);
```

## Video stream lifecycle

Create streams from stored videos, then manage metadata, captions, chapters, posters, and thumbnail candidates.

```ts theme={"system"}
const { stream } = await convertly.video.streams.create({
  sourceFileId: fileId,
  packageFormats: ["hls"],
  videoCodec: "h264",
  access: "public",
});

await convertly.video.streams.addCaptions(stream.id, {
  label: "English",
  language: "en",
  kind: "subtitles",
  content: "WEBVTT\n\n00:00:01.000 --> 00:00:04.000\nHello world",
});

await convertly.video.streams.replaceChapters(stream.id, [
  { title: "Intro", start: 0 },
  { title: "Demo", start: 42 },
]);

await convertly.video.streams.setPosterFromTime(stream.id, 12.5);

const { candidates } = await convertly.video.streams.listThumbnailCandidates(stream.id);
```

Embed playback with [`@convertly-sh/player`](/docs/video-player) — the SDK covers server-side stream management, not the browser player UI.

## Error handling

The SDK throws `ConvertlyError` on non-2xx responses. The error includes the HTTP status and parsed response body:

```ts theme={"system"}
import { ConvertlyError } from "@convertly-sh/sdk";

try {
  const result = await convertly.media.convert({ ... });
} catch (err) {
  if (err instanceof ConvertlyError) {
    console.error("Status:", err.status);
    console.error("Body:", err.body);
  }
}
```

## Method reference

| Method                                                                    | Description                                                                  |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `new Convertly(options)`                                                  | Create a client. Options: `apiKey`, `baseUrl?`, `fetch?`.                    |
| `convertly.media.convert(opts)`                                           | Convert a file to another format.                                            |
| `convertly.media.compress(opts)`                                          | Compress an image or document.                                               |
| `convertly.media.thumbnail(opts)`                                         | Generate a thumbnail or poster frame.                                        |
| `convertly.media.removeBackground(opts)`                                  | Remove the background from an image.                                         |
| `convertly.media.watermark(opts)`                                         | Add a text or image watermark.                                               |
| `convertly.media.pdfPreview(opts)`                                        | Render a PDF page to an image.                                               |
| `convertly.media.imageToPdf(opts)`                                        | Convert images to a PDF.                                                     |
| `convertly.media.stripMetadata(opts)`                                     | Remove EXIF and metadata.                                                    |
| `convertly.media.inspect(opts)`                                           | Inspect file properties.                                                     |
| `convertly.media.trim(opts)`                                              | Trim video or audio.                                                         |
| `convertly.media.gif(opts)`                                               | Create a GIF from video.                                                     |
| `convertly.media.storyboard(opts)`                                        | Generate a video storyboard.                                                 |
| `convertly.media.transform(opts)`                                         | Apply transforms to an image.                                                |
| `convertly.media.transfer(opts)`                                          | Download or transfer a remote file.                                          |
| `convertly.media.signedTransform(opts)`                                   | Generate a signed transform URL.                                             |
| `convertly.video.streams.create(opts)`                                    | Create an HLS/DASH video streaming asset from a stored video.                |
| `convertly.video.streams.list(opts?)`                                     | List video streaming assets.                                                 |
| `convertly.video.streams.get(id)`                                         | Get a video streaming asset with renditions, captions, and analytics counts. |
| `convertly.video.streams.update(id, opts)`                                | Update title, description, tags, or engagement settings.                     |
| `convertly.video.streams.delete(id)`                                      | Delete a video streaming asset.                                              |
| `convertly.video.streams.addCaptions(id, track)`                          | Add or replace a WebVTT caption track.                                       |
| `convertly.video.streams.removeCaption(id, captionId)`                    | Remove a caption track.                                                      |
| `convertly.video.streams.replaceChapters(id, chapters)`                   | Replace chapter markers.                                                     |
| `convertly.video.streams.removeChapter(id, chapterId)`                    | Remove one chapter.                                                          |
| `convertly.video.streams.setPosterFromTime(id, seconds)`                  | Generate a poster frame from the source video.                               |
| `convertly.video.streams.uploadPoster(id, file, filename?, contentType?)` | Upload a custom poster image.                                                |
| `convertly.video.streams.listThumbnailCandidates(id)`                     | List generated thumbnail candidates.                                         |
| `convertly.storage.files.list(opts?)`                                     | List Convertly Storage files with pagination.                                |
| `convertly.storage.files.get(id)`                                         | Fetch file metadata and a short-lived download URL.                          |
| `convertly.storage.files.upload(opts)`                                    | Upload via multipart or presigned direct-to-storage.                         |
| `convertly.storage.files.update(id, opts)`                                | Rename, slug, or update library metadata.                                    |
| `convertly.storage.files.search(opts?)`                                   | Faceted library search with tags, orientation, and facet counts.             |
| `convertly.storage.files.delete(id)`                                      | Delete a stored file.                                                        |
| `convertly.ai.tagFile(id, opts?)`                                         | AI-generate and persist image tags (Forma AI quota).                         |
| `convertly.library.taxonomy.list(opts?)`                                  | List taxonomy terms for a locale.                                            |
| `convertly.library.taxonomy.create(opts)`                                 | Create a taxonomy term with optional synonyms.                               |
| `convertly.library.taxonomy.update(id, opts)`                             | Update a taxonomy term or replace synonyms.                                  |
| `convertly.library.taxonomy.delete(id)`                                   | Delete a taxonomy term.                                                      |
| `convertly.storage.folders.list(opts?)`                                   | List folders.                                                                |
| `convertly.storage.folders.create(opts)`                                  | Create a folder.                                                             |
| `convertly.storage.folders.update(id, opts)`                              | Rename or move a folder.                                                     |
| `convertly.storage.folders.delete(id)`                                    | Delete a folder and nested contents.                                         |
| `convertly.storage.uploads.createSession(opts)`                           | Start a presigned upload session.                                            |
| `convertly.storage.uploads.putObject(session, bytes, contentType?)`       | PUT bytes to the signed upload URL.                                          |
| `convertly.storage.uploads.complete(body)`                                | Finalize a presigned upload as a stored file.                                |
| `convertly.jobs.get(id)`                                                  | Get a job by ID.                                                             |
| `convertly.jobs.list()`                                                   | List recent jobs.                                                            |
| `convertly.jobs.cancel(id)`                                               | Cancel a pending job.                                                        |
| `convertly.jobs.wait(id, opts?)`                                          | Poll until a job completes or fails.                                         |

Raw REST API examples remain available in the API Reference for teams that prefer direct HTTP calls.

## Other languages

Convertly ships first-party SDKs for **JavaScript/TypeScript** and **PHP**. For Python, Go, Ruby, Java, or .NET, use the REST API with your HTTP client of choice.

* OpenAPI spec: [openapi.json](https://docs.convertly.sh/openapi.json) (also wired into the Mintlify API Reference)
* Generate clients with [OpenAPI Generator](https://openapi-generator.tech/) or your platform's codegen tooling
* Webhooks, workflows, and CDN configuration remain REST-first — see the [API Reference](/api-reference/media/convert-files)
