Story payload
For completeRunnerJob, each scene often looks like:
"scenes": [
{
"narration": "…",
"durationSeconds": 6,
"imageUrl": "https://…",
"audioUrl": "https://…"
}
]Documentation
Xenonflare Studio is the product you use in the browser. The runner is separate open-source software you install on your own computer or server. It talks to Studio over HTTPS using a unique key you create here — one key per runner. You manage runners only from the Runners page (add, rename, remove). There is no separate public API to create keys outside the app.
Source and instructions live on GitHub. Clone the repository, follow the README to install dependencies, and use published releases when available.
The runner lives in a public repository — star it, report issues, open pull requests, or clone the source. Use Releases when published for packaged downloads; otherwise follow the README on the default branch.
RUNNER_TOKEN (or as the Bearer token in Authorization headers), start the process, and keep it running while you generate shorts in the app.Job endpoints share one HTTPS prefix. Append the function path (for example /leaseRunnerJob). The hosted Studio uses the production API host below (also shown when signed in under Runners).
API base
https://cloud.xenonflare.com
The runner calls these with POST, Content-Type: application/json, and Authorization: Bearer <runnerToken> (the full key from the dashboard).
| Path | Role |
|---|---|
| /leaseRunnerJob | Claim a job (body may be empty). |
| /heartbeatRunnerJob | Body { "projectId" } — extend lease while working. |
| /runnerSignUpload | Body { "projectId", "uploads": [{ "path", "contentType" }] } — returns signed PUT URLs (max 16 per call). |
| /completeRunnerJob | Body { "projectId", "story"?, "videoUrl"? } — at least one of story or videoUrl; if story is set, story.scenes must be a non-empty array. |
| /failRunnerJob | Body { "projectId", "error" } — mark failure; paid jobs may refund a credit when applicable. |
200 with { "leased": false } means no job right now. When leased: true, you receive projectId, leaseExpiresAt, and a project object with fields such as topic, style, voiceId, includeTts.
leaseRunnerJob until you get a job.heartbeatRunnerJob before the lease expires.runnerSignUpload then PUT files to the returned URLs.completeRunnerJob or failRunnerJob.For completeRunnerJob, each scene often looks like:
"scenes": [
{
"narration": "…",
"durationSeconds": 6,
"imageUrl": "https://…",
"audioUrl": "https://…"
}
]