Error Handling

Error codes, HTTP status codes, and rate limits for the Playtest Parlor API.

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

StatusMeaningWhen It Occurs
400Bad RequestInvalid request data (missing fields, wrong types, etc.)
401UnauthorizedMissing or invalid authentication token
403ForbiddenToken is valid but you lack permission (e.g., don't own the resource)
404Not FoundResource does not exist (game, asset, component)
409ConflictAction conflicts with current state (e.g., modifying a finalized revision)
413Payload Too LargeRequest body exceeds size limit or file exceeds storage quota
429Too Many RequestsRate limit exceeded
502Bad GatewayServer error or temporary service issue

Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401No authentication token provided
INVALID_TOKEN401Token is malformed or no longer valid
VALIDATION_ERROR400Request body has invalid or missing fields
GAME_NOT_FOUND404Game does not exist
ASSET_NOT_FOUND404Asset does not exist
COMPONENT_NOT_FOUND404Component does not exist
REVISION_FINALIZED409Cannot modify components or assets in a finalized revision
PERMISSION_DENIED403You do not own this resource
RATE_LIMITED429Too many requests in this time window
STORAGE_LIMIT_EXCEEDED413Your account has reached storage quota
DERIVATION_FAILED400Asset image processing failed (invalid image, corrupted file, etc.)
INVALID_CODE400Authorization code is invalid or malformed
CODE_EXPIRED400Authorization code has expired (valid for 10 minutes)
REDIRECT_URI_MISMATCH400Redirect URI does not match registered value
CLIENT_ID_MISMATCH400Client 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.

EndpointLimitWindowNotes
POST /token5per minutePer user, across all apps
POST /presign60per minuteAsset uploads
POST /upload-complete60per minuteAsset completion
POST /components120per minuteSingle component create
POST /components/batch10per minuteBatch create requests
POST /games10per hourGame creation

Handling Rate Limits

When you receive a 429 response:

  1. Check the Retry-After header for the number of seconds to wait
  2. Wait that amount of time
  3. Retry your request
  4. 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:

  1. Check that your token is correctly formatted (starts with pp_)
  2. Verify you're including it in the Authorization: Bearer header
  3. 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:

  1. Wait the number of seconds specified in Retry-After
  2. Reduce request frequency or batch more components per request (up to 200)
  3. Spread requests over longer time windows

STORAGE_LIMIT_EXCEEDED on asset upload

Error: Account has reached storage quota

Solution:

  1. Delete unused assets or games
  2. Contact support to request a higher quota
  3. Compress or optimize images before uploading

DERIVATION_FAILED on image processing

Error: Image could not be processed

Solution:

  1. Verify the image is a valid PNG or JPEG
  2. Check that the file is not corrupted
  3. Ensure widthPx and heightPx values match the actual image dimensions
  4. Try re-uploading the asset