1 Общая информация
Данный документ описывает Partner Publishing API — внутренний HTTP API для внешних партнёров ЛитРес, позволяющий автоматизировать размещение и управление артами (книгами) в каталоге ЛитРес.
Все эндпоинты находятся по префиксу `/partners/`.
Во всех запросах к API (если не указано обратное) используется аутентификация через HTTP-заголовки. Все обязательные параметры отмечены звёздочкой (**\***).
2 Аутентификация
Каждый запрос к API должен содержать аутентификационные данные. Поддерживаются два метода. Для новых интеграций следует использовать метод на основе заголовков.
Аутентификация через HTTP-заголовки (основной метод)
В каждом запросе передаются следующие заголовки:
- `X-Timestamp`* — текущее время в виде Unix Timestamp (целое число, секунды);
- `X-Partner-Id`* — идентификатор партнёра;
- `X-Signature`* — HMAC-SHA256 подпись, формируемая следующим образом:
```python
import hashlib
import hmac
import time
def make_headers(partner_id: int, partner_secret: str) -> dict:
timestamp = int(time.time())
message = f"{timestamp}.{partner_id}"
signature = hmac.new(
partner_secret.encode("utf-8"),
message.encode("utf-8"),
hashlib.sha256,
).hexdigest()
return {
"X-Timestamp": str(timestamp),
"X-Partner-Id": str(partner_id),
"X-Signature": signature,
}
```
Подпись действительна в течение **60 секунд** с момента генерации.
3 Последовательность размещения арта
Для успешного прохождения релиза и появления арта в каталоге необходимо выполнить следующие шаги в указанном порядке:
1. Создать или обновить персон, связанных с артом (запрос `PUT /partners/persons/{person_uuid}`);
2. Создать или обновить описание арта (запрос `PUT /partners/arts`);
3. Загрузить обложку арта (запрос `POST /partners/cover`);
4. Загрузить файл арта (запрос `POST /partners/file/fb2` или `POST /partners/file/pdf`);
5. С некоторой периодичностью проверять статус арта (запрос `GET /partners/update-log`).
4 Управление артами
4.1 Создание и обновление арта
Используется следующий URL: `PUT /partners/arts`.
Запрос создаёт новый арт или полностью заменяет метаданные существующего (идентификация по `uuid`). UUID генерируется на стороне партнёра. **При каждом вызове необходимо передавать полное актуальное состояние арта**, а не только изменившиеся поля.
Параметры запроса передаются в теле запроса в формате JSON. Обязательные параметры отмечены звёздочкой:
- `uuid`* — уникальный идентификатор арта, сгенерированный партнёром по стандарту RFC 4122. Запрещается генерировать UUID упрощённым генератором случайных символов. Если передан UUID существующего арта, происходит обновление его метаданных;
- `name`* — название арта. Должно быть уникальным среди всех артов партнёра. Названия «КАПСОМ» запрещены. Точка в конце не нужна;
- `price`* — цена в рублях, `≥ 0`. Дробная часть отделяется точкой. Для бесплатного распространения указывается `0`;
- `min_age`* — возрастное ограничение на содержание арта (целое число). Допустимые значения: `0`, `6`, `12`, `16`, `18`, `21`;
- `language_code`* — двухбуквенный код языка, на котором написан арт (формат ISO);
- `source_language_code`* — двухбуквенный код языка оригинала. Если арт не является переводом, указывается то же значение, что и в `language_code`;
- `drm`* — тип защиты от копирования. Допустимые значения: `litres`, `no`;
- `genres`* — массив жанров арта. Должен содержать хотя бы один элемент. Подробнее — в разделе «Жанры»;
- `art_type` — тип арта;
- `file_extension` — расширение файла арта. Допустимые значения: `fb2`, `pdf`, `epub`;
- `annotation` — аннотация к арту в формате HTML. Подробнее — в разделе «Формат аннотации»;
- `isbn` — ISBN арта (13 цифр без разделителей);
- `date_written_at` — дата написания арта в формате `ГГГГ-ММ-ДД`;
- `translated_at` — дата перевода в формате `ГГГГ-ММ-ДД`;
- `valid_till` — дата и время истечения прав в формате ISO 8601. При передаче текущей даты арт немедленно снимается с продажи;
- `trial_chars` — размер пробного фрагмента в символах. Взаимоисключающий с `trial_percent`;
- `trial_percent` — размер пробного фрагмента в процентах (от 8 до 20). Взаимоисключающий с `trial_chars`. Если оба параметра равны `null`, используется значение по умолчанию `24`;
- `art_refresh_in_days` — интервал обновления чернового арта в днях. При указании этого параметра арт считается черновиком;
- `publisher_art_code` — внутренний код арта у правообладателя;
- `publisher_name` — название издательства;
- `persons` — список персон, связанных с артом. Подробнее — в разделе «Связи арта с персонами»;
- `series_info` — объект с информацией о сериях. Подробнее — в разделе «Серии»;
- `art_relations` — список логических связей с другими артами. Подробнее — в разделе «Логические связи между артами»;
- `tags` — список тегов арта. Подробнее — в разделе «Теги»;
- `podcast` — параметры подкаста (`is_completed`, `rss_link`). Передаётся только для артов-подкастов;
- `partner_owner_info` — дополнительные данные о правообладателе. Только для привилегированных партнёров.
Ответ сервера: `204 No Content`.
Возможные ошибки:
- `403` — UUID арта принадлежит другому партнёру;
- `422` — UUID уже используется для другого арта; неуникальное название; некорректная аннотация; неизвестные теги; персона или серия не принадлежит правообладателю партнёра; попытка изменить ISBN; некорректная конфигурация агентов.
Формат аннотации
Поле `annotation` должно содержать HTML со следующей структурой:
```xml
<annotation><p>Первый абзац.</p><p>Второй абзац.</p></annotation>
```
Правила:
- вся аннотация оборачивается в тег `<annotation>`;
- внутри `<annotation>` весь текст должен быть заключён в теги `<p>` — «голый» текст непосредственно в `<annotation>` не допускается;
- вложенность тегов — только один уровень (`<p>` внутри `<annotation>`, но не `<p>` внутри `<p>`);
- допустимые теги стилей: `<b>`, `<i>`, `<u>`, `<sub>`, `<sup>`;
- допустимые теги списков: `<ul>`, `<ol>`, `<li>`;
- ссылки (`<a>`) в аннотации запрещены — сервер вернёт ошибку.
Примеры:
```xml
<annotation><p>Текст.</p></annotation> ✅
<annotation><p>Текст1.</p><p>Текст2.</p></annotation> ✅
<annotation>Голый текст</annotation> ❌
<annotation><p>Текст1<p>Текст2</p></p></annotation> ❌
Связи арта с персонами
Список персон, связанных с артом. К арту должна быть привязана хотя бы одна персона с типом связи `author`.
```json
"persons": [
{"uuid": "5fec2133-b3e1-4a0a-961e-81493c9dfd6d", "relation": "author"},
{"uuid": "a1b2c3d4-...", "relation": "translator"}
]
```
- `uuid`* — UUID персоны, заранее созданной партнёром;
- `relation`* — тип связи персоны с артом. Допустимые значения:
- `author` — автор;
- `coauthor` — соавтор;
- `translator` — переводчик;
- `illustrator` — художник;
- `compiler` — составитель;
- `editor` — редактор;
- `narrator` — чтец (для аудиокниг).
Логические связи между артами
Список логических связей с другими артами партнёра.
```json
"art_relations": [
{"uuid": "33b19c47-...", "relation": "sequel"},
{"uuid": "58f47daf-...", "relation": "prequel"}
]
```
- `uuid`* — UUID связанного арта, заранее созданного партнёром;
- `relation`* — тип связи. Допустимые значения:
- `sequel` — продолжение;
- `prequel` — предыстория;
- `previous` — предыдущий выпуск;
- `next` — следующий выпуск;
- `translated_from` — перевод с (язык оригинала);
- `translated` — перевод;
- `collected` — сборник;
- `part` — часть сборника;
- `reedition` — переиздание;
- `another_type` — другой тип того же произведения (например, аудиоверсия текстовой книги);
- `auto_speech` — создана авточтецом;
- `auto_speech_paid` — создана авточтецом на продажу;
- `another_translation` — альтернативный перевод;
- `intersection` — тематическое пересечение;
- `appendix` — приложение;
- `appendix_to` — приложение к;
- `translation_to_other_lang` — перевод на другой язык.
Серии артов
Информация о сериях, в которые входит арт.
```json
"series_info": {
"mode": "append",
"series": [
{"uuid": "9b9bbdad-22f2-455d-bfe2-73d8f35d340b", "order": 5},
{"uuid": "ab940dec-936d-40fc-8ce4-357e75917e34"}
]
}
```
- `mode` — режим обновления серий:
- `append` — добавить переданные серии к уже имеющимся;
- `replace` — заменить все имеющиеся серии переданным списком;
- `series` — список серий. Каждый элемент содержит:
- `uuid`* — UUID серии, заранее созданной партнёром;
- `order` — порядковый номер арта в серии (целое положительное число). Указывается при наличии нумерации. Для тематических серий (например, «учебники») номер можно не указывать.
Тип защиты (DRM)
Поле `drm` определяет тип защиты арта от копирования. Допустимые значения:
- `litres` — DRM-защита ЛитРес;
- `no` — без DRM.
4.2 Изменение цены арта
Используется следующий URL: `PATCH /partners/arts/price`.
Позволяет изменить цену опубликованного арта без прохождения повторной модерации.
Параметры запроса передаются в теле запроса в формате JSON:
- `art_uuid`* — UUID арта;
- `price`* — новая цена в рублях от `0` до `100000`.
Ответ сервера: `204 No Content`.
Возможные ошибки: `404` — арт не найден.
4.3 Обновление правообладателей арта
Используется следующий URL: `PUT /partners/arts/rightholders`.
Полностью заменяет список правообладателей арта. Доступно только по специальному требованиями, так как обычно 1 партнёр = 1 правообладатель.
Параметры запроса передаются в теле запроса в формате JSON:
- `art_uuid`* — UUID арта;
- `rightholders`* — список правообладателей. Каждый элемент содержит:
- `id`* — идентификатор правообладателя в системе ЛитРес;
- `uuid`* — UUID правообладателя;
- `agent_uuid`* — UUID агента;
- `is_owner`* — является ли данный правообладатель владельцем арта;
- `share_percent`* — процент отчислений.
Пример тела запроса:
```json
{
"art_uuid": "63c38eb5-c0f1-4cae-b170-0bfa812e5c5f",
"rightholders": [
{
"id": 123,
"uuid": "5fec2133-b3e1-4a0a-961e-81493c9dfd6d",
"agent_uuid": "ab940dec-936d-40fc-8ce4-357e75917e34",
"is_owner": true,
"share_percent": "100.00"
}
]
}
```
Ответ сервера: `204 No Content`.
Возможные ошибки: `404` — арт не найден; `400` — правообладатель не найден, дублирование владельцев, некорректный процент отчислений, правообладатели не принадлежат данному партнёру.
5 Загрузка файлов
5.1 Загрузка обложки арта
Используется следующий URL: `POST /partners/cover`.
Для PDF-артов загрузка обложки обязательна до отправки файла арта. Для артов других форматов рекомендуется.
Параллельная загрузка объектов от одного партнёра не поддерживается. Загружайте объекты по одному.
Параметры запроса передаются в формате `multipart/form-data`:
- `art_uuid`* — UUID арта;
- `file_checksum`* — SHA-256 хеш содержимого файла в нижнем регистре. Вычисляется следующим образом:
```python
image_content = file.read()
file_hash = hashlib.sha256(image_content).hexdigest()
```
- `file`* — файл обложки.
Требования к файлу обложки:
- допустимые форматы: JPEG, JPG, PNG, WEBP (цветовая схема RGB);
- если ширина изображения превышает 1500 px, оно пропорционально уменьшается;
- рекомендуемый минимальный размер: 1000×1500 px;
- рекомендуемое соотношение сторон: 5×7 (ширина × высота).
Ответ сервера: `204 No Content`.
Возможные ошибки: `404` — арт не найден; `422` — неподдерживаемый формат файла, неверная контрольная сумма.
5.2 Загрузка FB2-файла арта
Используется следующий URL: `POST /partners/file/fb2`.
Параллельная загрузка объектов от одного партнёра не поддерживается. Загружайте объекты по одному.
Параметры запроса передаются в формате `multipart/form-data`:
- `art_uuid`* — UUID арта;
- `file_checksum`* — SHA-256 хеш содержимого ZIP-архива в нижнем регистре. Вычисляется следующим образом:
```python
file.seek(0)
file_hash = hashlib.sha256(file.read()).hexdigest()
```
- `file`* — FB2-файл, упакованный в ZIP-архив.
Требования к файлу:
- название файла должно оканчиваться на `.zip`;
- архив должен содержать ровно один файл с расширением `.fb2`;
- кодировка текста в файле: UTF-8;
- FB2-файл должен соответствовать схеме FictionBook 2.2;
- не допускаются теги `<table>` и `<stylesheet>`;
- все внутренние ссылки и сноски должны иметь актуальные точки привязки;
- оглавление не должно содержаться в файле — оно формируется автоматически из заголовков;
- изображения в книге: форматы JPEG или PNG, цветовая схема RGB, разрешение каждого файла не более 2 мегапикселей (длина × ширина ≤ 2 000 000 px). Все изображения обязательно должны быть использованы в тексте;
- если файл содержит обложку: формат JPEG, цветовая схема RGB, минимальный размер бо́льшей стороны — 1500 px.
Учитывайте, что успешная загрузка файла запускает на стороне ЛитРес процедуру релиза. До окончания релиза изменять метаданные арта или повторно загружать файл нельзя — API будет возвращать ошибку.
Ответ сервера: `204 No Content`.
Возможные ошибки: `404` — арт не найден; `422` — неверное расширение файла, неверная контрольная сумма, повреждённый ZIP-архив; `400` — ошибка загрузки или обработки файла.
5.3 Загрузка PDF-файла арта
Используется следующий URL: `POST /partners/file/pdf`.
Параллельная загрузка объектов от одного партнёра не поддерживается. Загружайте объекты по одному.
Перед загрузкой PDF-файла для арта должна быть загружена обложка.
Параметры запроса передаются в формате `multipart/form-data`:
- `art_uuid`* — UUID арта;
- `file_checksum`* — SHA-256 хеш содержимого файла в нижнем регистре. Вычисляется следующим образом:
```python
file.seek(0)
file_hash = hashlib.sha256(file.read()).hexdigest()
```
- `trial_pages_count`* — страницы пробного фрагмента. Передаются диапазонами или поштучно, через запятую. Рекомендуется включать не более 20% от общего числа страниц. Примеры:
- `1-4,7-8,15` — страницы 1–4, 7–8 и 15;
- `10` — первые 10 страниц;
- `1-5,7` — страницы 1–5 и 7;
- `file`* — PDF-файл арта.
Требования к файлу:
- название файла должно оканчиваться на `.pdf`;
- в названии допустимы только латинские буквы, арабские цифры и символ нижнего подчёркивания `_`. Пробелы запрещены;
- файл должен быть валидным PDF;
- максимальный размер файла: 70 МБ;
- все страницы книги должны находиться в одном файле; рекомендуется размещать одну страницу книги на одну страницу PDF-документа, а не разворот.
Учитывайте, что успешная загрузка файла запускает на стороне ЛитРес процедуру релиза. До окончания релиза изменять метаданные арта или повторно загружать файл нельзя — API будет возвращать ошибку.
Ответ сервера: `204 No Content`.
Возможные ошибки: `404` — арт не найден; `422` — неверное расширение, некорректное имя файла, неверная контрольная сумма, повреждённый PDF, некорректный диапазон страниц; `400` — обложка не загружена, несоответствие типа арта, релиз уже выполняется, ошибка загрузки.
6 Управление персонами
Создание и обновление персоны
Используется следующий URL: `PUT /partners/persons/{person_uuid}`.
Создаёт новую персону или обновляет существующую. UUID генерируется на стороне партнёра. Персоны являются общими — одна и та же персона (например, автор) может быть связана с несколькими артами.
**Важно:** если персона была объединена с другой редакторами ЛитРес, её описание нельзя обновить через API (сервер вернёт ошибку), однако привязывать арты к ней по прежнему можно, используя исходный UUID.
Параметры пути:
- `person_uuid`* — UUID персоны по стандарту RFC 4122.
Параметры запроса передаются в теле запроса в формате JSON:
- `last_name`* — фамилия (не более 255 символов). Используется также для псевдонимов и коллективных обозначений, например «Редакция». «Капс» запрещён. Точка в конце не нужна;
- `first_name` — имя (не более 255 символов);
- `middle_name` — отчество (не более 255 символов);
- `full_name` — полное имя (не более 255 символов). Если не передан, формируется автоматически из имени, отчества и фамилии. Должно быть уникальным среди всех персон партнёра — допускается не более 5 персон с одинаковым полным именем;
- `full_name_genitive` — полное имя в родительном падеже;
- `last_name_genitive` — фамилия в родительном падеже;
- `birth_year` — год рождения (от `-1000` до `9999`);
- `description_lang_code` — двухбуквенный код языка биографии (по умолчанию `ru`);
- `description` — биография автора. Допускается простой текст или HTML. Ссылки в тексте биографии запрещены — сервер вернёт ошибку.
Ответ сервера: `204 No Content`.
Возможные ошибки: `403` — ошибка прав доступа; `400` — отсутствует фамилия, ошибка создания или обновления, биография содержит ссылки, персона объединена, превышен лимит дублирующихся имён, некорректный UUID.
7 Жанры
Для получения дерева жанров используется URL: `GET https://api.litres.ru/foundation/api/genres`.
В запросе создания/обновления арта допускается использовать только «конечные» жанры — то есть те, которые находятся на самом нижнем уровне вложенности дерева и не являются контейнерами. Каждый жанр передаётся в виде объекта с полем `token`:
```json
"genres": [
{"token": "home_cooking", "is_main": true},
{"token": "home_crafts", "is_main": false}
]
```
- `token`* — токен жанра из дерева жанров ЛитРес;
- `is_main` — является ли жанр основным. Основной жанр используется в случаях, когда учитывается только один жанр. Допускается не более одного основного жанра.
Рекомендуется обновлять информацию по жанровому дереву не реже одного раза в сутки.
8 Теги ЛитРес
Запрос списка тегов (JSON)
Используется следующий URL: `GET /partners/tags`.
Возвращает список тегов, доступных для использования при создании артов.
Ответ сервера
Пример возвращаемого JSON:
```json
{
"timestamp": "2025-05-29T15:30:00+03:00",
"tags": [
{
"uuid": "617082dd-5b5b-11e4-96e2-0025905a06ea",
"tag_title": "облачные сервисы",
"visible": 1
},
{
"uuid": "614bcc80-5b5b-11e4-96e2-0025905a06ea",
"tag_title": "облачные технологии"
}
]
}
```
В ответе корневой объект содержит поле `timestamp` — текущее время сервера, а также массив тегов `tags`. Каждый тег представлен следующими полями:
- `uuid` — идентификатор тега. Используется в запросе создания/обновления арта;
- `tag_title` — текстовое описание тега;
- `visible` — видимость тега на карточке арта. Может отсутствовать, что означает значение по умолчанию (тег отображается). Значения:
- `0` — тег не отображается на карточке арта;
- `1` — тег отображается на карточке арта.
9 Коды ответов HTTP
| Код | Значение |
|---|---|
| `200 OK` | Успешный запрос на получение данных |
| `204 No Content` | Успешный запрос на изменение данных |
| `400 Bad Request` | Ошибка бизнес-логики |
| `403 Forbidden` | Ошибка аутентификации или недостаточно прав |
| `404 Not Found` | Арт или персона не найдены |
| `422 Unprocessable Entity` | Ошибка валидации параметров запроса |