Developer documentation

Convert PDF, image, video and audio files via API

Add file conversion to your own product. Authenticate with a registered-user API key and POST your file — the response is the converted file (or, for video editor renders, a job id you poll).

Quick start

  1. 1. Sign upCreate an account on the website. API keys are registered-user only.
  2. 2. Mint a keyOpen /account and click Create new key. Copy the plaintext shown once.
  3. 3. Call the APISend Authorization: Bearer YOUR_KEY on every request.
# Convert PDF -> JPG and save the result
curl -X POST https://your-domain.com/api/tools/pdf-to-jpg \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -o pages.zip

All samples use https://your-domain.com as the base URL — replace it with your own deployment.

Authentication

Every request must carry your API key in either header:

Authorization: Bearer yk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: yk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Keys are tied to your account; uploads count against your storage limits (3 GB per file for registered users).
  • The plaintext key is shown only once at creation; revoke and re-mint if you lose it.
  • Keep keys server-side. The browser sample is for trusted internal tools only.
  • Invalid or revoked keys return 401 Unauthorized.

Endpoints

All endpoints are POST and accept multipart/form-data. The single-input tools take a field named file; multi-input tools (image-compression, pdf-merge) take repeating files fields. Most return the converted file directly; the video editor returns a job id you poll.

PDF

Convert from / to PDF, plus split / merge / compress.

EndpointInputOutput
/api/tools/pdf-to-jpgPDFZIP of JPG (one per page)
/api/tools/pdf-to-wordPDFDOCX
/api/tools/pdf-to-powerpointPDFPPTX
/api/tools/pdf-to-excelPDFXLSX
/api/tools/pdf-to-htmlPDFHTML
/api/tools/pdf-splitPDF + rangesZIP of split PDFs
/api/tools/pdf-mergeMultiple PDFsMerged PDFsend each file as field name `files`
/api/tools/pdf-compressPDFCompressed PDF

Office & Web → PDF

Documents to PDF.

EndpointInputOutput
/api/tools/word-to-pdfDOCX / DOCPDF
/api/tools/powerpoint-to-pdfPPTX / PPTPDF
/api/tools/excel-to-pdfXLSX / XLSPDF
/api/tools/html-to-pdfHTMLPDF
/api/tools/jpg-to-pdfJPG / PNG (one or many)PDF

Image

Compress and convert images.

EndpointInputOutput
/api/tools/image-compressionJPG / PNG / WebP (one or many, field `files`)JSON with download URLsOptional form fields: mode=lossy|custom, jpg_quality, png_quality, webp_quality, width, height, resize_to_fit
/api/tools/jpg-to-pngJPGPNG

Video

Convert, trim, transcribe, and edit video.

EndpointInputOutput
/api/tools/video-to-videoVideo + target_formatConverted videotarget_format e.g. mp4 / webm / mov
/api/tools/video-to-audioVideo + target_formatAudio filetarget_format e.g. mp3 / m4a / wav
/api/tools/video-to-gifVideoAnimated GIF
/api/tools/video-to-textVideoJSON transcript
/api/tools/video-cutterVideo + start + endTrimmed video
/api/tools/online-video-editor/exportJSON project + media filesJob id (poll for MP4)Async: see the dedicated section below

Audio

Trim and cut audio.

EndpointInputOutput
/api/tools/audio-cutterAudio + start + endTrimmed audio

Async jobs (online video editor)

The online video editor renders multi-clip projects in the background. POST the project JSON plus each referenced media file as media_<assetId>; you get back a job id. Poll until status is completed, then download the rendered MP4.

import json, time, requests

API_BASE = "https://your-domain.com"
API_KEY  = "YOUR_API_KEY"
HEADERS  = {"Authorization": f"Bearer {API_KEY}"}

project = {
    "settings":   {"width": 1280, "height": 720, "fps": 30, "duration": 4.0},
    "assets":     [{"id": "clip1", "src": "input.mp4", "kind": "video"}],
    "videoClips": [{"id": "v1", "assetId": "clip1", "track": 0,
                    "timelineStart": 0, "sourceStart": 0, "sourceEnd": 4}],
    "audioClips": [], "textClips": [],
}

# 1. Submit
with open("input.mp4", "rb") as fh:
    res = requests.post(
        f"{API_BASE}/api/tools/online-video-editor/export",
        headers=HEADERS,
        data={"project": json.dumps(project)},
        files={"media_clip1": ("input.mp4", fh, "video/mp4")},
        timeout=600,
    )
res.raise_for_status()
job_id = res.json()["jobId"]

# 2. Poll
while True:
    job = requests.get(
        f"{API_BASE}/api/tools/online-video-editor/export/{job_id}",
        headers=HEADERS, timeout=30,
    ).json()
    print("status", job["status"], "progress", job.get("progress"))
    if job["status"] in ("completed", "failed"):
        break
    time.sleep(2)

if job["status"] != "completed":
    raise RuntimeError(job.get("error") or "render failed")

# 3. Download
out = requests.get(
    f"{API_BASE}/api/tools/online-video-editor/export/{job_id}/download",
    headers=HEADERS, timeout=600,
)
with open("output.mp4", "wb") as f:
    f.write(out.content)

The status payload includes progress (0–1), savedToLibrary, and bunnyOutput with the CDN URL once stored.

Limits & storage

AspectAnonymous (no key)With API key
Per-file upload size300 MB3 GB
StorageTemporary; cleaned up automaticallySaved to your media library on Bunny CDN
ConcurrencyShared queue (max 500 pending jobs)Same — design for retries on 429

Errors

Errors are JSON with a detail field describing what went wrong.

StatusMeaning
400Bad input — unsupported file type, missing field, file empty, or exceeds size limit.
401Missing, invalid, or revoked API key.
409Async job not yet complete — keep polling the status endpoint.
429Conversion queue is saturated — retry after a short delay.
503Worker pool unavailable; retry with exponential backoff.

Ready to integrate?

Mint your first API key and start converting in minutes.

Get an API key