# Книга, главы и герои

Всё о книге: главы с состоянием и герои с голосами.

`GET /books/{book_id}` · чтение

Главное для работы через API — `chapters` (что озвучивать) и `characters` (кому какой голос).

## Параметры пути

| Параметр | Что это |
|---|---|
| `book_id` | Id книги |

## Что в ответе

| Поле | Что это |
|---|---|
| `chapters[].status` | `draft` — не озвучена, `queued` / `rendering` — идёт, `ready` — готова, `failed` — ошибка |
| `chapters[].audio_url` | MP3 главы, если готова |
| `chapters[].chars` | Знаков текста главы |
| `chapters[].review` | Сколько реплик под вопросом «кто говорит» |
| `characters[]` | Герои: `id`, `name`, `is_narrator`, `voice_id`, `emotion`, `gender`, `age` |
| `characters[].share` | Доля текста книги, которую читает герой |
| `edition` | Текущая версия озвучки |

## Ошибки

| Код | Когда |
|---|---|
| `404` | Нет такой книги или она не ваша |

```bash
curl "https://golosar-kniga.tech/api/v1/books/$BOOK_ID" \
  -H "x-api-key: $KEY"
```

```python
import os, requests

API = "https://golosar-kniga.tech/api/v1"
H = {"x-api-key": os.environ["GOLOSAR_KEY"]}
book_id = "01a134d0-dd73-77be-aa8d-0944ffb2b5e3"

r = requests.get(f"{API}/books/{book_id}", headers=H)
r.raise_for_status()
print(r.json())
```

```javascript
const API = "https://golosar-kniga.tech/api/v1";
const H = { "x-api-key": process.env.GOLOSAR_KEY };
const bookId = "01a134d0-dd73-77be-aa8d-0944ffb2b5e3";

const r = await fetch(`${API}/books/${bookId}`, { headers: H });
if (!r.ok) throw new Error(await r.text());
console.log(await r.json());
```

```json Ответ 200
{
  "book": {
    "id": "01a134d0-dd73-77be-aa8d-0944ffb2b5e3",
    "title": "Вечер в саду",
    "author": "Иван Петров",
    "status": "ready",
    "created_at": "2026-10-13T10:31:05.833003+00:00",
    "language": "ru",
    "subtitle": "",
    "series": null,
    "series_no": "",
    "genre": "",
    "age_rating": "",
    "thoughts": "hero",
    "sound": "studio",
    "check": "auto",
    "reading": "roles",
    "cover_url": null,
    "active_edition_id": "01a134d0-ddcc-7b41-ba3d-b8112c6d0414",
    "chapters": [
      {
        "id": "01a134d0-ddb7-72aa-b96c-967b596362fe",
        "position": 0,
        "title": "Глава 1",
        "status": "draft",
        "chars": 108,
        "duration_s": null,
        "rendered_at": null,
        "audio_url": null,
        "review": 0,
        "runs": [
          [
            "01a134d0-dda0-7b5d-800a-17ac9f33d738",
            43,
            false
          ],
          [
            "01a134d0-ddae-7737-9ff4-0672f189eef8",
            10,
            false
          ]
        ]
      },
      {
        "id": "01a134d0-ddc1-70fb-8b40-c2fe892e3bd1",
        "position": 1,
        "title": "Глава 2",
        "status": "draft",
        "chars": 56,
        "duration_s": null,
        "rendered_at": null,
        "audio_url": null,
        "review": 0,
        "runs": [
          [
            "01a134d0-dda0-7b5d-800a-17ac9f33d738",
            56,
            false
          ]
        ]
      }
    ],
    "chapters_ready": 0,
    "duration_s": 0,
    "characters": [
      {
        "id": "01a134d0-dda0-7b5d-800a-17ac9f33d738",
        "name": "Рассказчик",
        "aliases": [],
        "is_narrator": true,
        "voice_id": "01a134c9-6200-71bf-90af-073da699a09e",
        "emotion": "Нейтрально",
        "controls": {
          "speed": 1.0
        },
        "position": 0,
        "gender": "",
        "age": "",
        "description": "",
        "preset_id": null,
        "source": "rules",
        "share": 0.792
      },
      {
        "id": "01a134d0-ddae-7737-9ff4-0672f189eef8",
        "name": "Мира",
        "aliases": [
          "Мира"
        ],
        "is_narrator": false,
        "voice_id": "01a134c9-6200-71bf-90af-073da699a09e",
        "emotion": "Нейтрально",
        "controls": {
          "pitch": 0,
          "speed": 1.0,
          "formant": 1.0
        },
        "position": 1,
        "gender": "f",
        "age": "",
        "description": "",
        "preset_id": "01a134c9-6244-7ce9-b73b-4f11b4038f7c",
        "source": "rules",
        "share": 0.08
      }
    ],
    "review_total": 0,
    "analysis": null,
    "edition": {
      "id": "01a134d0-ddcc-7b41-ba3d-b8112c6d0414",
      "name": "Версия 1",
      "status": "draft",
      "count": 1
    }
  }
}
```
