furybot

Studio jobs API

Use an images-scoped key — the "Create images key" button on your account page. This is the same card catalogue the studio UI uses, not raw Comfy graphs. For OSS ComfyUI clients, use /comfy instead.

Endpoints

  • GET /api/meta — public cards and capabilities for this deployment
  • POST /api/jobs — enqueue a card (card, prompt, optional uploads)
  • GET /api/jobs — your recent jobs, each in the same shape as a single poll: a finished one carries output_rel and output_url on the same terms as below, and a job with no file yet carries neither. queue_position is not on the list — ask for the one job you are waiting on.
  • GET /api/jobs/{id} — poll status; a finished job carries output_rel, the path of the result relative to the output root, and output_url, the convenience path /api/jobs/{id}/output. output_url is a path on this host, not a signed remote URL — it is absent until there is a file to fetch, and fetching it still needs your key. A job still waiting carries queue_position, its 1-based place among your own queued jobs — not a global position and not an estimated time; it is absent once the job starts. weight is what the job counts as against your per-hour and per-day limits: 1 for a still, more for a clip.
  • GET /api/jobs/{id}/output — the bytes themselves (advertised as output_url, what the studio preview fetches). GET /api/jobs/{id}/file is the same product feature under the older name: same ownership, same bytes. A 404 on one while the other works is a parity bug, not a documented exception. Admin twin: GET /api/admin/jobs/{id}/output (alias /file).

On a chat-only deployment (no image plane), POST /api/jobs returns 501. Chat and /v1 keep working. When a named instance pack is off (GET /api/metacapabilities.stills / video / meme is false), that card is absent from the list and POST /api/jobs with it returns 501 with a stable body: stills generation is not enabled on this deployment, video generation is not enabled on this deployment, or meme generation is not enabled on this deployment. Photo-border is its own card and is not those packs. The same four names are what furyowner toggles at /api/admin/capabilities and what the studio cards honour — a pack is not API-only or UI-only.

Example

curl -sS https://YOUR-HOST/api/meta \
  -H "Authorization: Bearer YOUR_IMAGES_KEY"

curl -sS https://YOUR-HOST/api/jobs \
  -H "Authorization: Bearer YOUR_IMAGES_KEY" \
  -H "Content-Type: application/json" \
  -d '{"card":"generate_image","prompt":"a red bicycle on a hill"}'

curl -sS https://YOUR-HOST/api/jobs/JOB_ID/output \
  -H "Authorization: Bearer YOUR_IMAGES_KEY" -o result.png

Exact card ids come from /api/meta for your host — do not assume every deployment ships the same set.

Calling from a browser

A page served from this same host can call these endpoints directly: it is same-origin, and the preflight allows Authorization and Content-Type, so a bearer token from browser JavaScript works.

A page on another origin cannot. Cross-origin requests are refused, and no header you add on your side changes that — route the call through your own server and have that server hold the key. That is the right shape anyway: a key shipped to a browser on a page you do not control is a key you have published.

Server-side SDKs — Node, Python, Go, curl — are not subject to CORS at all. It is a browser rule, so nothing here applies to them.

Also see