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

# Authentication

> API keys for systems, AuthKit sign-in for people, permissions, errors and rate limits.

Every request belongs to one tenant: the tenant of the key or person making it. There are two kinds of caller.

## API keys

For CRMs, scripts and other systems. A key looks like `pk_live_<prefix>_<secret>`. Send it in either header:

<CodeGroup>
  ```bash X-API-Key theme={null}
  curl "https://api.parser-app.com/v1/jobs" -H "X-API-Key: pk_live_..."
  ```

  ```bash Bearer theme={null}
  curl "https://api.parser-app.com/v1/jobs" -H "Authorization: Bearer pk_live_..."
  ```
</CodeGroup>

* **Create** with `POST /v1/api-keys` (`keys:manage`). The key is returned once; only its prefix and a hash of
  the secret are kept, so a lost key cannot be recovered, only replaced.
* **Scopes** default to `jobs:write jobs:read underwriting:write`. A key can never hold a permission its creator
  lacks. A key can also be given an expiry.
* **Rotate** with `POST /v1/api-keys/{id}/rotate?overlap_seconds=3600`: a new key with the same name and scopes,
  the old one valid for the overlap so your systems can switch without downtime.
* **Revoke** with `DELETE /v1/api-keys/{id}`. Revoked and expired keys are refused with `401`.

## People

People sign in through AuthKit, and their access token is the bearer. The token's organization names the tenant,
and its role (or explicit permissions) sets what they may do:

| Role | Permissions |
| - | - |
| `owner`, `admin` | everything below |
| `underwriter` | `jobs:write` `jobs:read` `jobs:delete` `underwriting:write` `usage:read` |
| `viewer` | `jobs:read` `usage:read` |

## Permissions

| Permission | Allows |
| - | - |
| `jobs:write` | Submit packets and emails |
| `jobs:read` | Read jobs and their results |
| `jobs:delete` | Erase a job and its documents |
| `underwriting:write` | Run the underwriting calculator |
| `webhooks:manage` | Register, rotate and remove webhooks |
| `mailboxes:manage` | Connect and manage mailboxes |
| `integrations:manage` | Install and manage CRM and Slack integrations |
| `keys:manage` | Create, rotate and revoke API keys |
| `settings:manage` | Change the tenant's settings |
| `usage:read` | Read usage, cost and quality reports |
| `audit:read` | Read the audit log |

A missing permission is `403`. `GET /v1/me` shows the caller, its tenant, its permissions and the tenant's
modules. Every change (keys, settings, webhooks, mailboxes, erasures) is written to the audit log, read with
`GET /v1/audit-log`.

## Errors

Every error has the same shape, and the request id is also in the `X-Request-ID` header. Quote it when you
contact support.

```json theme={null}
{"error": {"code": "unauthenticated", "message": "invalid, revoked or expired API key or token", "request_id": "e2a0d3ae..."}}
```

| Status | Meaning |
| - | - |
| `400` / `422` | The request is malformed or a field is invalid; `message` says which. |
| `401` | No credential, or one that is invalid, revoked or expired. |
| `403` | The caller lacks a permission, or the tenant's module for this route is off. |
| `404` | No such resource for this tenant. |
| `409` | An `Idempotency-Key` reused with a different request. |
| `413` | A file, email or attachment over the size limits. |
| `429` | A rate limit, or the tenant's active-job or monthly budget limit. Retry after `Retry-After` seconds. |

## Rate limits

* **Writes** (`POST`, `PATCH`, `DELETE`): 120 a minute per API key or person, and 600 a minute per tenant.
* **Reads**: about 1,200 a minute per caller.
* **Jobs**: at most `max_active_jobs` (20 by default) queued or running per tenant at once.

Beyond a limit the answer is `429` with `Retry-After`.


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