Skip to main content

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.

The Media Tools API turns common product media tasks into simple authenticated requests. Every tool accepts either a multipart file upload or a remote sourceUrl. Add async=true when the job may be heavy, such as background removal, video watermarking, PDF previews, audio extraction, or large thumbnails.

Input modes

file upload
curl -X POST "https://convertly.sh/api/media/thumbnail" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./video.mp4" \
  -F "width=640" \
  -F "height=360" \
  -F "format=jpg"
remote URL
curl -X POST "https://convertly.sh/api/media/thumbnail" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "sourceUrl=https://cdn.example.com/uploads/video.mp4" \
  -F "width=640" \
  -F "height=360" \
  -F "format=jpg"
async
curl -X POST "https://convertly.sh/api/media/poster-frame" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "sourceUrl=https://cdn.example.com/uploads/video.mp4" \
  -F "timestamp=4" \
  -F "async=true"
Async media tools return a jobId. Poll GET /api/jobs/{id} or listen for media.tool.completed webhooks.
{
  "jobId": "65f3a673-69d6-42cc-8f6b-fc5a21fb5a8e",
  "status": "pending",
  "tool": "poster-frame"
}

Endpoints

ToolEndpointBest for
Thumbnail generationPOST /api/media/thumbnailImage thumbnails and video preview thumbnails.
PDF previewsPOST /api/media/pdf-previewRendering a PDF page as jpg, png, webp, or avif.
Image to PDFPOST /api/media/image-to-pdfCombining one or more images into a PDF.
Metadata strippingPOST /api/media/strip-metadataRemoving EXIF, GPS, tags, and container metadata.
Poster framesPOST /api/media/poster-frameExtracting a video frame for upload previews.
Audio extractionPOST /api/media/extract-audioPulling audio from video as mp3, m4a, wav, ogg, or flac.
WatermarkingPOST /api/media/watermarkApplying text watermarks to images and videos.
Media inspectionPOST /api/media/inspectReading dimensions, duration, codecs, file size, streams, and metadata flags.
TrimPOST /api/media/trimCutting video or audio by start time and duration.
Video to GIFPOST /api/media/gifCreating short animated previews from video.
StoryboardPOST /api/media/storyboardGenerating contact sheets from video frames.
Image transformPOST /api/media/transformResizing, cropping, rotating, flipping, and exporting images.
Background removalPOST /api/media/remove-backgroundRemoving image backgrounds while preserving existing transparent cutouts.

Examples

Thumbnail

curl -X POST "https://convertly.sh/api/media/thumbnail" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./video.mp4" \
  -F "width=640" \
  -F "height=360" \
  -F "format=jpg" \
  -F "timestamp=2"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/video.mp4");
body.append("width", "640");
body.append("height", "360");
body.append("format", "jpg");

const res = await fetch("https://convertly.sh/api/media/thumbnail", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

console.log(await res.json());

PDF preview

curl -X POST "https://convertly.sh/api/media/pdf-preview" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./contract.pdf" \
  -F "page=1" \
  -F "format=webp" \
  -F "width=1600"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/contract.pdf");
body.append("page", "1");
body.append("format", "webp");
body.append("async", "true");

const res = await fetch("https://convertly.sh/api/media/pdf-preview", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Image to PDF

curl -X POST "https://convertly.sh/api/media/image-to-pdf" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "files=@./page-1.jpg" \
  -F "files=@./page-2.jpg" \
  -F "pageSize=a4"
const body = new FormData();
body.append("files", fileInput.files[0]);
body.append("files", fileInput.files[1]);
body.append("pageSize", "a4");

await fetch("https://convertly.sh/api/media/image-to-pdf", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Strip metadata

curl -X POST "https://convertly.sh/api/media/strip-metadata" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./photo.jpg"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/photo.jpg");

await fetch("https://convertly.sh/api/media/strip-metadata", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Remove background

curl -X POST "https://convertly.sh/api/media/remove-background" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./product.jpg" \
  -F "format=png" \
  -F "model=medium" \
  -F "async=true"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/product.jpg");
body.append("format", "png");
body.append("model", "medium");

await fetch("https://convertly.sh/api/media/remove-background", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});
When the input already has meaningful transparency, Convertly returns a cleaned transparent output without re-segmenting it. Add force=true only when you intentionally want to segment an already-transparent image again.

