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

# Errors & CORS

> HTTP error codes, error response shapes, and cross-origin configuration for the self-hosted CRM API.

## Error responses

When a request fails, the server returns an appropriate HTTP status code with a JSON error body.

### Common status codes

| Status | Meaning |
| - | - |
| `400` | Bad request — malformed JSON, missing required fields, or invalid query parameters. |
| `401` | Unauthorized — no valid session, token, or API key provided. |
| `403` | Forbidden — the authenticated user lacks the required RBAC permission for this action. |
| `404` | Not found — the resource type (`:resource` slug) does not exist, or the specific record ID was not found. |
| `422` | Validation error — the request body failed server-side validation rules. |
| `500` | Internal server error — an unexpected error occurred. |

### Error shape

Most error responses follow this format:

```json theme={null}
{
  "error": "Unauthorized"
}
```

Validation errors may include additional detail:

```json theme={null}
{
  "error": "Validation failed",
  "details": [
    { "field": "email", "message": "must be a valid email address" }
  ]
}
```

### Handling errors

* Check the HTTP status code first for routing (retry logic, user feedback, etc.).
* Read the `error` field for a human-readable description.
* For `403` responses, verify the user's RBAC role includes the required permission (e.g. `records.write` for create/update/delete operations).
* Do not retry `401`, `403`, or `404` errors — these indicate a configuration or permissions issue, not a transient failure.

***

## Public endpoints (no auth required)

These endpoints are accessible without authentication:

| Method | Path | Description |
| - | - | - |
| `GET` | `/` | Service name and basic info. Returns pointers to docs and health endpoints. |
| `GET` | `/health` | Basic health check. |
| `GET` | `/health/ready` | Readiness check (confirms the server and its dependencies are ready to accept requests). |

```bash theme={null}
curl https://your-app.up.railway.app/health
```

***

## CORS and browser clients

If a web application on a **different origin** calls the CRM API (e.g. a frontend at `https://app.yourcompany.com` calling `https://crm.yourcompany.com`), the browser enforces CORS restrictions.

### Configuring allowed origins

Set the `ALLOWED_ORIGINS` environment variable on your BasicsOS server to a comma-separated list of origins:

```bash theme={null}
ALLOWED_ORIGINS=https://app.yourcompany.com,https://admin.yourcompany.com
```

The server will include the appropriate `Access-Control-Allow-Origin` headers for these origins.

### When CORS is not needed

* **Same-origin requests** — if your frontend and API share the same origin, CORS does not apply.
* **Server-to-server requests** — requests made from a backend service using a Personal CRM API token (`Bearer bos_crm_...`) are not subject to CORS.

> [!TIP]
>
> If you are building a server-to-server integration and do not need browser access, you can skip CORS configuration entirely.


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