Authenticate. Submit. Receive the result.
A compact reference for integrating Dislify media jobs, quotas, and webhook delivery into a server-side application.
Reference
Exchange an API key
API keys are long-lived account secrets. Exchange one from your server for a developer token before calling protected job routes.
const tokenRes = await fetch("https://api.dislify.com/v1/developers/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
apiKey: process.env.DISLIFY_API_KEY,
}),
})
const { token } = await tokenRes.json()
console.log(token)Reference
Create a compression job
Send multipart form data with the media file and a compression mode. The response returns a job record for asynchronous processing.
import { readFile } from "node:fs/promises"
const fileBytes = await readFile("./video.mp4")
const formData = new FormData()
formData.append(
"file",
new Blob([new Uint8Array(fileBytes)], { type: "video/mp4" }),
"video.mp4",
)
formData.append("compression", "balanced")
const res = await fetch("https://api.dislify.com/v1/jobs", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
},
body: formData,
})
const job = await res.json()
console.log(job.id)
console.log(job.status)Reference
Read job status
Check the job while processing or use webhooks to receive completion and failure events automatically.
const jobId = "job_123"
const res = await fetch(`https://api.dislify.com/v1/jobs/${jobId}`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
})
const job = await res.json()
console.log(job.id)
console.log(job.status)
console.log(job.downloadUrl)
// Tip:
// You do not need to keep polling this endpoint.
// Register a webhook to receive job.completed and job.failed events automatically.Reference
Download a completed output
The download URL is protected. Send the same temporary Bearer token when requesting the file; the route verifies job ownership before streaming bytes from private R2 storage.
import fs from "node:fs"
const downloadRes = await fetch(job.downloadUrl, {
headers: {
Authorization: `Bearer ${token}`,
},
})
if (!downloadRes.ok) {
throw new Error(`Download failed: ${downloadRes.status}`)
}
const bytes = Buffer.from(await downloadRes.arrayBuffer())
fs.writeFileSync(job.outputName || "dislify-output.bin", bytes)Reference
Register and verify webhooks
Store the signing secret when the endpoint is created, verify the raw request body, and route events by the Dislify event header.
const res = await fetch("https://api.dislify.com/v1/developers/webhooks", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
url: "https://your-app.com/api/dislify/webhook",
events: [
"upload.received",
"quota.updated",
"job.completed",
"job.failed",
],
}),
})
const data = await res.json()
console.log(data.webhook.id)
console.log(data.webhook.secret)import crypto from "node:crypto"
import express from "express"
const app = express()
app.use(
express.json({
verify: (req, _res, buf) => {
req.rawBody = buf.toString("utf8")
},
}),
)
const WEBHOOK_SECRET = process.env.DISLIFY_WEBHOOK_SECRET
app.post("/api/dislify/webhook", (req, res) => {
const signature = req.header("X-Dislify-Signature")
const event = req.header("X-Dislify-Event")
const expectedSignature = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(req.rawBody)
.digest("hex")
if (signature !== expectedSignature) {
return res.status(401).json({
error: "Invalid webhook signature",
})
}
if (event === "job.completed") {
console.log("Job completed:", req.body.data)
}
if (event === "job.failed") {
console.log("Job failed:", req.body.data)
}
if (event === "upload.received") {
console.log("Upload received:", req.body.data)
}
if (event === "quota.updated") {
console.log("Quota updated:", req.body.data)
}
return res.json({ received: true })
})
app.listen(3001, () => {
console.log("Webhook server running on port 3001")
})Reference
Default Unlimited API policy
Dislify applies both burst protection and monthly quotas. Completed outputs follow the account retention policy rather than permanent file storage.
60
Job submissions per hour
10,000
Job submissions per month
90 days
Completed-output retention
Reference
Endpoint map
The primary routes used by a standard server-side integration.
/v1/developers/token/v1/developers/token/refresh/v1/jobs/v1/jobs/:id/v1/jobs/:id/download/v1/developers/webhooksKeep credentials server-side
Never expose API keys or webhook secrets in client bundles. Use environment variables and verify webhook signatures against the raw request body.
Ready when you are
Ready to connect the pipeline?
Create an Unlimited account, generate an API key, and submit the first media job from your server.
