# External Transcription API — справочник

Пошаговая интеграция для разработчиков: **[integration-guide.md](integration-guide.md)**  
Руководство оператора (токены, Services): **[admin-guide.md](admin-guide.md)**

---

## Базовые URL

### Production (kapilar)

| | URL |
|---|-----|
| **Transcription API** | `http://kapilar.med.cv.cai.cfuv.ru/serv/v1/transcribe` |
| **OpenAPI** | `http://kapilar.med.cv.cai.cfuv.ru/serv/docs` |
| **Admin UI** | `http://kapilar.med.cv.cai.cfuv.ru/` |

### Local Docker

| | URL |
|---|-----|
| **Transcription API** | `http://localhost:8000/api/v1/transcribe` |
| **OpenAPI** | `http://localhost:8000/docs` |
| **Admin UI** | `http://localhost:5173` |

---

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

### API-токен (рекомендуется)

Выпускается в **Admin → API Tokens**. Передавайте:

```http
Authorization: Bearer asr_YOUR_TOKEN
```

```http
X-API-Key: asr_YOUR_TOKEN
```

Аудит: **API Tokens → history**.

### Legacy key

`TRANSCRIPTION_API_KEY` из Settings — без аудита по токенам. Не для production.

---

## Endpoints

Все пути ниже относительно **Transcription API base** (`…/v1/transcribe`).

### POST `` (create job)

**Async** — возвращает `job_id`.

**Content-Type:** `multipart/form-data`

| Поле | Тип | Обязательно | Описание |
|------|-----|-------------|----------|
| file | file | ✓ | Аудио/видео |
| asr_provider_id | UUID | | ID провайдера из Admin |
| model | string | | `rnnt`, `ctc`, `base`, … |
| engine | string | | `gigaam`, `whisper`, `silero`, `vosk`, `whisperx` |
| diarize | string/bool | | `true` / `false` (default `false`) — ASR + speaker diarization |
| max_speakers | int | | Только с `diarize=true`: 1–32, default `8` |

**Выбор ASR:** `asr_provider_id` → `model` + `engine` → default из Settings.  
**Спикеры:** `diarize=true` (нужен сервис `diarization`). Сегменты = **реплики диаризации** (не ASR-чанки ~20 с); поле `speaker`: `Speaker 1`, …

Подробнее и чеклист проверки: [integration-guide.md — диаризация](integration-guide.md#диаризация-как-читать-сегменты).

**Response `201`:**

```json
{
  "job_id": "7fd01fce-2209-401e-ba14-1f728b45ebc8",
  "status": "queued",
  "model": "rnnt",
  "engine": "gigaam",
  "diarize": false
}
```

### GET `/{job_id}`

Статус: `queued`, `running`, `completed`, `failed`, `cancelled`.  
В ответе также `model`, `engine`, `diarize`.

### GET `/{job_id}/result`

Только `completed`. Иначе `409`.

Поля: `text`, `segments[]` (`index`, `start`, `end`, `text`, `speaker`, …), `duration_sec`, `model`, `engine`, `diarize`, `error`.  
При `diarize=true` у сегментов заполнен `speaker`.

---

## Примеры (production)

### curl

```bash
TOKEN="asr_YOUR_TOKEN"
BASE="http://kapilar.med.cv.cai.cfuv.ru/serv/v1/transcribe"
FILE="audio.mp3"

# только ASR
curl -s -X POST "$BASE" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@$FILE" \
  -F "engine=gigaam" \
  -F "model=rnnt"

# ASR + спикеры
curl -s -X POST "$BASE" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@$FILE" \
  -F "engine=gigaam" \
  -F "model=rnnt" \
  -F "diarize=true" \
  -F "max_speakers=4"

curl -s "$BASE/JOB_ID" -H "Authorization: Bearer $TOKEN"
curl -s "$BASE/JOB_ID/result" -H "Authorization: Bearer $TOKEN"
```

### Python

См. полный пример в [integration-guide.md](integration-guide.md#пример-на-python).

### Скрипт проекта

```bash
python scripts/run_transcribe_api.py \
  --host https://kapilar.med.cv.cai.cfuv.ru \
  --token asr_… \
  --engine gigaam \
  --model rnnt \
  audio.mp3
```

| Переменная | Default |
|------------|---------|
| `TRANSCRIPTION_API_TOKEN` | — |
| `TRANSCRIPTION_HOST` | — (→ `--host`) |
| `TRANSCRIPTION_API_URL` | local: `http://localhost:8000/api/v1/transcribe` |
| `API_PUBLIC_PREFIX` | `/serv` на сервере, `/api` локально |

---

## Admin REST API (краткая справка)

**Production base:** `http://kapilar.med.cv.cai.cfuv.ru/serv`  
**Local base:** `http://localhost:8000/api`  
**Auth:** cookie после `POST …/auth/login`

| Группа | Endpoints |
|--------|-----------|
| Auth | `POST /auth/login`, `POST /auth/logout`, `GET /auth/me` |
| Media | `GET/POST /media/upload`, `DELETE /media/{id}` |
| Jobs | `GET/POST /jobs`, export txt/json/srt |
| System | `GET /system/services`, `POST /system/containers/{id}/start\|stop` |
| Tokens | `GET/POST /tokens`, usage history |
| Settings | `GET/PATCH /settings/transcription` |

---

## Коды ошибок

| HTTP | Причина |
|------|---------|
| 401 | Нет или неверный токен |
| 403 | Job другого токена |
| 404 | Job не найден |
| 409 | Result до `completed` |
| 413 | Файл > `MAX_UPLOAD_BYTES` |
| 503 | API выключен или нет ASR |

---

## Production checklist

1. Отдельный токен на каждый клиент
2. ASR-контейнеры running перед нагрузкой
3. Timeout клиента ≥ длительности аудио
4. Не использовать legacy key
5. Revoke скомпрометированных токенов
