Error handling
Use this reference to interpret errors from the Apso platform API and select the appropriate troubleshooting step.
Standard error response
The platform API uses this standard error envelope:
{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}Some guarded endpoints return a richer payload with a machine-readable code and, where relevant, an upgradeUrl. See Entitlement and limit errors.
HTTP status codes
| Status | Meaning on this API |
|---|---|
400 | Malformed request: validation failure, non-integer id on an integer route, or an unknown sort/filter field |
401 | Missing or invalid authentication |
403 | Not permitted: tenant scoping, or an entitlement/limit block |
404 | Resource not found |
429 | A rate or quota was exceeded, such as the AI token budget. |
500 | Unexpected server error |
Malformed request errors (400)
A central filter maps common PostgreSQL request errors to 400:
- Non-integer ID on an integer route, such as
GET /WorkspaceServices/5f097102. - Unknown sort or filter field, such as
GET /ServiceDeployments?sort=status,DESCwhenstatusis not a column.
Malformed identifiers and query fields return 400. Investigate sustained 500 responses as server faults.
Authentication errors (401)
Requests without a valid session or bearer token return 401. Authentication uses Better Auth. Confirm that the Authorization bearer token or session cookie is present and valid. Service API keys with the apso_ prefix authenticate against the deployed service API. See API key management.
Entitlement and limit errors (403)
Plan limits return 403 with a code and an upgradeUrl:
code | When | Extra fields |
|---|---|---|
SERVICE_LIMIT_REACHED | Creating a service past your plan’s maxServices, such as a second service on Free | tier, limit, current |
TEAM_MEMBER_LIMIT_REACHED | Inviting past your plan’s maxTeamMembers (seats = members + pending invites) | tier, limit, current |
ENTITLEMENT_REQUIRED | Using a feature that your tier does not include, such as external AWS or audit logs | entitlement, currentTier |
WORKSPACE_NOT_FOUND | The workspace context couldn’t be resolved | Not applicable |
{
"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"
}To resolve the error, follow the upgradeUrl or free capacity by deleting a service or removing 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 or limit block, such as
SERVICE_LIMIT_REACHED. See Entitlement and limit errors. - A malformed or empty prompt/name.
Read the message shown in the create dialog; it is the server’s message.
Deployment and build failures
Deployment and provisioning run asynchronously. A failed operation sets Build status to Error or Deployment health to Failed. See Understand service status for an explanation of each indicator.
Diagnose: Open the service’s Logs and Deployments sections. Check the deployment status, then retry the deployment after fixing the schema, scaffold, or GitHub connection error.
Troubleshooting checklist
- Read the
codeandmessage: most platform errors are self-describing (SERVICE_LIMIT_REACHED,ENTITLEMENT_REQUIRED,Token limit exceeded). 400? Check the id format and anysort/filterfield names against the entity’s columns.401? Re-authenticate; confirm the bearer/session is attached.403with acode? It’s a plan limit or entitlement: follow theupgradeUrl.429? You’ve hit the token budget; wait for the reset or upgrade.- Deploy failed? Check Logs and Deployments, then confirm the GitHub connection for code-scaffolded services.
Generated services use the same NestJS error envelope. Product-specific validation defines the messages for each service.