Skip to Content
Error Handling

Error Handling

All PickLayer API errors follow a consistent envelope format with HTTP status codes and typed error messages.

Error Response Format

{ "code": 400, "message": "Messages array is required and must not be empty", "type": "VALIDATION", "data": { "field": "messages" } }
FieldDescription
codeHTTP status code
messageHuman-readable error description
typeError category (see table below)
dataAdditional context (field names, limits, etc.)

Error Types

HTTPTypeMeaning
400VALIDATIONJSON schema violation or missing required fields
401AUTHENTICATIONAccess token invalid or expired
402PAYMENT_REQUIREDInsufficient funds, cap exceeded, or billing issue
403FORBIDDENSuspended user or forbidden route
404NOT_FOUNDOrganization, application, or resource not found
409CONFLICTDuplicate handler, idempotency mismatch
429QUOTARate limit or spend ceiling exceeded
5xxSERVER_ERRORProvider failure or internal error

Billing Error Codes

When billing validation fails, the data field includes a specific reason code:

ReasonHTTPDescription
NOT_FUNDED402User plan assignment is not funded
FUNDING_MODE_INACTIVE400Funding mode is not active
PERIOD_INACTIVE400Billing period outside start/end dates
PERIOD_INVALID400Billing period start or end date is missing
CAP_NOT_SET400Plan has no monthly cost cap configured
CAP_EXCEEDED402User has exceeded their monthly cost cap
POOL_EXHAUSTED402Organization/app pool has insufficient credits
INSUFFICIENT_FUNDS402Insufficient funds in wallet
PRICING_RATE_NOT_FOUND404No pricing rate found for model
ASSIGNMENT_NOT_FOUND404User plan assignment not found

Rate Limiting (429)

When rate limits are exceeded, the response includes retry information:

{ "code": 429, "message": "Rate limit exceeded", "type": "QUOTA", "data": { "limitType": "requests_per_minute", "limitValue": 60, "currentValue": 61, "retryAfterSeconds": 45 } }

The Retry-After HTTP header is also set with the number of seconds to wait.

Provider Errors

When an upstream AI provider returns an error, PickLayer wraps it:

{ "code": 502, "message": "Provider returned error: rate limit exceeded", "type": "SERVER_ERROR", "data": { "provider": "openai", "providerError": "Rate limit exceeded. Please retry after 20 seconds." } }

Best Practices

  1. Always check type for programmatic error handling
  2. Use data.field in validation errors to highlight specific input issues
  3. Respect Retry-After headers for rate limit errors
  4. Log request_id from response headers for debugging with support
Last updated on