All API errors follow a consistent JSON format. The HTTP status code indicates the category of error, and the error code provides specific details.
Error Format
Every error response includes an error object with a code and message:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The game name is required"
}
}
HTTP Status Codes
| Status | Meaning | When It Occurs |
|---|---|---|
| 400 | Bad Request | Invalid request data (missing fields, wrong types, etc.) |
| 401 | Unauthorized | Missing or invalid authentication token |
| 403 | Forbidden | Token is valid but you lack permission (e.g., don't own the resource) |
| 404 | Not Found | Resource does not exist (game, asset, component) |
| 409 | Conflict | Action conflicts with current state (e.g., modifying a finalized revision) |
| 413 | Payload Too Large | Request body exceeds size limit or file exceeds storage quota |
| 429 | Too Many Requests | Rate limit exceeded |
| 502 | Bad Gateway | Server error or temporary service issue |
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | No authentication token provided |
INVALID_TOKEN | 401 | Token is malformed or no longer valid |
VALIDATION_ERROR | 400 | Request body has invalid or missing fields |
GAME_NOT_FOUND | 404 | Game does not exist |
ASSET_NOT_FOUND | 404 | Asset does not exist |
COMPONENT_NOT_FOUND | 404 | Component does not exist |
REVISION_FINALIZED | 409 | Cannot modify components or assets in a finalized revision |
PERMISSION_DENIED | 403 | You do not own this resource |
RATE_LIMITED | 429 | Too many requests in this time window |
STORAGE_LIMIT_EXCEEDED | 413 | Your account has reached storage quota |
DERIVATION_FAILED | 400 | Asset image processing failed (invalid image, corrupted file, etc.) |
INVALID_CODE | 400 | Authorization code is invalid or malformed |
CODE_EXPIRED | 400 | Authorization code has expired (valid for 10 minutes) |
REDIRECT_URI_MISMATCH | 400 | Redirect URI does not match registered value |
CLIENT_ID_MISMATCH | 400 | Client ID is invalid or doesn't match the code |
Rate Limits
Rate limits protect the service from abuse. When you exceed a limit, you receive a 429 response with RATE_LIMITED code. The response includes a Retry-After header (in seconds) telling you when to retry.
| Endpoint | Limit | Window | Notes |
|---|---|---|---|
POST /token | 5 | per minute | Per user, across all apps |
POST /presign | 60 | per minute | Asset uploads |
POST /upload-complete | 60 | per minute | Asset completion |
POST /components | 120 | per minute | Single component create |
POST /components/batch | 10 | per minute | Batch create requests |
POST /games | 10 | per hour | Game creation |
Handling Rate Limits
When you receive a 429 response:
- Check the
Retry-Afterheader for the number of seconds to wait - Wait that amount of time
- Retry your request
- Implement exponential backoff for robustness
Example:
async function makeRequestWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After')) || 5;
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
Common Errors and Solutions
VALIDATION_ERROR on game creation
Error: Missing required field name
Solution: Ensure you include the name field in your request:
{
"name": "My Game"
}
INVALID_TOKEN on API request
Error: Your token is invalid or expired
Solution:
- Check that your token is correctly formatted (starts with
pp_) - Verify you're including it in the
Authorization: Bearerheader - If the user revoked the token in Settings, redirect them to authorize again
RATE_LIMITED on batch component create
Error: Too many requests; maximum 10 batch requests per minute
Solution:
- Wait the number of seconds specified in
Retry-After - Reduce request frequency or batch more components per request (up to 200)
- Spread requests over longer time windows
STORAGE_LIMIT_EXCEEDED on asset upload
Error: Account has reached storage quota
Solution:
- Delete unused assets or games
- Contact support to request a higher quota
- Compress or optimize images before uploading
DERIVATION_FAILED on image processing
Error: Image could not be processed
Solution:
- Verify the image is a valid PNG or JPEG
- Check that the file is not corrupted
- Ensure widthPx and heightPx values match the actual image dimensions
- Try re-uploading the asset