Skip to Content
APSO is in public beta. Get started
ManageError Handling

Error Handling

How the Apso platform API reports errors, the errors you are most likely to hit, and how to resolve them. Error shapes here are the ones the platform server actually returns.

Standard error response

The platform API is NestJS-based, so errors follow the standard envelope:

{ "statusCode": 400, "message": "…", // string, or an array of strings for validation errors "error": "Bad Request" }

Some guarded endpoints return a richer payload with a machine-readable code and, where relevant, an upgradeUrl — see the entitlement and limit errors below.

HTTP status codes

StatusMeaning on this API
400Malformed request — validation failure, non-integer id on an integer route, or an unknown sort/filter field
401Missing or invalid authentication
403Not permitted — tenant scoping, or an entitlement/limit block
404Resource not found
429Rate/quota exceeded — e.g. the AI token budget
500Unexpected server error

Malformed requests → 400

A central filter maps common Postgres request errors to 400 (instead of leaking a 500):

  • Non-integer id on an integer route — e.g. GET /WorkspaceServices/5f097102.
  • Unknown sort/filter field — e.g. GET /ServiceDeployments?sort=status,DESC where status isn’t a column.

Only these narrow, clearly-malformed cases become 400. Genuine server faults still surface as 500, so a sustained 500 is a real bug, not a bad request.

Authentication → 401

Requests without a valid session/bearer are rejected with 401. Authentication uses BetterAuth; ensure the Authorization bearer (or session cookie) is present and current. Service API keys (apso_…) authenticate against the deployed service API, not the platform API — see API Key Management.

Entitlement & limit errors → 403

Plan limits return 403 with a code and an upgradeUrl:

codeWhenExtra fields
SERVICE_LIMIT_REACHEDCreating a service past your plan’s maxServices (e.g. a 2nd service on Free)tier, limit, current
TEAM_MEMBER_LIMIT_REACHEDInviting past your plan’s maxTeamMembers (seats = members + pending invites)tier, limit, current
ENTITLEMENT_REQUIREDUsing a feature your tier lacks (e.g. external AWS, audit logs)entitlement, currentTier
WORKSPACE_NOT_FOUNDThe workspace context couldn’t be resolved
{ "statusCode": 403, "error": "Forbidden", "code": "SERVICE_LIMIT_REACHED", "message": "Your free plan allows 1 service. Upgrade to create more.", "tier": "free", "limit": 1, "current": 1, "upgradeUrl": "/billing/upgrade" }

Resolution: upgrade the plan (the upgradeUrl), or free up capacity (delete a service, remove a member). See Service Settings.

Quota errors → 429

AI features enforce a per-workspace token budget. Exhausting it returns 429:

{ "error": "Token limit exceeded", "message": "You have exceeded your monthly token limit. Please upgrade your plan.", "usage": { "tokensUsed": 25000, "tokenLimit": 25000, "percentage": 100 } }

The budget resets on a rolling monthly window; it also applies before an AI plan or phase runs, so a blocked request never partially executes.

Service creation errors

The create flow surfaces the API’s error message directly. Common causes:

  • An entitlement/limit block (e.g. SERVICE_LIMIT_REACHED) — see above.
  • A malformed or empty prompt/name.

Read the message shown in the create dialog; it is the server’s message.

Deployment & build failures

Deployment and provisioning are asynchronous. Failure surfaces as the service’s build status = Error (red badge) or a deployment health of Failed. See Service List for how those indicators differ.

Diagnose: open the service’s Logs and Deployments sections, check the build/deploy status, and retry the deploy after fixing the cause (often a schema/scaffold error or a missing GitHub connection for code-scaffolded deploys).

Troubleshooting checklist

  1. Read the code and message — most platform errors are self-describing (SERVICE_LIMIT_REACHED, ENTITLEMENT_REQUIRED, Token limit exceeded).
  2. 400? Check the id format and any sort/filter field names against the entity’s columns.
  3. 401? Re-authenticate; confirm the bearer/session is attached.
  4. 403 with a code? It’s a plan limit or entitlement — follow the upgradeUrl.
  5. 429? You’ve hit the token budget; wait for the reset or upgrade.
  6. Deploy failed? Check Logs + Deployments; confirm the GitHub connection for code-scaffolded services.

This documents the platform API’s error behavior as implemented. Application-specific error catalogs (per generated service) follow the same NestJS envelope but define their own validation messages.

Last updated on