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

# Authentication

> API keys, scopes, and rate limits

## API Keys

All API requests require an API key passed in the `Authorization` header:

```bash theme={null}
Authorization: Bearer mk_<64 hex characters>
```

### Creating an API Key

1. Go to **Settings > API** in the [Mokaru app](https://app.mokaru.ai/settings)
2. Click **Create API key**
3. Give it a name (e.g. "Claude Desktop") and select permissions
4. Copy the key immediately - it's only shown once

<Warning>
  API keys require a **Plus plan**. You can have **1 active key** per account. Revoke the existing key to create a new one.
</Warning>

## Scopes

Each API key has scopes that control what it can access:

| Scope               | Description                                 |
| ------------------- | ------------------------------------------- |
| `jobs:search`       | Search job listings                         |
| `tracker:read`      | Read your applications                      |
| `tracker:write`     | Create and update applications              |
| `profile:read`      | Read your career profile                    |
| `profile:write`     | Update your career profile                  |
| `contacts:read`     | Read your contacts                          |
| `contacts:write`    | Create, update, and delete contacts         |
| `experiences:read`  | Read your work experiences                  |
| `experiences:write` | Create, update, and delete work experiences |
| `education:read`    | Read your education                         |
| `education:write`   | Create, update, and delete education        |
| `skills:read`       | Read your skills                            |
| `skills:write`      | Create, update, and delete skills           |
| `resume:read`       | List and read resumes                       |
| `resume:write`      | Create, update, and delete resumes          |
| `resume:export`     | Export resumes as PDF                       |

If a request requires a scope the key doesn't have, the API returns `403 Forbidden`.

## Rate Limits

Rate limits are **per account** (not per key) using a sliding window:

| Endpoint                              | Limit           |
| ------------------------------------- | --------------- |
| `POST /v1/jobs/search`                | 30 requests/min |
| `POST /v1/tracker/applications`       | 20 requests/min |
| `PATCH /v1/tracker/applications/:id`  | 20 requests/min |
| `GET /v1/tracker/applications`        | 60 requests/min |
| `GET /v1/profile`                     | 30 requests/min |
| `PATCH /v1/profile`                   | 20 requests/min |
| `GET /v1/contacts`                    | 60 requests/min |
| `GET /v1/contacts/:id`                | 30 requests/min |
| `POST /v1/contacts`                   | 20 requests/min |
| `PATCH /v1/contacts/:id`              | 20 requests/min |
| `DELETE /v1/contacts/:id`             | 10 requests/min |
| `GET /v1/experiences`                 | 60 requests/min |
| `GET /v1/experiences/:id`             | 30 requests/min |
| `POST /v1/experiences`                | 20 requests/min |
| `PATCH /v1/experiences/:id`           | 20 requests/min |
| `DELETE /v1/experiences/:id`          | 10 requests/min |
| `GET /v1/education`                   | 60 requests/min |
| `GET /v1/education/:id`               | 30 requests/min |
| `POST /v1/education`                  | 20 requests/min |
| `PATCH /v1/education/:id`             | 20 requests/min |
| `DELETE /v1/education/:id`            | 10 requests/min |
| `GET /v1/skills`                      | 60 requests/min |
| `GET /v1/skills/:id`                  | 30 requests/min |
| `POST /v1/skills`                     | 20 requests/min |
| `PATCH /v1/skills/:id`                | 20 requests/min |
| `DELETE /v1/skills/:id`               | 10 requests/min |
| `DELETE /v1/tracker/applications/:id` | 10 requests/min |
| `GET /v1/resume`                      | 60 requests/min |
| `GET /v1/resume/:id`                  | 30 requests/min |
| `POST /v1/resume`                     | 10 requests/min |
| `PATCH /v1/resume/:id`                | 20 requests/min |
| `DELETE /v1/resume/:id`               | 10 requests/min |
| `POST /v1/resume/:id/export/pdf`      | 5 requests/min  |

Every response includes rate limit headers:

```
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 29
X-RateLimit-Reset: 1710504000000
```

When rate limited, the response includes a `Retry-After` header (in seconds).

## Error Responses

| Status | Meaning                                       |
| ------ | --------------------------------------------- |
| `400`  | Bad request - missing or invalid fields       |
| `401`  | Missing, invalid, expired, or revoked API key |
| `403`  | API key lacks required scope                  |
| `429`  | Rate limit exceeded                           |
| `500`  | Internal server error                         |

All errors return JSON:

```json theme={null}
{
  "error": "Invalid or expired API key"
}
```

## Security

* Keys are **SHA-256 hashed** before storage - plain keys are never stored
* **256-bit entropy** (32 random bytes) - cryptographically secure
* Keys can be **revoked instantly** from Settings
* **Standalone auth** - not tied to your browser session, designed for machine-to-machine access
