Dashboard
API Reference

API reference

Error Reference

All errors follow a consistent JSON structure. Use the code field for programmatic handling and message for human-readable context.

Error response structure

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The field 'jurisdiction' is required.",
    "details": {
      "field": "jurisdiction",
      "issue": "missing_required_field"
    }
  }
}

HTTP status codes

200

OK

Request succeeded. Body contains the result.

201

Created

Resource created successfully.

204

No Content

Success with no response body (e.g. DELETE).

400

Bad Request

Malformed JSON or missing required fields.

401

Unauthorized

Missing or invalid API key.

403

Forbidden

Key does not have the required scope for this action.

404

Not Found

The requested resource does not exist.

409

Conflict

A conflicting resource already exists.

422

Unprocessable Entity

Validation failed — see details in the error body.

429

Too Many Requests

Rate limit exceeded. See Retry-After header.

500

Internal Server Error

Unexpected server error. Contact support if persistent.

503

Service Unavailable

Temporary outage. Check status.policifyai.com.

Error codes

CodeStatusMeaning
UNAUTHORIZED401API key missing, invalid, or revoked
FORBIDDEN403Key does not have the required scope
NOT_FOUND404Resource with the given ID does not exist
VALIDATION_ERROR422One or more fields failed validation
MISSING_FIELD422A required field was not included
INVALID_FIELD422A field has an invalid value or format
RATE_LIMITED429Too many requests in the current window
GENERATION_FAILED500Policy generation encountered an AI error
PLAN_LIMIT_REACHED403Your plan's policy generation quota is exhausted
CLIENT_NOT_FOUND404The specified client_id does not exist
WEBHOOK_ENDPOINT_INVALID422The webhook URL is not reachable or returned non-2xx

Recommended error handling

async function callPolicify(endpoint, options) {
  const res = await fetch(`https://policifyai.com/api/v1${endpoint}`, options)

  if (res.ok) return res.json()

  const { error } = await res.json()

  switch (error.code) {
    case 'RATE_LIMITED':
      const retryAfter = parseInt(res.headers.get('Retry-After') ?? '60')
      await sleep(retryAfter * 1000)
      return callPolicify(endpoint, options) // retry once

    case 'UNAUTHORIZED':
      throw new Error('Invalid API key — check your environment variable')

    case 'PLAN_LIMIT_REACHED':
      throw new Error('Policy quota exhausted — upgrade your plan')

    default:
      throw new Error(`API error ${res.status}: ${error.message}`)
  }
}