Skip to main content
◆ FORGE · errors
Errors return a JSON body with a detail message:
detail is a string on every hand-raised error. The one exception is 422 (request-body validation), where FastAPI returns detail as an array of {loc, msg, type} records naming exactly which field failed.

Status codes

401: authentication

Every forge API call takes Authorization: Bearer <access token> (your Supabase session token). Missing or unverifiable tokens get 401 with authentication required, invalid or expired session, or invalid token, re-authenticate and retry. When the auth backend is down or rate-limited, you get 503 auth check failed instead: that’s a retry condition, not a “sign in again.”

402: insufficient credits

Only deliver can return it:
N is the number of not-yet-billed kept episodes entering this delivery. The debit is atomic and refused whole, nothing changed: no credits moved, no export started, the kept set is untouched. Top up and retry the exact same call; it will bill the same set once. The colon-separated fields come after the token, never before it, so matching on the insufficient_credits prefix keeps working. The two pointers are there for headless callers with no UI to fall back on: packs lists what you can buy, checkout opens the purchase.

403: forbidden surfaces

Three doors are closed by design, not by accident:
  • The direct job API (POST /api/aug/datasets, POST /api/aug/jobs) is a dev/studio surface. On auth-enforcing deployments (forge.alakazam.gg) it would run real renders and export them with no billing, so it answers 403 the direct job API is disabled on this deployment. Campaigns are the door.
  • Campaign job artifacts outside the review allowlist. The files route on a campaign’s run serves what review needs, clips, gate series, stills. Everything else under the job dir is the deliverable, so it answers 403 this artifact ships in the campaign's delivered export. Deliver, then download the archive.
  • Publishing to a Hugging Face namespace not on the server’s allowlist. Export locally instead, or ask us to enable your namespace.

404: tenancy reads as not-found

404 deliberately covers two cases you can’t tell apart: an id that doesn’t exist, and an id that belongs to another account. Campaigns, jobs, and episode names are all owner-scoped this way. If a request that worked yesterday now 404s, check which account’s token you’re sending before assuming the resource is gone.

409: right call, wrong moment

Each 409 names a specific state; each has one move:

503: fail closed

The forge refuses rather than guesses. If the billing backend is unreachable at deliver time, delivery refuses (billing check failed, try again) instead of exporting unledgered data. If the auth backend is unreachable, calls refuse instead of pooling you into someone else’s tenant. If a dataset read is temporarily unavailable, listings say so instead of returning an empty page. In every case nothing changed on your campaign, wait a moment and retry the same call.

Additions found in adversarial review

  • 502: dataset registration can fail upstream (opening a sample or creating a campaign while the dataset host is unreachable). Retryable.
  • 500: POST …/proposals surfaces a mining crash as mining failed. Report it; re-running after a health recompute usually clears it.
  • More 409s: switching target class before health has computed; a chunk upload whose sha256 doesn’t match its manifest entry; completing an upload twice; completing an upload with missing chunks (this last one is the single place detail is an object ({error, missing}) so tooling can list the gaps).
  • A fourth 403 door: /api/workbench/admin/* (usage, comp grants) is operator-only, admin only for everyone else.