Docs / Files, documents and media
Audio and video tools API
Convert, trim, draw a waveform or take a frame, with ffmpeg.
Files in, files out, nothing kept. Each counts as 30 against the rate limit. Needs a free API key once keys are required (see /keys).
https://api.dharun.devNo key needed for most600 units a minute, 3000 with a free keyThis page as MarkdownConvert audio or video
POST/v1/media/convert
To MP3, WAV, OGG (Opus), M4A, FLAC, MP4, WebM or an animated GIF. Options go in the query string, or as form fields when the file is sent as multipart/form-data.
Send: Audio or video ffmpeg can read (MP3, WAV, M4A, OGG, FLAC, MP4, MOV, WebM, MKV...), up to 10 MB; the first 10 minutes are used. Post the file as the request body, or as multipart/form-data. Try it with this sample.
The answer returns the audio itself; errors are JSON as everywhere else.
Model endpoint: it will need a free API key, sent as Authorization: Bearer <key> or X-API-Key. Until the date on API keys it answers without one and says so in the X-Key-Notice header. With a key: 500 model requests a day.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
formatquery, required | What to make. One of: mp3, wav, ogg, m4a, flac, mp4, webm, gif. |
curl
# a sample to try: https://api.dharun.dev/samples/speech.mp3
curl -F "[email protected]" -o speech.wav "https://api.dharun.dev/v1/media/convert?format=wav&utm_medium=docs"JavaScript
// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/media/convert?format=wav&utm_medium=docs", { method: "POST", body: form });
if (!response.ok) throw new Error((await response.json()).error.message);
const file = await response.blob();Python
import requests
files = [("file", open("speech.mp3", "rb"))]
response = requests.post("https://api.dharun.dev/v1/media/convert?format=wav&utm_medium=docs", files=files, timeout=90)
if not response.ok:
raise RuntimeError(response.json()["error"]["message"])
open("speech.wav", "wb").write(response.content)Try it here
Change the values and send the request from your browser. Needs JavaScript.
Cut a clip
POST/v1/media/trim
Keeps the part from start to end. Options go in the query string, or as form fields when the file is sent as multipart/form-data.
Send: Audio or video ffmpeg can read (MP3, WAV, M4A, OGG, FLAC, MP4, MOV, WebM, MKV...), up to 10 MB; the first 10 minutes are used. Post the file as the request body, or as multipart/form-data. Try it with this sample.
The answer returns the audio itself; errors are JSON as everywhere else.
Model endpoint: it will need a free API key, sent as Authorization: Bearer <key> or X-API-Key. Until the date on API keys it answers without one and says so in the X-Key-Notice header. With a key: 500 model requests a day.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
startquery | Seconds, or m:ss. Default 0. |
endquery, required | Seconds, or m:ss. |
formatquery | Output format when the file's own is not one of these. One of: mp3, wav, ogg, m4a, flac, mp4, webm, gif. |
curl
# a sample to try: https://api.dharun.dev/samples/speech.mp3
curl -F "[email protected]" -o speech.mp3 "https://api.dharun.dev/v1/media/trim?start=0&end=1.5&utm_medium=docs"JavaScript
// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/media/trim?start=0&end=1.5&utm_medium=docs", { method: "POST", body: form });
if (!response.ok) throw new Error((await response.json()).error.message);
const file = await response.blob();Python
import requests
files = [("file", open("speech.mp3", "rb"))]
response = requests.post("https://api.dharun.dev/v1/media/trim?start=0&end=1.5&utm_medium=docs", files=files, timeout=90)
if not response.ok:
raise RuntimeError(response.json()["error"]["message"])
open("speech.mp3", "wb").write(response.content)Try it here
Change the values and send the request from your browser. Needs JavaScript.
Waveform picture
POST/v1/media/waveform
Send: Audio or video ffmpeg can read (MP3, WAV, M4A, OGG, FLAC, MP4, MOV, WebM, MKV...), up to 10 MB; the first 10 minutes are used. Post the file as the request body, or as multipart/form-data. Try it with this sample.
The answer returns the image itself; errors are JSON as everywhere else.
Model endpoint: it will need a free API key, sent as Authorization: Bearer <key> or X-API-Key. Until the date on API keys it answers without one and says so in the X-Key-Notice header. With a key: 500 model requests a day.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
widthquery | 100 to 4000. Default 1200. |
heightquery | 40 to 1000. Default 200. |
colorquery | Hex. Default 2563eb. |
curl
# a sample to try: https://api.dharun.dev/samples/speech.mp3
curl -F "[email protected]" -o out.png "https://api.dharun.dev/v1/media/waveform?width=800&height=160&utm_medium=docs"JavaScript
// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/media/waveform?width=800&height=160&utm_medium=docs", { method: "POST", body: form });
if (!response.ok) throw new Error((await response.json()).error.message);
const file = await response.blob();Python
import requests
files = [("file", open("speech.mp3", "rb"))]
response = requests.post("https://api.dharun.dev/v1/media/waveform?width=800&height=160&utm_medium=docs", files=files, timeout=90)
if not response.ok:
raise RuntimeError(response.json()["error"]["message"])
open("out.png", "wb").write(response.content)Try it here
Change the values and send the request from your browser. Needs JavaScript.
A frame from a video
POST/v1/media/thumbnail
Send: Audio or video ffmpeg can read (MP3, WAV, M4A, OGG, FLAC, MP4, MOV, WebM, MKV...), up to 10 MB; the first 10 minutes are used. Post the file as the request body, or as multipart/form-data. Try it with this sample.
The answer returns the image itself; errors are JSON as everywhere else.
Model endpoint: it will need a free API key, sent as Authorization: Bearer <key> or X-API-Key. Until the date on API keys it answers without one and says so in the X-Key-Notice header. With a key: 500 model requests a day.
What you send here is never written to the log, and the answer is not cached.
| Parameter | Description |
|---|---|
atquery | Time, seconds or m:ss. Default 1. |
widthquery | 32 to 3840. Default 640. |
curl
# a sample to try: https://api.dharun.dev/samples/clip.mp4
curl -F "[email protected]" -o out.png "https://api.dharun.dev/v1/media/thumbnail?at=1&utm_medium=docs"JavaScript
// input is an <input type="file"> element
const form = new FormData();
form.append("file", input.files[0]);
const response = await fetch("https://api.dharun.dev/v1/media/thumbnail?at=1&utm_medium=docs", { method: "POST", body: form });
if (!response.ok) throw new Error((await response.json()).error.message);
const file = await response.blob();Python
import requests
files = [("file", open("clip.mp4", "rb"))]
response = requests.post("https://api.dharun.dev/v1/media/thumbnail?at=1&utm_medium=docs", files=files, timeout=90)
if not response.ok:
raise RuntimeError(response.json()["error"]["message"])
open("out.png", "wb").write(response.content)Try it here
Change the values and send the request from your browser. Needs JavaScript.
Using an AI assistant? Connect the MCP server and it can call this API by itself. Want every endpoint on one bench? Open the playground.