PandaStack

Errors

The exact JSON error bodies the PandaStack API returns, indexed by HTTP status and literal error string.

Every JSON error the API returns is flat. There is one required field, error, holding a human-readable message:

{ "error": "not found" }

Some responses add a detail sibling with a longer explanation:

{ "error": "unauthorized", "detail": "missing bearer token" }

Quota and rate-limit responses add context fields alongside error (for example workspace, tier, limit_per_hr). There is no code field, no nested error object, and no details object.

Branch on the HTTP status, not on the message text. The error string is written for humans and can change; the status is the contract.

Request IDs

The request ID is a response header, not a body field. Every API response carries X-Request-Id. If you send your own X-Request-Id (up to 64 characters), the API reuses it and forwards it to the compute node, so one ID correlates the whole request across services.

capture the request id
curl -sS -D- -o/dev/null https://api.pandastack.ai/v1/sandboxes \
  -H "Authorization: Bearer $PANDASTACK_API_KEY" | grep -i x-request-id

Status codes

HTTPLiteral error stringWhat it meansWhat to do
400git_url is required, name is required, cmd required, invalid json, env must be a string map, idle_timeout_seconds must be >= 60The request body is missing or malformedFix the payload; do not retry unchanged
401unauthorized (with detail: missing bearer token, invalid api token, or jwt required)No credential, an unknown API key, or a token-auth call on a JWT-only routeSend Authorization: Bearer $PANDASTACK_API_KEY; see Authentication
402free quota exceededFree credit is spent; the workspace is pausedAdd a payment method or upgrade — below
402monthly free credit exhaustedSame cap, enforced at the compute node with usage numbers attachedSame fix; the body includes credit_usd and cost_usd_used
402subscription not activeStripe subscription is past_due or canceled; running resources keep running, new creates are refusedUpdate payment; the body carries subscription_status
402org limit reached: your <tier> plan allows <n> org(s). Upgrade to create more.Plan org capUpgrade or reuse an existing org
402seat limit reached: your <tier> plan allows <n> member(s). Upgrade to invite more.Plan seat capUpgrade or remove a member
403account suspendedThe workspace is blocked from creating computeContact support (detail says so)
404not foundUnknown ID, or the resource belongs to another workspaceCheck the ID and your current org — Wrong workspace
404sandbox not found, sandbox not found or not runningThe sandbox ID does not exist on the node handling the requestRe-read GET /v1/sandboxes
404no code deployed yetFunction exists but has never been deployedPOST /v1/functions/{id}/deploy first
409sandbox not running (paused or hibernated) — resume/wake it firstYou called exec (or another guest operation) on a paused sandboxPOST /v1/sandboxes/{id}/resume. Hibernated sandboxes wake automatically
409managed sandbox: delete it from the feature that owns it (Databases or Apps)You called DELETE /v1/sandboxes/{id} on a sandbox owned by an app or databaseDelete the app or database instead
409volume already existsVolume name is takenPick another name
429rate limit: 50 req/burst, 25/sec sustained per workspacePer-workspace token bucket. Retry-After: 1 is setBack off and retry
429hourly create limit exceededToo many creates in the last hour; body has limit_per_hr and used_last_hrWait, or raise the workspace limit
429max sandboxes reachedConcurrent-sandbox cap; body has max and activeDelete idle sandboxes
429workspace resource quota exceededAggregate CPU or memory cap; body has cpu_used/cpu_max/memory_mb_used/memory_mb_maxDelete idle sandboxes or raise the cap
429monthly cpu-seconds quota exceeded, monthly budget exceededA workspace monthly ceiling you set was hitRaise the ceiling or wait for the monthly reset
500Varies — the underlying error textA bug or an unhandled failureRetry once; if it persists, report it with the X-Request-Id
502no available compute nodeNo node could take the request. Under load this is capacityRetry with backoff — below
502agent unreachableA node was chosen but the proxy could not reach itRetry with backoff
507insufficient host memory for sandboxA specific node refused the placement on memory admissionRetry; the scheduler picks again

402: free quota exceeded

The free tier includes $5.40 of credit per month. You get a warning email at 80%. At 100%, compute stops: running resources are paused and creates are refused. Nothing is deleted — your apps, databases, and data stay intact.

The control plane refuses the create before it reaches a node:

{
  "error": "free quota exceeded",
  "detail": "This account has used its free credit. Add a payment method to keep creating sandboxes."
}

Upgrading lifts the pause on the next reconcile, roughly a minute later. You do not need to recreate anything.

A paused app's URL answers 503 with an HTML page (not JSON), plus Retry-After: 3600 and an X-Pandastack-App: suspended header. See App serves 503.

502: no available compute node

Fleet capacity is bounded by memory. When no node can hold a new VM, the create fails at routing time with a plain 502:

{ "error": "no available compute node" }

This is transient. Retry with exponential backoff. If it repeats over minutes, delete sandboxes you are no longer using and contact support — see 502 Bad Gateway on create.

502 here does not mean the API is down. GET /healthz will still return 200 — the failure is placement, not the control plane.

Retrying

There is no retryable flag and no retry_after_sec field. Decide from the status:

  • Retry with backoff: 429, 500, 502, 507. Only 429 from the per-workspace rate limiter sets a Retry-After header (1 second).
  • Do not retry unchanged: 400, 401, 403, 404, 409 — the request or the resource state has to change first.
  • 402 clears when billing is sorted, not on retry.

Creates are not idempotent. Retrying a POST /v1/sandboxes that actually succeeded but whose response you lost will create a second sandbox; list and reconcile rather than blind-retrying.

Reporting a problem

Include the X-Request-Id response header and the resource ID. Those two make a request traceable end to end. Email hello@pandastack.ai, or open an issue at github.com/pandastack-io/pandastack-ai/issues.

For symptom-first debugging, start at Troubleshooting.

On this page