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

# Доступы

> Свои доступы для пользователей: завести, выдать, отозвать, проверить

Доступ — ваша отметка у пользователя Ai-Seven: например, «участник чемпионата». Что доступ означает, решаете вы; в Ai-Seven он ничего не открывает и не закрывает. Мы храним, кому и до какого момента вы его выдали, и показываем действующие доступы в [статистике](https://docs.aisevenai.ru/partner-api/statistics.md).

Выдача доступа не связана с [выдачей подписки](https://docs.aisevenai.ru/partner-api/subscriptions.md): за что давать доступ, решаете вы.

**1. Заведите доступ**

Один раз: ключ и название. `POST /accesses`

**2. Выдайте пользователю**

По `public_id`, бессрочно или до заданного момента. `PUT /accesses/{key}/users/{public_id}`

**3. Проверяйте в статистике**

Действующие доступы — в поле `accesses` ответов статистики.

**4. Отзовите, когда нужно**

`DELETE /accesses/{key}/users/{public_id}`

Вы видите и выдаёте только свои доступы: доступы других партнёров вам не видны, а ваши — им.

## Завести доступ

```http theme={null}
POST /api/v1/partner/accesses
```

### Тело запроса

```json theme={null}
{
  "key": "championship",
  "title": "Чемпионат"
}
```

**key** `string` *required*

Ключ доступа, от 1 до 64 символов: латинские буквы, цифры и `_ . : -`. Уникален в рамках вашей интеграции. Его вы передаёте при выдаче и видите в статистике.

**title** `string` *required*

Название, от 1 до 100 символов.

### Ответ

`201 Created`

```json theme={null}
{
  "key": "championship",
  "title": "Чемпионат",
  "created_at": 1761379200
}
```

**key** `string`

Ключ доступа.

**title** `string`

Название доступа.

**created\_at** `integer`

Момент создания, unix-время в секундах.

> [!NOTE]
>
> Доступ с уже заведённым ключом второй раз не заводится: вернётся `409` с кодом `access_exists`, существующий доступ не меняется. При повторе после таймаута такой ответ означает, что доступ уже заведён.

## Список доступов

```http theme={null}
GET /api/v1/partner/accesses
```

Все заведённые вами доступы в порядке создания.

```json theme={null}
[
  { "key": "championship", "title": "Чемпионат", "created_at": 1761379200 },
  { "key": "final", "title": "Финал", "created_at": 1761465600 }
]
```

Поля — как в ответе на создание.

## Выдать доступ

```http theme={null}
PUT /api/v1/partner/accesses/{key}/users/{public_id}
```

Выдаёт пользователю заведённый доступ. Запрос идемпотентный: повторная выдача не создаёт второй записи, а заменяет срок на переданный.

**key** `string` *required*

Ключ заведённого доступа. Незаведённый ключ — `404`, новый доступ при выдаче не создаётся.

**public\_id** `string` *required*

Идентификатор пользователя в Ai-Seven, UUID — из [статистики](https://docs.aisevenai.ru/partner-api/statistics.md) или из [токена виджета](https://docs.aisevenai.ru/widget/overview.md).

### Тело запроса

Тело — JSON-объект, обязательно. Для бессрочного доступа — пустой объект `{}`.

```json theme={null}
{
  "expires_at": 1767214800
}
```

**expires\_at** `integer`

Момент окончания доступа, **unix-время в секундах**. Не передан или `null` — доступ бессрочный. После этого момента доступ не показывается в статистике.

### Ответ

```json theme={null}
{
  "key": "championship",
  "title": "Чемпионат",
  "expires_at": 1767214800
}
```

**key** `string`

Ключ доступа.

**title** `string`

Название доступа.

**expires\_at** `integer | null`

Момент окончания, unix-время в секундах. `null` — бессрочный.

> [!WARNING]
>
> Повторная выдача **заменяет** срок, а не продлевает: запрос с `{}` делает доступ бессрочным, даже если раньше у него был срок. Чтобы продлить, передайте новый момент окончания целиком.

## Отозвать доступ

```http theme={null}
DELETE /api/v1/partner/accesses/{key}/users/{public_id}
```

**key** `string` *required*

Ключ заведённого доступа.

**public\_id** `string` *required*

Идентификатор пользователя в Ai-Seven.

Ответ — `204 No Content`, без тела. Запрос идемпотентный: отзыв доступа, которого у пользователя нет, тоже возвращает `204`.

## Проверить доступ

Отдельного эндпоинта проверки нет: действующие доступы пользователя приходят в поле `accesses` [статистики](https://docs.aisevenai.ru/partner-api/statistics.md) — и в списке, и по одному пользователю.

```http theme={null}
GET /api/v1/partner/stats/users/{public_id}
```

```json theme={null}
{
  "public_id": "9f1c2a6e-4b70-4f1a-9d2c-8b5e0a7d3f42",
  "accesses": [
    { "key": "championship", "title": "Чемпионат", "expires_at": 1767214800 }
  ]
}
```

В ответе показаны только поля, относящиеся к доступам. Истёкшие и отозванные доступы не показываются. В список пользователей `GET /stats/users` попадают только пользователи с активностью за период; чтобы проверить доступ конкретного пользователя, запрашивайте его по `public_id`.

### Пример

```python Python theme={null}
import requests

BASE = "https://aisevenai.ru/api/v1/partner"
headers = {"Authorization": f"Bearer {api_token}"}

requests.post(f"{BASE}/accesses", headers=headers, json={"key": "championship", "title": "Чемпионат"})

requests.put(
    f"{BASE}/accesses/championship/users/{public_id}",
    headers=headers,
    json={"expires_at": 1767214800},
).raise_for_status()

user = requests.get(f"{BASE}/stats/users/{public_id}", headers=headers).json()
has_access = any(a["key"] == "championship" for a in user["accesses"])
```

```javascript Node.js theme={null}
const BASE = "https://aisevenai.ru/api/v1/partner";
const headers = { Authorization: `Bearer ${apiToken}`, "Content-Type": "application/json" };

await fetch(`${BASE}/accesses`, {
  method: "POST",
  headers,
  body: JSON.stringify({ key: "championship", title: "Чемпионат" }),
});

await fetch(`${BASE}/accesses/championship/users/${publicId}`, {
  method: "PUT",
  headers,
  body: JSON.stringify({ expires_at: 1767214800 }),
});

const user = await (await fetch(`${BASE}/stats/users/${publicId}`, { headers })).json();
const hasAccess = user.accesses.some((a) => a.key === "championship");
```

```bash cURL theme={null}
curl -X PUT https://aisevenai.ru/api/v1/partner/accesses/championship/users/$PUBLIC_ID \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"expires_at": 1767214800}'

curl -X DELETE https://aisevenai.ru/api/v1/partner/accesses/championship/users/$PUBLIC_ID \
  -H "Authorization: Bearer $API_TOKEN"
```

## Ошибки

Помимо [общих ошибок](https://docs.aisevenai.ru/partner-api/overview.md#ошибки-авторизации):

| Код | `error.code` | Сообщение | Причина |
| - | - | - | - |
| `404` | `access_not_found` | Доступ с таким ключом не заведён | Ключ не заведён вами — при выдаче и отзыве |
| `404` | `user_not_found` | Пользователь не найден | Указан несуществующий `public_id` |
| `409` | `access_exists` | Доступ с таким ключом уже заведён | Повторное создание доступа с тем же ключом |
| `422` | `validation_error` | — | Ключ или название не прошли проверку, `public_id` не UUID, нет тела, `expires_at` не положительное целое или лишнее поле |


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