# Аутентификация

Каждый запрос аутентифицируется одним **API-ключом**. Вы отправляете его как заголовок
`X-API-Key` — без танцев с OAuth, без обмена токенами.
**Область действия API-ключа:** API-ключ даёт доступ только к **сервису загрузки PDF** — эндпоинтам
`/api/v1/upload-service/*` (загрузка, статус задачи, скачивание, удаление). Это вся публичная
поверхность обработки.

## Создание API-ключа

Обычный способ получить ключ — **портал Accessful**: войдите, откройте **API-ключи** и
создайте ключ. Ключ показывается **один раз** при создании — скопируйте его немедленно. Мы
храним только хеш, поэтому больше никогда не сможем его показать.

Ключ выглядит так:

```
ak_oCe4cm015zL8vCbBne_wUZDcM6G1RWqD7Ekc2944EAA
```

- Префикс `ak_`, за которым следуют 43 безопасных для URL символа.
- На один аккаунт допускается до **10 активных ключей**.
- Ключ может необязательно иметь **дату истечения**; отозвать его можно в любой момент в портале.
**Caution:** Относитесь к ключу как к паролю. Он привязан к вашему аккаунту и может загружать, скачивать и
**безвозвратно удалять** ваши кейсы. Никогда не встраивайте его в клиентский код, который вы
поставляете конечным пользователям.

### Программное управление ключами (необязательно)

Если вы автоматизируете ротацию ключей, эндпоинты управления находятся по адресу
`/api/v1/auth/api-keys` и требуют **bearer-токен OAuth2** из вашего входа в портал
(`Authorization: Bearer <jwt>`) — а не API-ключ:

| Метод &amp; путь | Назначение |
| --- | --- |
| `POST /api/v1/auth/api-keys` | Создать ключ — ответ содержит открытый текст **один раз** |
| `GET /api/v1/auth/api-keys` | Список ваших ключей (значения замаскированы) |
| `POST /api/v1/auth/api-keys/{id}/revoke` | Отозвать ключ |
| `DELETE /api/v1/auth/api-keys/{id}` | Удалить ключ |

## Отправка ключа в запросах

Добавляйте заголовок `X-API-Key` к каждому вызову:

```bash
curl https://api.accessful.de/api/v1/upload-service/job-status/<caseId> \
  -H "X-API-Key: ak_your_key_here"
```
```js
await fetch(`https://api.accessful.de/api/v1/upload-service/job-status/${caseId}`, {
  headers: { 'X-API-Key': process.env.ACCESSFUL_API_KEY },
});
```
```java
HttpRequest.newBuilder()
    .uri(URI.create("https://api.accessful.de/api/v1/upload-service/job-status/" + caseId))
    .header("X-API-Key", System.getenv("ACCESSFUL_API_KEY"))
    .GET().build();
```
## Проверка ключа

Быстро проверьте ключ, запросив случайный несуществующий кейс. Рабочий ключ возвращает
**404** (кейс не существует) — *а не* 401.

1. Отправьте запрос статуса с одноразовым ID кейса:

   ```bash
   curl -i https://api.accessful.de/api/v1/upload-service/job-status/00000000-0000-0000-0000-000000000000 \
     -H "X-API-Key: ak_your_key_here"
   ```

2. Прочитайте строку статуса:

   - **`404 Not Found`** → ваш ключ принят. ✅
   - **`401 Unauthorized`** → ключ отсутствует, имеет неверный формат или отозван.

## Ошибки аутентификации

| Статус | Значение |
| --- | --- |
| `401 Unauthorized` | Нет ключа, неверный формат ключа или отозванный/просроченный ключ. |
| `403 Forbidden` | Ключ действителен, но не имеет прав на это действие. |

Отсутствующий или недействительный ключ (**401**) отклоняется на **gateway**, прежде чем запрос
достигнет приложения — поэтому 401 никогда не несёт тело [Problem Details](https://docs.accessful.de/ru/errors/).
Полагайтесь на код статуса. **403** приходит от самого приложения и несёт тело Problem Details,
как и другие ошибки уровня приложения.