Skip to content

Reference

Error Handling

Response envelope format, HTTP status codes, common errors, and retry strategies.

Every PacSpace API response follows a consistent envelope format. This page covers the response structure, status codes, common errors, and how to implement retries.


Response Envelope

Success

json
{
  "statusCode": 200,
  "data": {
    "...": "response payload"
  }
}

Error

json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation failed: 'items' must be a non-empty array."
}

All responses include a statusCode field. Successful responses contain a data field. Error responses contain error and message fields.


HTTP Status Codes

CodeMeaningWhen It Happens
200OKRequest succeeded
201CreatedResource created successfully
202AcceptedRequest accepted for async processing (writes, facts)
400Bad RequestInvalid request body, missing fields, or validation failure
401UnauthorizedMissing, invalid, or expired authentication
402Payment RequiredInsufficient credits to complete the operation
403ForbiddenValid auth but insufficient permissions
404Not FoundResource doesn't exist
409ConflictResource already exists or state conflict
422Unprocessable EntityRequest is well-formed but semantically invalid
429Too Many RequestsRate limit exceeded
500Internal Server ErrorSomething went wrong on our end
502Bad GatewayUpstream service temporarily unavailable
503Service UnavailablePacSpace is temporarily down for maintenance

Common Errors

ErrorStatusCauseFix
Invalid API key401The X-Api-Key header is missing or malformedCheck your API key format: pk_{env}_{id}.{secret}
API key disabled401The key has been toggled offRe-enable the key in the dashboard
JWT expired401The dashboard access token has expiredLog in again to get a new token
Insufficient credits402Your credit balance is too lowTop up credits in the dashboard
Validation failed400Required fields are missing or invalidCheck the error message for specific field details
Record not found404The record key or resource ID doesn't existVerify the key/ID is correct
Environment not provisioned403You haven't activated the required environmentProvision it via POST /dashboard/contracts/provision
Rate limit exceeded429Too many requests in a short periodImplement exponential backoff (see below)
Internal server error500An unexpected error occurredRetry with backoff; contact support if persistent

Rate Limits

PacSpace applies rate limits per API key to ensure fair usage:

TierRequests per secondBurst
Sandbox10 req/s20
Production100 req/s200
EnterpriseCustomCustom

When rate limited, the response includes a Retry-After header indicating how many seconds to wait.


Retry Strategy

For transient errors (429, 500, 502, 503), implement exponential backoff with jitter:

javascript
async function fetchWithRetry(url, options, maxRetries = 5) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);

      // Don't retry client errors (except 429)
      if (response.ok) {
        return response.json();
      }

      if (response.status === 429 || response.status >= 500) {
        const retryAfter = response.headers.get('Retry-After');
        const baseDelay = retryAfter
          ? parseInt(retryAfter, 10) * 1000
          : Math.min(1000 * Math.pow(2, attempt), 30000);

        // Add jitter: ±25% randomization
        const jitter = baseDelay * 0.25 * (Math.random() * 2 - 1);
        const delay = Math.max(0, baseDelay + jitter);

        console.log(`Retry ${attempt + 1}/${maxRetries} in ${Math.round(delay)}ms`);
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }

      // Non-retryable error
      const error = await response.json();
      throw new Error(`PacSpace ${response.status}: ${error.message}`);

    } catch (err) {
      if (attempt === maxRetries - 1) throw err;

      // Network errors are retryable
      const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

Retry Rules

StatusRetry?Strategy
400NoFix the request
401NoFix authentication
402NoTop up credits
403NoCheck permissions
404NoCheck the resource ID
429YesUse Retry-After header
500YesExponential backoff
502YesExponential backoff
503YesExponential backoff

Best Practices

  1. Always check statusCode — Don't assume success based on HTTP status alone
  2. Log error responses — The message field contains actionable details
  3. Implement retries for 5xx — Transient errors resolve quickly
  4. Respect rate limits — Use the Retry-After header when present
  5. Set reasonable timeouts — 30 seconds for writes, 10 seconds for reads
  6. Monitor 402 errors — Set up balance alerts to avoid credit exhaustion
Was this page helpful?

Last updated February 11, 2026