Documentation

Runner setup

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.

Download the runner

Source and instructions live on GitHub. Clone the repository, follow the README to install dependencies, and use published releases when available.

Open source on GitHub

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.

GitHub starsGitHub forks

https://github.com/Xenon-Flare/runner

Connect with your key

  1. In Studio go to Runners Add runner, pick a display name, and copy the one-time key. You can rename or remove runners anytime from the same page. Keys cannot be shown again after you close the dialog — remove the runner and add a new one if you lose the key.
  2. Copy the API base URL from that page into your runner configuration (the open-source project documents the exact variable name).
  3. Paste the key into the runner as RUNNER_TOKEN (or as the Bearer token in Authorization headers), start the process, and keep it running while you generate shorts in the app.

API base URL

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

Job HTTP API (runner only)

The runner calls these with POST, Content-Type: application/json, and Authorization: Bearer <runnerToken> (the full key from the dashboard).

PathRole
/leaseRunnerJobClaim a job (body may be empty).
/heartbeatRunnerJobBody { "projectId" } — extend lease while working.
/runnerSignUploadBody { "projectId", "uploads": [{ "path", "contentType" }] } — returns signed PUT URLs (max 16 per call).
/completeRunnerJobBody { "projectId", "story"?, "videoUrl"? } — at least one of story or videoUrl; if story is set, story.scenes must be a non-empty array.
/failRunnerJobBody { "projectId", "error" } — mark failure; paid jobs may refund a credit when applicable.

Lease response

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.

Typical loop

  1. Call leaseRunnerJob until you get a job.
  2. Run your local pipeline; call heartbeatRunnerJob before the lease expires.
  3. Upload assets via runnerSignUpload then PUT files to the returned URLs.
  4. Finish with completeRunnerJob or failRunnerJob.

Jobs & credits

  • Shared queue — uses credits; any allowed fleet runner may process (Studio decides routing).
  • Your runners only — free when you choose that option at create time; only runners registered on your account can pick those jobs up.

Story payload

For completeRunnerJob, each scene often looks like:

"scenes": [
  {
    "narration": "…",
    "durationSeconds": 6,
    "imageUrl": "https://…",
    "audioUrl": "https://…"
  }
]