Poster frame

curl -X POST "https://convertly.sh/api/media/poster-frame" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./clip.mp4" \
  -F "timestamp=3.5" \
  -F "width=1280" \
  -F "format=jpg"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/clip.mp4");
body.append("timestamp", "3.5");
body.append("width", "1280");
body.append("async", "true");

await fetch("https://convertly.sh/api/media/poster-frame", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Extract audio

curl -X POST "https://convertly.sh/api/media/extract-audio" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./clip.mp4" \
  -F "format=mp3" \
  -F "bitrateKbps=192" \
  -F "async=true"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/clip.mp4");
body.append("format", "mp3");
body.append("bitrateKbps", "192");
body.append("async", "true");

await fetch("https://convertly.sh/api/media/extract-audio", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Watermark

curl -X POST "https://convertly.sh/api/media/watermark" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./clip.mp4" \
  -F "text=Acme Studio" \
  -F "position=bottom-right" \
  -F "opacity=0.72" \
  -F "async=true"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/clip.mp4");
body.append("text", "Acme Studio");
body.append("position", "bottom-right");
body.append("async", "true");

await fetch("https://convertly.sh/api/media/watermark", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Inspect

curl -X POST "https://convertly.sh/api/media/inspect" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./upload.mov"
const body = new FormData();
body.append("sourceUrl", "https://cdn.example.com/upload.mov");

const res = await fetch("https://convertly.sh/api/media/inspect", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CONVERTLY_API_KEY}` },
  body,
});

Trim

curl -X POST "https://convertly.sh/api/media/trim" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "sourceUrl=https://cdn.example.com/video.mp4" \
  -F "start=12" \
  -F "duration=8" \
  -F "format=mp4" \
  -F "async=true"

Video to GIF

curl -X POST "https://convertly.sh/api/media/gif" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "sourceUrl=https://cdn.example.com/video.mp4" \
  -F "start=2" \
  -F "duration=4" \
  -F "width=480" \
  -F "async=true"

Storyboard

curl -X POST "https://convertly.sh/api/media/storyboard" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "sourceUrl=https://cdn.example.com/video.mp4" \
  -F "frames=12" \
  -F "columns=4" \
  -F "format=jpg" \
  -F "async=true"

Image transform

curl -X POST "https://convertly.sh/api/media/transform" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "sourceUrl=https://cdn.example.com/photo.jpg" \
  -F "width=1200" \
  -F "height=900" \
  -F "fit=cover" \
  -F "format=webp"

Response shapes

Most media tool endpoints return a files array:
{
  "files": [
    {
      "filename": "clip-thumbnail.jpg",
      "mimeType": "image/jpeg",
      "originalSize": 24819034,
      "finalSize": 82419,
      "downloadUrl": "data:image/jpeg;base64,..."
    }
  ]
}
Async job results are available through GET /api/jobs/{id}:
{
  "jobId": "65f3a673-69d6-42cc-8f6b-fc5a21fb5a8e",
  "jobType": "media_tool",
  "status": "completed",
  "results": {
    "files": [
      {
        "filename": "clip-poster.jpg",
        "mimeType": "image/jpeg",
        "downloadUrl": "https://..."
      }
    ]
  }
}
Media inspection returns:
{
  "media": {
    "filename": "clip.mp4",
    "mimeType": "video/mp4",
    "sizeBytes": 24819034,
    "kind": "video",
    "width": 1920,
    "height": 1080,
    "duration": 18.4,
    "streams": []
  }
}