Skip to main content
The Convertly SDK wraps multipart uploads, media tool source URLs, async job polling, and file transfers.
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 and configure an origin source or Convertly Storage file id first.
npm install @convertly-sh/sdk

Create a client

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:
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:
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

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

OptionTypeDescription
formatstringRequired. Target format: jpg, png, webp, avif, svg, mp4, webm, mov, mp3, wav, ogg, m4a, flac, pdf, etc.
compressionstringImage compression preset: high, balanced, ultra.
resizestringResize strategy: fit, fill, cover, contain.
resizeWidthnumberTarget width in pixels.
resizeHeightnumberTarget height in pixels.
autoOrientbooleanAuto-rotate based on EXIF. Default true.
monobooleanFor SVG tracing: true for monochrome, false to preserve color.
saveToStoragebooleanSave 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:
const svg = await convertly.media.convert({
  file: logoBuffer,
  filename: "logo.png",
  format: "svg",
  mono: false,
});

Compress a file

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

Compression options

OptionTypeDescription
mode"quality" | "target-size"quality uses a 1-100 level. target-size aims for a specific byte count.
qualitynumber1-100 quality level. Higher is better quality, larger file.
targetBytesnumberTarget file size in bytes when mode is target-size.
losslessbooleanUse lossless compression where supported.
stripMetadatabooleanRemove EXIF and metadata.
saveToStoragebooleanSave 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

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

Thumbnails and poster frames

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

Watermark

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

PDF tools

// 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

// 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:
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:
// 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

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

// 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

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.
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:
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:
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

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.
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 — 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:
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

MethodDescription
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 (also wired into the Mintlify API Reference)
  • Generate clients with OpenAPI Generator or your platform’s codegen tooling
  • Webhooks, workflows, and CDN configuration remain REST-first — see the API Reference