DislifyDislify

Command Palette

Search for a command to run...

API reference

Authenticate. Submit. Receive the result.

A compact reference for integrating Dislify media jobs, quotas, and webhook delivery into a server-side application.

01

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.

auth-token
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)
02

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.

create-job
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)
03

Reference

Read job status

Check the job while processing or use webhooks to receive completion and failure events automatically.

job-status
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.
04

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.

download-output
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)
05

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.

register-webhook
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)
webhook-handler
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")
})
06

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

07

Reference

Endpoint map

The primary routes used by a standard server-side integration.

POST/v1/developers/token
Exchange an API key for an access token
POST/v1/developers/token/refresh
Refresh an authenticated developer token
POST/v1/jobs
Upload media and create a compression job
GET/v1/jobs/:id
Read job state and download information
GET/v1/jobs/:id/download
Download the completed output with the same Bearer token
POST/v1/developers/webhooks
Register a signed webhook endpoint

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