API Get key

StaglightTools

Captions

Burned-in captions with styles, fonts and colors inside the safe zone.

Price
15 crper run
Usual time
≈ 60 s
Model id
edit.captions

Playground

Playground

Video *

Sign in to upload a file.

Audio language

1 - 6

Style

50 - 150

Outline
Shadow
Position
Letters
Sign up to run it

Change the settings: the price and the code follow. You need an account to run it.

edit.captions
Takes
Text, Video

No example of this model yet. These are its real settings.

# 0. Upload your file first and put the id it prints in params.
curl -s -X POST https://staglight.ai/api/v1/uploads \
  -H "Authorization: Bearer $STAGLIGHT_API_KEY" -F file=@your-file | jq -r .id

# 1. Create the job. It is charged once and refunded if it fails.
JOB_ID=$(curl -s -X POST https://staglight.ai/api/v1/jobs \
  -H "Authorization: Bearer $STAGLIGHT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "op": "edit.captions",
    "params": {
      "video": "med_your_upload_id"
    },
    "max_credits": 15
  }' | jq -r .id)

# 2. Poll until it finishes. Each call waits up to 30 seconds.
while :; do
  JOB=$(curl -s "https://staglight.ai/api/v1/jobs/$JOB_ID?wait=30" -H "Authorization: Bearer $STAGLIGHT_API_KEY")
  case "$(echo "$JOB" | jq -r .status)" in queued|running) ;; *) break ;; esac
done

# 3. Download the result from outputs[0].download_url.
echo "$JOB" | jq '.outputs[0].download_url // .data'
import os, uuid, requests

BASE = "https://staglight.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['STAGLIGHT_API_KEY']}"}

# 0. Upload your file first and put the id it prints in params.
with open("your-file", "rb") as f:
    print(requests.post(f"{BASE}/uploads", headers=HEADERS, files={"file": f}, timeout=300).json()["id"])

# 1. Create the job. It is charged once and refunded if it fails.
r = requests.post(f"{BASE}/jobs", timeout=60,
                  headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
                  json={
                    "op": "edit.captions",
                    "params": {
                      "video": "med_your_upload_id"
                    },
                    "max_credits": 15
                  })
r.raise_for_status()
job = r.json()

# 2. Poll until it finishes. Each call waits up to 30 seconds.
while job["status"] in ("queued", "running"):
    job = requests.get(f"{BASE}/jobs/{job['id']}", headers=HEADERS,
                       params={"wait": 30}, timeout=60).json()

# 3. Download the result from outputs[0].download_url.
print(job["outputs"][0]["download_url"] if job["outputs"] else job["data"] or job["error"])
// Node 18 or newer. Save as run.mjs: top-level await needs a module.
const BASE = "https://staglight.ai/api/v1";
const headers = { Authorization: `Bearer ${process.env.STAGLIGHT_API_KEY}` };

// 0. Upload your file first and put the id it prints in params.
// const form = new FormData(); form.append('file', yourFile);
// const { id } = await (await fetch(`${BASE}/uploads`, { method: 'POST', headers, body: form })).json();

// 1. Create the job. It is charged once and refunded if it fails.
let res = await fetch(`${BASE}/jobs`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
  body: JSON.stringify({
    "op": "edit.captions",
    "params": {
      "video": "med_your_upload_id"
    },
    "max_credits": 15
  }),
});
if (!res.ok) throw new Error((await res.json()).error.message);
let job = await res.json();

// 2. Poll until it finishes. Each call waits up to 30 seconds.
while (job.status === "queued" || job.status === "running") {
  job = await (await fetch(`${BASE}/jobs/${job.id}?wait=30`, { headers })).json();
}

// 3. Download the result from outputs[0].download_url.
console.log(job.outputs[0]?.download_url ?? job.data ?? job.error);
{
  "id": "job_19a2b3c4d5e6f7a8b9c0d1",
  "op": "edit.captions",
  "status": "queued",
  "credits": 15,
  "title": "",
  "params": {
    "video": "med_your_upload_id"
  },
  "progress": null,
  "outputs": [],
  "data": null,
  "error": null,
  "run_id": null,
  "source": "api",
  "created_at": "2026-11-06T12:00:00Z",
  "finished_at": null,
  "eta_seconds": 60
}

What it costs

15 cr per run. The settings do not change the price.

The playground shows the exact price for your settings. A job is charged once when it is accepted, and refunded if it fails. The price is checked again with your file before it runs.

Parameters

NameTypeDefaultAllowed
videorequiredVideo media id Video
textCaption text (optional) string Up to 40,000 characters
langAudio language enum auto auto, es, en
words_per_lineWords per line integer 3 1 - 6
presetStyle enum bold bold, minimal, karaoke, subtitle
fontFont enum archivo archivo, anton, bebas, poppins, bangers, archivoblack, kanit, barlow, titillium, titan, bungee, alfaslab, ...
sizeSize (%) integer 100 50 - 150
colorText color string #FFFFFF Up to 7 characters
highlightHighlight color string #FFE600 Up to 7 characters
outlineOutline enum auto auto, off, thin, medium, thick
outline_colorOutline color string #000000 Up to 7 characters
shadowShadow enum auto auto, off, soft, hard
positionPosition enum low low, middle, top, bottom
caseLetters enum as_is as_is, upper

Send these inside params. Files are media ids from POST /api/v1/uploads. View documentation

More models