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

# Media Tools API

> Generate thumbnails, previews, watermarks, clean files, and media metadata.

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.

<div className="convertly-callout">
  Pass a multipart `file` for uploads or `sourceUrl` for remote assets. Set `async=true` for heavy work like background removal, long video processing, or large PDF previews. In JavaScript examples, read `CONVERTLY_API_KEY` from `process.env` on your server — never hardcode keys in source files.
</div>

## Input modes

```bash file upload theme={"system"}
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"
```

```bash remote URL theme={"system"}
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"
```

```bash async theme={"system"}
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.

```json theme={"system"}
{
  "jobId": "65f3a673-69d6-42cc-8f6b-fc5a21fb5a8e",
  "status": "pending",
  "tool": "poster-frame"
}
```

## Endpoints

| Tool                 | Endpoint                            | Best for                                                                                                                                     |
| -------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Thumbnail generation | `POST /api/media/thumbnail`         | Image thumbnails and video preview thumbnails.                                                                                               |
| PDF previews         | `POST /api/media/pdf-preview`       | Rendering a PDF page as `jpg`, `png`, `webp`, or `avif`.                                                                                     |
| Image to PDF         | `POST /api/media/image-to-pdf`      | Combining one or more images into a PDF.                                                                                                     |
| Metadata stripping   | `POST /api/media/strip-metadata`    | Removing EXIF, GPS, tags, and container metadata.                                                                                            |
| Poster frames        | `POST /api/media/poster-frame`      | Extracting a video frame for upload previews.                                                                                                |
| Audio extraction     | `POST /api/media/extract-audio`     | Pulling audio from video as `mp3`, `m4a`, `wav`, `ogg`, or `flac`.                                                                           |
| Watermarking         | `POST /api/media/watermark`         | Applying text watermarks to images and videos.                                                                                               |
| Media inspection     | `POST /api/media/inspect`           | Reading dimensions, duration, codecs, file size, streams, and metadata flags.                                                                |
| Trim                 | `POST /api/media/trim`              | Cutting video or audio by start time and duration.                                                                                           |
| Video to GIF         | `POST /api/media/gif`               | Creating short animated previews from video.                                                                                                 |
| Storyboard           | `POST /api/media/storyboard`        | Generating contact sheets from video frames.                                                                                                 |
| Image transform      | `POST /api/media/transform`         | Resizing, cropping, rotating, flipping, and exporting images.                                                                                |
| Background removal   | `POST /api/media/remove-background` | Removing image backgrounds and returning transparent PNG or WebP output. Use the `model` parameter for finer edge quality on hair and glass. |

## Examples

### Thumbnail

```bash theme={"system"}
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"
```

```js theme={"system"}
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,
});

const result = await res.json();
```

### PDF preview

```bash theme={"system"}
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"
```

```js theme={"system"}
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

```bash theme={"system"}
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"
```

```js theme={"system"}
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

```bash theme={"system"}
curl -X POST "https://convertly.sh/api/media/strip-metadata" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./photo.jpg"
```

```js theme={"system"}
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

```bash theme={"system"}
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"
```

```js theme={"system"}
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

```bash theme={"system"}
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"
```

```js theme={"system"}
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

```bash theme={"system"}
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"
```

```js theme={"system"}
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

```bash theme={"system"}
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"
```

```js theme={"system"}
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

```bash theme={"system"}
curl -X POST "https://convertly.sh/api/media/inspect" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -F "file=@./upload.mov"
```

```js theme={"system"}
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

```bash theme={"system"}
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

```bash theme={"system"}
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

```bash theme={"system"}
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

```bash theme={"system"}
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:

```json theme={"system"}
{
  "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}`:

```json theme={"system"}
{
  "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:

```json theme={"system"}
{
  "media": {
    "filename": "clip.mp4",
    "mimeType": "video/mp4",
    "sizeBytes": 24819034,
    "kind": "video",
    "width": 1920,
    "height": 1080,
    "duration": 18.4,
    "streams": []
  }
}
```
