> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uptimeio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> The error format, the error codes you can receive, and how to handle them

Every failed API request returns a non-2xx HTTP status and a JSON body with an error `code` you can program against and a human-readable `message`.

## Error response format

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed: interval_seconds: Interval must be at least 30 seconds"
  }
}
```

| Field | Type | Description |
| - | - | - |
| `success` | boolean | Always `false` for errors. |
| `error.code` | string | Stable, machine-readable code. Branch on this, not on `message`. |
| `error.message` | string | Human-readable explanation. Wording can change. |
| `error.details` | object or array | Optional extra context, omitted when there is none. Its shape depends on the error: an object for most errors, a list of entries when a request body fails schema validation. |

<Note>
  A request to a path that does not exist returns `404` with the body `{ "error": "Not Found", "path": "/api/..." }`. This one response does not use the `success` / `error.code` envelope, so check the path and method first if you see it.
</Note>

## HTTP status codes

| Status | Meaning |
| - | - |
| `400` | The request is malformed or fails validation. |
| `401` | Missing or invalid credentials. |
| `403` | Authenticated, but not allowed (role, read-only key, plan limit, unverified email). |
| `404` | The resource does not exist or is not visible to you. |
| `409` | The resource already exists or conflicts with current state. |
| `429` | You exceeded the rate limit. |
| `500` | Unexpected server error. Safe to retry with backoff. |
| `503` | Temporarily unavailable. Retry with backoff. |

## Error codes

Endpoint pages list the codes that are specific to them. The codes below can occur across the API.

### Authentication (401)

| Code | Meaning | What to do |
| - | - | - |
| `MISSING_AUTH` | No `Authorization` or `X-API-Key` header. | Send one. See [Authentication](/api-reference/authentication). |
| `MISSING_API_KEY` | `X-API-Key` header is empty. | Send the key. |
| `INVALID_API_KEY` | Unknown, malformed or revoked key. | Check the key; create a new one if needed. |
| `INVALID_TOKEN`, `TOKEN_EXPIRED` | Session token is invalid or expired. | Sign in again (dashboard sessions). |
| `AUTHENTICATION_REQUIRED` | The endpoint needs an authenticated user. | Authenticate and retry. |

### Permissions and plan (403)

| Code | Meaning | What to do |
| - | - | - |
| `READ_ONLY_API_KEY` | A `read` key attempted a write. | Use a `read_write` key. |
| `JWT_REQUIRED` | The endpoint accepts session tokens only. | Use the dashboard, or pick an API-key-enabled endpoint. |
| `EMAIL_NOT_VERIFIED` | The account email is not verified. | Verify the email address in the dashboard. |
| `INSUFFICIENT_PERMISSIONS`, `FORBIDDEN` | Your role does not allow this action. | Ask an organization admin. |
| `ORGANIZATION_MISMATCH`, `PROJECT_ORGANIZATION_MISMATCH`, `API_KEY_ORGANIZATION_MISMATCH` | The resource belongs to a different organization than the credential. | Use a credential from the owning organization. |
| `MONITOR_LIMIT_REACHED` | Your plan's monitor limit is reached. | Delete monitors or upgrade. See [Plans](/billing/plans). |
| `INTERVAL_TOO_SHORT` | The interval is below your plan's minimum (Free 300 s, Pro and Scale 60 s). | Use a longer interval or upgrade. |
| `PLAN_LIMIT_EXCEEDED` | A plan limit that a higher plan raises was reached (for example Free's single status page or single project). | Upgrade your plan. |
| `INSUFFICIENT_PLAN` | The feature needs a higher plan. | Upgrade your plan. |
| `FAIR_USE_LIMIT_REACHED` | A fair-use ceiling that applies to every plan was reached. Upgrading does not raise it. | Reduce usage and retry. |

### Validation (400)

| Code | Meaning |
| - | - |
| `VALIDATION_ERROR` | The body, query string or path parameters failed validation. `details` explains which fields. |
| `VALIDATION_FAILED` | A validation rule specific to an endpoint failed (for example heartbeat settings on monitor creation). |
| `INVALID_INPUT`, `BAD_REQUEST`, `JSON_PARSE_ERROR` | The request is malformed or not valid JSON. |

### Not found and conflicts (404, 409)

| Code | Meaning |
| - | - |
| `RESOURCE_NOT_FOUND` | The resource does not exist. The message is the resource name followed by `not found` (for example `Incident not found`, `Status page not found`, `Group not found`), and `details.resourceType` holds the resource name. |
| `PROJECT_NOT_FOUND`, `ORGANIZATION_NOT_FOUND` | The project or organization does not exist. |
| `RESOURCE_ALREADY_EXISTS`, `CONFLICT` | The resource already exists or conflicts with current state. |
| `SLUG_ALREADY_TAKEN` | The status page subdomain or slug is taken. |

### Rate limiting (429)

| Code | Meaning |
| - | - |
| `RATE_LIMIT_EXCEEDED` | More than 1,000 requests in 15 minutes for this user (or IP). |

```json theme={null}
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests, please try again later",
    "retryAfter": 60
  }
}
```

The response also has a `Retry-After` header (seconds). Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (Unix seconds). The limit is the same on every plan.

### Server errors (5xx)

| Code | Status | Meaning |
| - | - | - |
| `INTERNAL_ERROR` | 500 | Unexpected error. |
| `DATABASE_ERROR` | 500 | A storage operation failed. |
| `SERVICE_UNAVAILABLE` | 503 | Temporarily unavailable. |

## Handling errors

Check the `success` flag and branch on `error.code`:

```javascript theme={null}
async function call(path, options = {}) {
  const response = await fetch(`https://api.uptimeio.com${path}`, {
    ...options,
    headers: {
      'X-API-Key': process.env.UPTIMEIO_API_KEY,
      'Content-Type': 'application/json',
      ...options.headers,
    },
  });
  const body = await response.json();

  if (body.success) return body.data;

  const { code, message, details } = body.error;
  switch (code) {
    case 'VALIDATION_ERROR':
      console.error('Fix the request:', details);
      break;
    case 'RATE_LIMIT_EXCEEDED':
      // Wait for the window to reset, then retry
      await new Promise((r) => setTimeout(r, Number(response.headers.get('Retry-After') ?? 60) * 1000));
      return call(path, options);
    case 'MISSING_API_KEY':
    case 'INVALID_API_KEY':
      console.error('Check UPTIMEIO_API_KEY');
      break;
    default:
      console.error(`${code}: ${message}`);
  }
  throw new Error(`${code}: ${message}`);
}
```

### Retry server errors with backoff

Retry `500` and `503` (and `429` after `Retry-After`). Do not retry other `4xx` errors: the same request will fail again.

```javascript theme={null}
async function callWithRetry(path, options, maxRetries = 3) {
  for (let attempt = 0; ; attempt++) {
    const response = await fetch(`https://api.uptimeio.com${path}`, {
      ...options,
      headers: { 'X-API-Key': process.env.UPTIMEIO_API_KEY, ...options?.headers },
    });
    if (response.status < 500 || attempt >= maxRetries) return response;
    await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
  }
}
```

## Debugging tips

<AccordionGroup>
  <Accordion title="Reproduce with curl" icon="terminal">
    ```bash theme={null}
    curl -v https://api.uptimeio.com/api/monitors \
      -H "X-API-Key: YOUR_API_KEY"
    ```

    `-v` shows the status code and rate limit headers.
  </Accordion>

  <Accordion title="Read the details" icon="magnifying-glass">
    For `VALIDATION_ERROR`, `message` or `details` names the failing fields. `PLAN_LIMIT_EXCEEDED` and `INSUFFICIENT_PLAN` include the limit or required plan in `details`.
  </Accordion>

  <Accordion title="Read the request ID" icon="hashtag">
    Every response has an `X-Request-ID` header that identifies the request.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.