# API authentication, responses and errors

Source: https://docs.coworkies.com/api/authentication/

> Use API key headers, understand scopes and response envelopes, and handle validation, authorization and rate-limit errors.

## Send the key in a header

Use one of these headers for authenticated requests:

```text
X-API-Key: YOUR_API_KEY
```

```text
Authorization: Bearer YOUR_API_KEY
```

The API also accepts `?api_key=`, but prefer headers to keep secrets out of URLs and access history. Store keys server-side and replace any key that is exposed.

## Permissions and key types

| Scope | Use |
|---|---|
| `read` | Read resources covered by the API. |
| `write` | Read and write resources; includes read access. |
| `jobs:read` | Read job listings. |
| `jobs:write` | Create/update jobs through POST and unpublish jobs. |
| `spaces:read` | Read space endpoints. |
| `cities:read` | Read city lookups; broad `read` also covers this. |
| `events:read` | Read event endpoints. |

`cwk_rstr_` keys are read-only; `cwk_live_` keys allow the configured write permissions. A prefix is not a permission grant by itself. The key's configured scopes and space restrictions still apply. A job-write scope alone does not grant every read scope; choose the permissions needed for both setup and writing.

## Response format

Success responses contain `success`, `status` and `data`. The shape of `data` depends on the endpoint: jobs use `data.jobs`, while cities and spaces return arrays.

```json
{
  "success": false,
  "status": 422,
  "error": {
    "code": "validation_error",
    "message": "Validation failed",
    "details": ["Job title is required"]
  }
}
```

`error.details` is not always an array. For rate limits and permission errors it can be an object. Check its type before iterating. Handle network errors and non-JSON responses as well as API errors.

## Fix common errors

| HTTP status | Action |
|---|---|
| `400` | Check JSON syntax and the request format. |
| `401` | Check the key, expiry, revoked status and any IP restrictions. |
| `403` | Check the required scope and whether the job belongs to the key's space. |
| `404` | Check the endpoint or resource identifier. |
| `405` | Use the endpoint's supported HTTP method. |
| `409` | An idempotent request may still be processing; retry after a short delay. |
| `422` | Correct the fields listed in `error.details`. |
| `429` | Wait for `error.details.retry_after_seconds`, then retry with backoff and jitter. |
| `500` | Retry cautiously; include context in a support report without sharing secrets. |

Job write operations are rate-limited per key. The reference gives a fallback of 120 writes per minute, but a key's configured limit takes precedence. Use the returned limit and retry delay rather than assuming a quota.

For retries of **job creation**, reuse an `Idempotency-Key` for the same logical request. The reference documents successful response replay for 24 hours. Use a new key for a different operation. See [Jobs API](https://docs.coworkies.com/api/jobs/) for a complete example.
