# Robotext API — полная документация Robotext — SaaS-сервис генерации контента нейросетями: тексты, изображения, презентации, песни, видео, редактирование и анализ фото. Все сервисы доступны по HTTP API. - Базовый адрес: https://robotext.io - Токен доступа: https://robotext.io/api (выдаётся после активации PRO) - Машиночитаемая спецификация: https://robotext.io/openapi.json Авторизация: `Authorization: Bearer <токен>` во всех запросах, создающих задачу. Без токена запрос выполняется как анонимный, с демо-ограничениями. Ограничения, общие для всех сервисов: одновременно выполняется только одна задача (очереди на стороне сервиса нет); статус асинхронной задачи опрашивается не чаще одного раза в секунду; почти все ошибки отдаются с HTTP 200 и полем "status": "error". --- ## Общая информация ### Документация для нейросетей и агентов Если API подключает не человек, а ИИ-агент, не пересказывайте документацию — дайте ему одну из ссылок ниже. Файлы открыты без авторизации и всегда соответствуют текущей версии сервиса. [/llms.txt](https://robotext.io/llms.txt) Копировать **Оглавление сервиса.** Короткий файл: что за API, как авторизоваться и ссылки на все разделы с пояснениями. Агент сам решит, что читать дальше. Это стандартное соглашение `llms.txt` — его понимают ассистенты в редакторах кода и агентные фреймворки. **Как передать:** «Вот документация API: https://robotext.io/llms.txt — подключись и сделай …». [/llms-full.txt](https://robotext.io/llms-full.txt) Копировать **Вся документация одним файлом.** Тот же текст, что на этой странице, но плоским markdown, вместе с примерами на Python. Подходит, когда агент забирает контекст одним запросом или когда нужно вложить документацию прямо в промпт. **Как передать:** дайте ссылку целиком или приложите содержимое файла в диалог с моделью. [/openapi.json](https://robotext.io/openapi.json) Копировать **Машиночитаемый контракт (OpenAPI 3.1).** Все эндпоинты со схемами запросов и ответов и полными списками допустимых значений: 44 шаблона генерации текста, 97 стилей изображений, подсервисы анализа фото, редактирования и видео. Из него генерируется клиент на любом языке, а агентные фреймворки импортируют его как готовый набор инструментов. **Как передать:** укажите URL спецификации в импорте инструментов агента или в генераторе клиента. Файлы обновляются вместе с сервисом — их достаточно один раз указать агенту, отдельные выгрузки поддерживать не нужно. Токен в них не входит: его нужно передать агенту отдельно. ### Общая информация API повторяет то же взаимодействие с сервисом, что и веб-интерфейс: те же эндпоинты, те же параметры. Отличия — авторизация по токену и несколько технических параметров. ### Авторизация Все запросы, создающие задачу, требуют Bearer-токен. Токен постоянный, находится вверху этой страницы и передаётся в заголовке: ```bash Authorization: Bearer 5036e45d-53f2-4a72-92d2-8d5d79e22a72 ``` Если заголовок не передан, запрос обрабатывается как анонимный (по IP-адресу вашего сервера) — с демо-ограничениями и чужим балансом. Неверный токен возвращает **HTTP 401**. Не публикуйте токен в клиентском коде: он даёт полный доступ к балансу аккаунта. ### Два режима обработки **Синхронный.** Одно соединение: запрос — ответ с готовым результатом. Так работают генерация текста (`/create-write-sync/…`), анализ фото и редактирование фото. Время ответа зависит от объёма результата, поэтому задайте таймаут клиента с запасом (по умолчанию многие библиотеки рвут соединение через 20–30 секунд). **Асинхронный.** Два запроса: создание задачи возвращает `job_id`, затем вы опрашиваете статус до готовности. Так работают перефразирование, сокращение, изображения, презентации, песни, видео и генерация стихов/текстов песен. При создании задачи ответ содержит `"status": "completed"` — это подтверждение того, что задача **принята**, а не готовности результата. Готовность определяется только ответом эндпоинта `ping-*`. ### Ограничения - Одновременных задач: 1 на аккаунт - Частота опроса статуса: не чаще 1 раза в секунду - Очередь на стороне API: отсутствует - Хранение результатов: 24 часа (текст), 4 суток (видео) Очереди на уровне веб-сервиса нет: **в работе может быть только одна задача**. Пока предыдущая не завершилась, новая либо отклоняется с `notice.type = "limit"` (генерация текста, изображения, презентации, песни, видео, анализ и редактирование фото), либо принимается, но ждёт своей очереди (перефразирование и сокращение). Статус задачи опрашивайте **не чаще одного раза в секунду** — более частые запросы не ускоряют обработку. **API не предназначен для массовой генерации.** Он рассчитан на единичные последовательные запросы: одна задача за раз, следующая — после завершения предыдущей. Попытки распараллелить нагрузку или прогнать через него большой объём не дадут выигрыша — запросы будут отклоняться с `notice.type = "limit"`. Если нужен объём **от тысячи генераций**, такие задачи специалисты сервиса выполняют отдельно и под ключ — с подходящими мощностями и сроками. За деталями услуги напишите нам через [контакты](https://robotext.io/contact). ### Формат запроса Тело передаётся как форма (`application/x-www-form-urlencoded` или `multipart/form-data`). Запросы с файлами — всегда `multipart/form-data`. CSRF-токен для API не нужен. ### Формат ошибок Почти все ошибки возвращаются с кодом **HTTP 200** и телом с `"status": "error"`. Ориентируйтесь на поле `status`, а не на HTTP-код. ```json { "status": "error", "message": "❌ Превышен лимит запросов. Пожалуйста, дождитесь завершения предыдущего запроса.", "notice": {"type": "limit"} } ``` Поле `message` предназначено для показа человеку и может содержать HTML. Для логики используйте `notice.type`: | notice.type | Что означает | |---|---| | `validation` | Некорректные параметры запроса. Дополнительно приходят `title` и `text` с пояснением. | | `limit` | Уже есть активная задача — дождитесь её завершения. | | `paywall_balance` | Закончился баланс аккаунта. | | `paywall_demo` | Исчерпаны бесплатные демо-попытки (запрос без токена). | | `paywall_queue` | Переполнена бесплатная очередь (только видео). | | `moderation` | Запрос или результат отклонён фильтром контента. | | `moderation_block` | Три отклонения подряд — создание запросов заблокировано. | | `unavailable` | Сервис временно недоступен, повторите позже. | | `error` | Техническая ошибка. | | `generating` / `queue` | Не ошибка: промежуточный статус при опросе задачи. | В ошибках, связанных с загружаемыми файлами, дополнительно приходит `error_type` со значением `format`, `resolution`, `size` или `invalid`. ### Стоимость **Отдельного тарифа для API нет.** Работа через API оплачивается так же, как работа через сайт: те же пакеты, те же цены, тот же баланс. Запросы из кода и действия в веб-интерфейсе списывают средства с одного счёта, поэтому докупать что-то отдельно «для интеграции» не нужно. Баланс пополняется **пакетами** — они различаются объёмом и ценой; чем больше пакет, тем ниже стоимость единицы. Пакеты привязаны к сервису, которым вы пользуетесь (тексты, изображения, презентации, песни, видео, работа с фото), а остаток виден вверху этой страницы и в ответе `GET /balance`. [**Актуальные тарифы и состав пакетов — на странице цен →**](https://robotext.io/price) ### Сколько списывается за операцию Баланс единый для всех сервисов и считается в символах. | Операция | Списывается | |---|---| | Генерация текста | длина сгенерированного текста | | Перефразирование | длина исходного текста | | Сокращение текста | 500 | | Изображение | 500 | | Анализ фото | 500 | | Редактирование фото | 500 | | Презентация | 10 000 | | Песня | 10 000 | | Видео | 10 000 | Списание с аккаунта происходит по факту успешной обработки. Если запрос отклонён фильтром контента или завершился ошибкой генерации, баланс не уменьшается. ### Остаток баланса `GET /balance` — требуется Bearer-токен Параметров нет. Возвращает остаток в единицах каждого сервиса: ```json { "balance_text": 52511, "balance_image": 106, "balance_ocr": 106, "balance_imgedit": 106, "balance_presentation": 5, "balance_song": 5, "balance_video": 5 } ``` ### История запросов `GET /jobs-list` — требуется Bearer-токен Параметров нет. Возвращает задачи аккаунта по всем сервисам: `rewrite_jobs`, `reduction_jobs`, `write_jobs`, `image_jobs`, `presentation_jobs`, `song_jobs`, `ocr_jobs`, `imgedit_jobs`, `video_jobs`. ```json { "rewrite_jobs": [ { "id": "5036e45d-53f2-4a72-92d2-8d5d79e22a72", "created_at": "2026-08-31 12:43:34", "source_text_short": "Как эффективно пропиарить свой бизнес в Москве? В...", "status": "Готово" } ], "reduction_jobs": [] } ``` ### Проверка подключения Минимальный пример: запрашиваем баланс и убеждаемся, что токен принят. ```python import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" resp = requests.get(f"{BASE}/balance", headers={"Authorization": f"Bearer {TOKEN}"}) resp.raise_for_status() # 401 означает, что токен неверный balance = resp.json() print("Символов:", balance["balance_text"]) print("Изображений:", balance["balance_image"]) print("Видео:", balance["balance_video"]) ``` --- ## Перефразирование ### Перефразирование текста Асинхронный сервис: создаём задачу, получаем job_id, опрашиваем статус. На выходе — несколько вариантов перефразированного текста и разбор по предложениям. В этом сервисе токен учитывается **только вместе с параметром `api=1`**. Без `api=1` заголовок авторизации игнорируется, и запрос выполняется от анонимного пользователя по IP-адресу. ### Создание задачи `POST /create-rewrite-job` — требуется Bearer-токен, формат: form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `api` | Да | Integer | Технический параметр, всегда `1`. Включает API-режим: авторизацию по токену и результат без служебной HTML-разметки. | | `mode` | Да | String | Режим: `simple` — поверхностное перефразирование, `deep` — глубокое. Другое значение вернёт ошибку. | | `html` | Да | String | Текст для обработки — обычный текст или HTML. HTML будет разобран, перефразирован и возвращён с сохранением исходной разметки. | | `stop_words` | Нет | String | JSON-массив строкой: `["стоп слово 1", "стоп слово 2"]`. | Ответ: ```json { "status": "completed", "message": "Идет подготовка к перефразированию текста, пожалуйста, ожидайте...", "job_id": "5036e45d-53f2-4a72-92d2-8d5d79e22a72" } ``` ### Получение результата `GET /ping-rewrite-job?job_id=` — без токена Пока задача обрабатывается: ```json { "status": "continue", "progress": "Нейросеть Robotext перефразирует текст... ✏️", "notice": {"type": "generating", "progress": 40} } ``` Поле `progress` предназначено для показа человеку и содержит HTML с разметкой прогресс-бара. Число процентов берите из `notice.progress`. По готовности: ```json { "status": "completed", "result_text": [ "Доброе утро, друзья. Давайте поработаем над этим.", "Доброе утро, товарищи! Давайте поработаем над проектами.", "Доброе утро, коллеги. Давайте поработаем над проектом!" ], "sentences_variat": { "sentence-1": ["Добрый день, товарищи.", ["Доброе утро, друзья."], ["Доброе утро, коллеги."]] }, "balance_message": "52511 символов", "result_len": 78, "keys": {} } ``` | Поле | Описание | |---|---| | `result_text` | Массив вариантов перефразированного текста (при `api=1`). | | `sentences_variat` | Разбор по предложениям: исходное предложение и варианты его замены. | | `result_len` | Длина исходного текста в символах — именно столько списано с баланса. | | `balance_message` | Остаток баланса после списания. | | `keys` | Зарезервировано, всегда пустой объект. | Если задача создана, когда предыдущая ещё не завершилась, запрос **не отклоняется**: задача принимается и ждёт своей очереди. В этом случае при опросе приходит `notice.type = "limit"` — это нормальное ожидание, а не ошибка. ### Ограничения - Стоимость: длина исходного текста - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Хранение результата: 24 часа ### Пример на Python ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # 1. Создаём задачу. Очереди на стороне сервиса нет: пока эта задача # не завершится, новые создавать нельзя. payload = { "api": "1", # обязателен для работы по токену "mode": "simple", # simple — поверхностное, deep — глубокое "html": "Добрый день, товарищи. Давайте займемся проектом.", } resp = requests.post(f"{BASE}/create-rewrite-job", headers=headers, data=payload) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] print("Задача создана:", job_id) # 2. Опрашиваем статус — не чаще одного раза в секунду. while True: time.sleep(1) ping = requests.get(f"{BASE}/ping-rewrite-job", params={"job_id": job_id}) ping.raise_for_status() data = ping.json() if data["status"] == "completed": for i, variant in enumerate(data["result_text"], 1): print(f"Вариант {i}: {variant}") print("Списано символов:", data["result_len"]) break if data["status"] == "error": raise SystemExit(data.get("message")) ``` --- ## Сокращение текста Асинхронный сервис: сжимает исходный текст до заданной длины с сохранением смысла. ### Создание задачи `POST /create-reduction-job` — требуется Bearer-токен, формат: form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `text` | Да | String | Исходный текст, обычный текст без разметки. От 400 до 24 000 символов. | | `requiredLength` | Да | Integer | Желаемая длина результата в символах. Допустимый диапазон зависит от длины исходного текста — см. таблицу ниже. | | `mode` | Нет | String | Режим сокращения, значение `whole`. Значение по умолчанию, менять не требуется. | | `output_format` | Нет | String | `plain` (сплошной текст, по умолчанию) или `bullet` (маркированный список). | ### Допустимая длина результата | Длина исходного текста | Допустимые значения requiredLength | |---|---| | 400 – 3 000 символов | 200 – не более 50% от длины исходного текста | | 3 000 – 6 000 символов | 200 – 1 500 | | 6 000 – 24 000 символов | 400 – 3 000 | При подсчёте длины исходного текста переводы строк считаются за один символ. Значение `requiredLength` вне допустимого диапазона вернёт ошибку с `notice.type = "validation"` и пояснением в `notice.text`. Ответ: ```json { "status": "completed", "message": "Идет подготовка к сокращению текста, пожалуйста, ожидайте...", "notice": {"type": "generating"}, "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341" } ``` ### Получение результата `GET /ping-reduction-job?job_id=` — без токена Пока задача обрабатывается: ```json { "status": "continue", "progress": "Нейросеть Robotext сокращает текст... ✏️", "notice": {"type": "generating", "progress": null} } ``` По готовности: ```json { "status": "completed", "result_text": "Сокращённый текст.", "balance_message": "52011 символов" } ``` ### Ограничения - Стоимость: 500 символов за запрос - Длина исходного текста: 400 – 24 000 символов - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Хранение результата: 24 часа Стоимость фиксированная и не зависит от объёма текста. Как и в перефразировании, задача, созданная во время обработки предыдущей, не отклоняется, а ждёт своей очереди (`notice.type = "limit"` при опросе). ### Пример на Python ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} text = ( "Искусственный интеллект объединяет в себе несколько научных направлений: " "нейронные сети, машинное обучение, обработку естественного языка, когнитивные " "вычисления и компьютерное зрение. Однако чёткого представления о том, что именно " "входит в понятие искусственного интеллекта, нет, так как нет общепринятых критериев " "разумности и соответствия человеческому интеллекту." ) * 3 # исходный текст должен быть не короче 400 символов # 1. Создаём задачу. В работе может быть только одна задача. payload = { "text": text, "requiredLength": "250", # см. таблицу допустимых значений "mode": "whole", } resp = requests.post(f"{BASE}/create-reduction-job", headers=headers, data=payload) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] print("Задача создана:", job_id) # 2. Опрашиваем статус не чаще одного раза в секунду. while True: time.sleep(1) ping = requests.get(f"{BASE}/ping-reduction-job", params={"job_id": job_id}) ping.raise_for_status() data = ping.json() if data["status"] == "completed": print("Результат:", data["result_text"]) print("Баланс:", data["balance_message"]) break if data["status"] == "error": raise SystemExit(data.get("message")) ``` --- ## Генерация текста 44 шаблона генерации: тексты, письма, рефераты, посты, описания товаров, стихи. Основной способ — синхронный запрос: одно соединение, в ответ приходит готовый текст. ### Синхронная генерация Работает для всех шаблонов, кроме poem и song-text. `POST /create-write-sync/<идентификатор-шаблона>` — требуется Bearer-токен, формат: form-data Идентификатор шаблона подставляется в URL — например `/create-write-sync/text-generator`. Полный список идентификаторов и их параметров — в таблицах ниже. | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `is_stream` | Да | String | Для API всегда `0` — ответ придёт одним готовым JSON. Без этого параметра сервис отдаёт текст потоком по мере генерации. | | `…` | Да | — | Параметры конкретного шаблона — см. таблицу «Параметры шаблонов». | Параметр `is_stream` читается только из тела формы. Если отправить запрос в формате JSON, он не будет учтён и ответ придёт потоком. Отправляйте тело как `application/x-www-form-urlencoded` или `multipart/form-data`. Ответ при `is_stream=0`: ```json { "status": "completed", "data": "Сгенерированный текст", "job_id": "94d5be99-b9c1-442b-9218-29fc9b3de0b3", "balance": "95068 символов" } ``` Готовый текст находится в поле `data`. Время ответа зависит от объёма результата, поэтому задайте таймаут клиента с запасом — 120 секунд и более. Ошибки этого эндпоинта возвращаются с суффиксом-разделителем `--END--` в конце тела — он используется в потоковом режиме. При разборе ответа отбрасывайте этот суффикс, если он есть (в примере ниже это учтено). ### Асинхронная генерация Единственный способ для шаблонов poem (стихи) и song-text (текст песни); для остальных шаблонов тоже доступен. `POST /create-write-job/<идентификатор-шаблона>` — требуется Bearer-токен, формат: form-data Параметры — те же, что у синхронного метода, но без `is_stream`. Ответ: ```json { "status": "completed", "message": "Идет подготовка к обработке, пожалуйста, ожидайте...", "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341" } ``` `GET /ping-write-job?job_id=` — без токена Пока задача обрабатывается: ```json { "status": "continue", "message": "Нейросеть Robotext генерирует текст... ✏️", "notice": {"type": "generating", "seconds": 30} } ``` По готовности: ```json { "status": "completed", "result": "Сгенерированный текст", "result_len": 1024, "balance": "95068 символов" } ``` Обратите внимание на разные имена полей: в синхронном ответе текст лежит в `data`, в асинхронном — в `result`. ### Ограничения - Стоимость: длина сгенерированного текста - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Хранение результата: 24 часа Если предыдущая генерация ещё не завершилась, новый запрос **отклоняется** с `notice.type = "limit"` — дождитесь её окончания. Запрос также проходит проверку контента: при отклонении приходит `notice.type = "moderation"`. ### Идентификаторы шаблонов и их параметры ### Общие шаблоны | Идентификатор | Назначение | Параметры | |---|---|---| | `text-generator` | Генератор текста | `text` — требования к тексту, до 24 000 | | `phrase-generator` | Генератор фраз и предложений | `lang` — `0` русский, `1` английский; `text` — исходные слова, до 1 000 | | `continue-text` | Продолжение текста | `text` — исходный текст, до 4 000 | | `create-questions` | Генератор вопросов | `text` — исходный текст, до 24 000 | | `create-dialogue` | Генератор диалогов | `people` — участники, до 200; `theme` — тема, до 400; `add` — детали, до 1 500 (необяз.) | | `synonymizer` | Синонимайзер | `text` — слово или фраза, до 140 | | `keywords` | Вписать ключевые слова | `keywords` — ключи, до 500; `text` — исходный текст, до 10 000 | | `expand-text` | Расширение текста | `text` — исходный текст, до 2 000 | | `nickname` | Генератор никнеймов | `text` — описание, до 2 000; `radio` — `value1` английский, `value2` русский | | `team-name` | Название команды | `text` — детали, до 2 000; `radio` — `value1` английский, `value2` русский | ### Бизнес и работа | Идентификатор | Назначение | Параметры | |---|---|---| | `commercial-offer` | Коммерческое предложение | `service` — предложение, до 300; `client` — получатель, до 200 (необяз.); `add` — детали, до 2 000 (необяз.) | | `email` | Генератор письма | `text` — суть письма, до 2 000; `client` — получатель, до 200 (необяз.) | | `complaint` | Жалоба, претензия, заявление | `style` — `0` жалоба, `1` претензия, `2` заявление; `name` — кому, до 200 (необяз.); `text` — детали, до 2 000 | | `naming` | Нейминг | `style` — `0` бренд, `1` магазин, `2` Telegram-канал, `3` YouTube-канал; `text` — детали, до 2 000 | | `business-plan` | Бизнес-план | `text` — детали о бизнесе, до 2 000 | | `marketing-plan` | Маркетинговый план | `text` — детали о бизнесе, до 2 000 | | `slogan` | Генератор слоганов | `text` — детали бренда, до 2 000 | ### Учёба | Идентификатор | Назначение | Параметры | |---|---|---| | `paper` | Генератор рефератов | `text` — тема, до 2 000 | | `intro` | Генератор введения | `text` — тема текста, до 12 000 | | `essay` | Генератор эссе | `text` — тема эссе, до 2 000 | | `composition` | Генератор сочинений | `text` — тема сочинения, до 2 000 | | `annotation` | Генератор аннотаций | `text` — тема, до 2 000; `text_type` — `0` диплом, `1` статья, `2` книга | ### Творчество | Идентификатор | Назначение | Параметры | |---|---|---| | `story` | Генератор историй | `text` — тема истории, до 2 000 | | `idea` | Идеи и сюжеты для книг | `text` — тема сюжета, до 2 000 | | `character-history` | История персонажа | `name` — имя, до 200; `text` — детали, до 2 000 | | `scenario` | Генератор сценария | `name` — имена персонажей, до 400; `text` — детали сюжета, до 2 000 | | `poem` (только асинхронно) | Генератор стихов | `radio` — `value1` тема, `value2` первая строчка; `keys` — тема или строка, до 80 | | `poem-idea` | Идеи для стихов | `text2` — требования, до 2 000 (необяз.) | | `song-text` (только асинхронно) | Генератор текста песни | `radio` — `value1` тема, `value2` первая строчка; `keys` — тема или строка, до 80 | | `song-idea` | Темы для песен | `text2` — требования, до 2 000 (необяз.) | | `fanfiction` | Генератор фанфиков | `name` — имена персонажей, до 400; `text` — детали сюжета, до 2 000 | | `song-rap` | Текст для рэпа | `text` — тема трека, до 2 000; `keys2` — ключевые слова, до 500 (необяз.) | | `quote` | Генератор цитат | `text2` — тема, до 500 (необяз.); `source` — автор или произведение, до 500 (необяз.) | | `quiz` | Генератор викторин | `text` — тема викторины, до 500 | Шаблоны `poem` и `song-text` доступны **только** через асинхронный эндпоинт `/create-write-job/…`; синхронный вернёт для них 404. Кроме того, для них действует более строгая проверка языка: доля русского текста в запросе должна быть не меньше 50%. ### Социальные сети | Идентификатор | Назначение | Параметры | |---|---|---| | `post-header` | Генератор заголовков | `style` — `0` статья, `1` новость, `2` видео; `name` — тема, до 200; `keys2` — ключевые слова, до 2 000 (необяз.) | | `create-post` | Генератор постов | `text` — тема поста, до 500; `keys2` — ключевые слова, до 2 000 (необяз.) | | `post-plan` | План статьи | `text` — тема статьи, до 500; `keys2` — ключевые слова, до 2 000 (необяз.) | | `content-plan` | Контент-план | `text` — детали о блоге, до 2 000 | ### SEO и вебсайты | Идентификатор | Назначение | Параметры | |---|---|---| | `seo-text` | Генератор SEO-текста | `text` — тема текста, до 500; `seo_keys` — ключевые слова, до 2 000 (необяз.) | | `html-description` | Мета-тег Description | `text` — детали страницы, до 16 000 | | `html-keywords` | Ключевые слова для страницы | `radio` — `value1` простой список, `value2` мета-тег Keywords; `text` — детали текста, до 16 000 | ### Маркетплейсы | Идентификатор | Назначение | Параметры | |---|---|---| | `product-description` | Описание товара | `name` — название, до 200; `product_keys` — ключевые слова, до 2 000 (необяз.) | | `product-review` | Генератор отзывов | `style` — `0` товар, `1` услуга; `mood` — `0` позитивный, `1` негативный, `2` нейтральный; `name` — название, до 200; `product_keys` — ключевые слова, до 2 000 (необяз.) | ### Праздники | Идентификатор | Назначение | Параметры | |---|---|---| | `congratulation` | Генератор поздравлений | `person` — кого поздравить, до 500; `text` — с чем, до 1 000; `who` — от кого, до 500 (необяз.) | ### Пример на Python: синхронная генерация ```python import json import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # is_stream=0 — получить готовый текст одним ответом. # Тело обязательно form-encoded: в JSON параметр is_stream не читается. payload = { "is_stream": "0", "text": "Напиши историю о путешествии на Байкал", } resp = requests.post( f"{BASE}/create-write-sync/text-generator", headers=headers, data=payload, timeout=180, # генерация длинного текста занимает время ) resp.raise_for_status() # Ошибки приходят с техническим суффиксом-разделителем — отбрасываем его. body = resp.text.split("--END--")[0] data = json.loads(body) if data["status"] == "error": raise SystemExit(data.get("data") or data.get("message")) print(data["data"]) print("Баланс:", data["balance"]) ``` ### Пример на Python: асинхронная генерация (стихи) ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # 1. Создаём задачу. Очереди на стороне сервиса нет: в работе только одна задача, # новый запрос до её завершения будет отклонён. payload = { "radio": "value1", # value1 — задаём тему, value2 — первую строчку "keys": "Осень в горах", # не длиннее 80 символов } resp = requests.post(f"{BASE}/create-write-job/poem", headers=headers, data=payload) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] # 2. Опрашиваем статус не чаще одного раза в секунду. while True: time.sleep(1) ping = requests.get(f"{BASE}/ping-write-job", params={"job_id": job_id}) ping.raise_for_status() data = ping.json() if data["status"] == "completed": print(data["result"]) # в асинхронном ответе поле result print("Символов:", data["result_len"]) break if data["status"] == "error": raise SystemExit(data.get("message")) ``` --- ## Изображения ### Генерация изображений Асинхронный сервис: создаём задачу, опрашиваем статус, скачиваем готовое изображение по своей ссылке. ### Создание задачи `POST /create-image-job` — требуется Bearer-токен, формат: form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `text` | Да | String | Описание изображения. От 4 до 900 символов, доля букв в тексте — не менее 30%. | | `aspect` | Нет | String | Формат изображения, по умолчанию `1x1`. Допустимые значения — в таблице ниже. | | `style` | Нет | String | Стиль обработки, по умолчанию `nostyle`. Допустимые значения — в таблице ниже. | Ответ: ```json { "status": "completed", "message": "Идет подготовка к обработке, пожалуйста, ожидайте...", "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341" } ``` ### Получение результата `GET /ping-image-job?job_id=` — без токена Пока идёт генерация: ```json { "status": "continue", "message": "Нейросеть Robotext генерирует изображение... 🖌️", "notice": {"type": "generating", "seconds": 10} } ``` По готовности: ```json { "status": "completed", "result": "ef3d4aa6-169a-470e-9814-cd93de65c341", "balance": "106 🖼️" } ``` Поле `result` совпадает с `job_id` и используется для скачивания. ### Скачивание изображения `GET /im/.png` — требуется Bearer-токен Скачивание требует Bearer-токен: сгенерированные изображения недоступны по прямой ссылке — так они остаются приватными. Без токена сервис вернёт «Задание не найдено». В ответе приходят байты изображения. Несмотря на расширение `.png` в адресе, фактический тип файла указан в заголовке `Content-Type` и может быть `image/jpeg`. ### Форматы изображения | aspect | Разрешение | aspect | Разрешение | |---|---|---|---| | `1x1` | 1024 × 1024 | `21x9` | 1344 × 576 | | `9x21` | 576 × 1344 | `16x9` | 1280 × 720 | | `9x16` | 720 × 1280 | `3x2` | 1248 × 832 | | `2x3` | 832 × 1248 | `4x3` | 1152 × 864 | | `3x4` | 864 × 1152 | `9x7` | 1152 × 896 | | `7x9` | 896 × 1152 | | | ### Стили обработки Значение `style` передаётся строкой. Без стиля — `nostyle`. ### Популярные `nostyle`, `misc-anime`, `vector`, `game-gta`, `photo-hdr` ### Художественные стили `artstyle-abstract`, `artstyle-abstract_expressionism`, `artstyle-art_deco`, `artstyle-art_nouveau`, `artstyle-constructivist`, `artstyle-cubist`, `artstyle-expressionist`, `artstyle-graffiti`, `artstyle-hyperrealism`, `artstyle-impressionist`, `artstyle-pixelart`, `artstyle-pointillism`, `artstyle-pop_art`, `artstyle-psychedelic`, `artstyle-renaissance`, `artstyle-steampunk`, `artstyle-surrealist`, `artstyle-typography`, `artstyle-watercolor` ### Фото `photo-alien`, `photo-analog_film`, `photo-film_noir`, `photo-glamour`, `photo-iphone_photographic`, `photo-long_exposure`, `photo-neon_noir`, `photo-silhouette`, `photo-tilt-shift` ### Разное `misc-3d`, `misc-architectural`, `misc-disco`, `misc-dreamscape`, `misc-dystopian`, `misc-fairy_tale`, `misc-gothic`, `misc-grunge`, `misc-horror`, `misc-kawaii`, `misc-lovecraftian`, `misc-macabre`, `misc-manga`, `misc-metropolis`, `misc-minimalist`, `misc-monochrome`, `misc-nautical`, `misc-space`, `misc-stained_glass`, `misc-techwear_fashion`, `misc-tribal`, `misc-zentangle` ### Игры `game-warhammer40`, `game-fortnite`, `game-bubble_bobble`, `game-cyberpunk_game`, `game-fighting_game`, `game-mario`, `game-minecraft`, `game-pokemon`, `game-retro_arcade`, `game-retro_game`, `game-rpg_fantasy_game`, `game-strategy_game`, `game-streetfighter`, `game-zelda` ### Реклама `ads-advertising`, `ads-automotive`, `ads-corporate`, `ads-fashion_editorial`, `ads-food_photography`, `ads-gourmet_food_photography`, `ads-luxury`, `ads-real_estate`, `ads-retail` ### Футуризм `futuristic-biomechanical`, `futuristic-biomechanical_cyberpunk`, `futuristic-cybernetic`, `futuristic-cybernetic_robot`, `futuristic-cyberpunk_cityscape`, `futuristic-futuristic`, `futuristic-retro_cyberpunk`, `futuristic-retro_futurism`, `futuristic-sci-fi`, `futuristic-vaporwave` ### Бумага `papercraft-collage`, `papercraft-flat_papercut`, `papercraft-kirigami`, `papercraft-paper_mache`, `papercraft-paper_quilling`, `papercraft-papercut_collage`, `papercraft-papercut_shadow box`, `papercraft-stacked_papercut`, `papercraft-thick_layered_papercut` ### Ограничения - Стоимость: 500 символов за изображение - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Длина описания: 4 – 900 символов Запрос проходит проверку контента. При отклонении приходит `notice.type = "moderation"`, баланс не списывается. ### Пример на Python ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # 1. Создаём задачу. Очереди на стороне сервиса нет: пока эта задача # не завершится, новые запросы будут отклонены. payload = { "text": "Девушка гуляет по новогодней Москве", "aspect": "1x1", # формат из таблицы форматов "style": "nostyle", # стиль из таблицы стилей } resp = requests.post(f"{BASE}/create-image-job", headers=headers, data=payload) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] print("Задача создана:", job_id) # 2. Опрашиваем статус не чаще одного раза в секунду. while True: time.sleep(1) ping = requests.get(f"{BASE}/ping-image-job", params={"job_id": job_id}) ping.raise_for_status() data = ping.json() if data["status"] == "completed": image_id = data["result"] # совпадает с job_id break if data["status"] == "error": raise SystemExit(data.get("message")) # 3. Скачиваем изображение — обязательно с токеном. img = requests.get(f"{BASE}/im/{image_id}.png", headers=headers) img.raise_for_status() with open("image.png", "wb") as f: f.write(img.content) print("Изображение сохранено в image.png") ``` --- ## Редактирование фото Синхронный сервис: загружаете фото, указываете инструмент — и получаете обработанное изображение одним запросом. 41 инструмент в 7 категориях. Исходные фото **нигде не сохраняются**: файлы проверяются в памяти и передаются обработчику. Хранится только результат. ### Обработка `POST /image-edit/process` — требуется Bearer-токен, формат: multipart/form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `page` | Да | String | Идентификатор инструмента из списка ниже. От него зависит, какие ещё параметры принимаются. | | `images` | Да | File[] | Файлы изображений. Для большинства инструментов — до 3 файлов, для «удалить фон» и «увеличить разрешение» — ровно 1. Поле повторяется для каждого файла. | | `main` | Нет | Integer | Индекс основного фото в списке, по умолчанию `0`. Основное фото используется как база, остальные — как референсы. | | `query` | Нет | String | Свой запрос на русском, обычно 10–300 или 10–400 символов в зависимости от инструмента. Если не передан — используется стандартный запрос инструмента. | | `resolution` | Нет | String | Разрешение результата, по умолчанию `source` (как в исходном фото). См. ниже. | | `background` | Нет | String | Только для `udalit-fon-tovara`: `transparent` (по умолчанию) или `white`. | | `scale` | Нет | String | Только для `uvelichit-razreshenie`: `2` (по умолчанию) или `4` — во сколько раз увеличить. | ### Значения resolution `source` — сохранить пропорции исходного фото (по умолчанию). Либо один из форматов: `1x1`, `9x7`, `7x9`, `4x3`, `3x4`, `3x2`, `2x3`, `16x9`, `9x16`, `21x9`, `9x21`. Либо точный размер вида `1024x768` — каждая сторона от 16 до 1536 пикселей. Ответ: ```json { "status": "completed", "job_id": "3d1f8c2b-7a45-4e19-b0d3-6f2a9c81e5b7", "image_url": "https://robotext.io/ime/3d1f8c2b-7a45-4e19-b0d3-6f2a9c81e5b7.png", "balance": 4500 } ``` Поле `image_url` приходит только при запросе с токеном. Обработка занимает до двух минут — установите таймаут клиента не менее 180 секунд. ### Скачивание результата `GET /ime/.png` — требуется Bearer-токен Тот же адрес, что в поле `image_url`. Требует Bearer-токен: результаты недоступны по прямой ссылке. ### Инструменты Значение параметра `page`. В колонке «Текст» указано, принимает ли инструмент параметр `query`. ### Товары и маркетплейсы | page | Что делает | Фото | Текст | |---|---|---|---| | `udalit-fon-tovara` | Удалить фон | 1 | нет, вместо него `background` | | `zamena-fona-tovara` | Заменить фон товара | до 3 | да, 10–400 | | `foto-tovara-wildberries` | Фото для Wildberries | до 3 | да, 10–300 | | `foto-tovara-ozon` | Фото для Ozon | до 3 | да, 10–300 | | `odezhda-na-ai-model` | Одежда на модели | до 3 | да, 10–400 | ### Деловое фото и портреты | page | Что делает | Фото | Текст | |---|---|---|---| | `biznes-portret` | Деловой портрет | до 3 | да, 10–300 | | `foto-na-rezyume` | Фото для резюме | до 3 | да, 10–300 | | `avatar-dlya-profilya` | Аватар для профиля | до 3 | да, 10–300 | | `retush-portreta` | Ретушь портрета | до 3 | да, 10–300 | ### Реставрация и качество | page | Что делает | Фото | Текст | |---|---|---|---| | `restavratsiya-foto` | Реставрация старого фото | до 3 | да, 10–300 | | `kolorizatsiya-foto` | Раскрасить чёрно-белое фото | до 3 | да, 10–300 | | `uluchshit-kachestvo-foto` | Улучшить качество | до 3 | да, 10–300 | | `uvelichit-razreshenie` | Увеличить разрешение | 1 | нет, вместо него `scale` | ### Объекты и сцена | page | Что делает | Фото | Текст | |---|---|---|---| | `udalit-obekt-s-foto` | Удалить объект | до 3 | да, 10–400 | | `udalit-cheloveka-s-foto` | Убрать человека | до 3 | да, 10–300 | | `ubrat-vodyanoy-znak` | Убрать водяной знак | до 3 | да, 10–300 | | `udalit-tekst-s-foto` | Удалить текст с фото | до 3 | да, 10–300 | | `rasshirit-foto` | Расширить кадр | до 3 | да, 10–300 | | `otredaktirovat-foto` | Произвольное редактирование | до 3 | да, 3–300 | ### Склейка и объединение | page | Что делает | Фото | Текст | |---|---|---|---| | `obedinit-dva-foto` | Объединить два фото | до 3 | да, 10–300 | | `zamena-litsa` | Заменить лицо | до 3 | да, 10–300 | | `sovmestnoe-foto` | Совместное фото | до 3 | да, 10–300 | | `kollazh-iz-foto` | Коллаж из фото | до 3 | да, 10–300 | | `primerit-odezhdu` | Примерить одежду | до 3 | да, 10–300 | | `primerit-prichesku` | Примерить причёску | до 3 | да, 10–400 | | `semeynyy-portret` | Семейный портрет | до 3 | да, 10–300 | ### Интерьер и недвижимость | page | Что делает | Фото | Текст | |---|---|---|---| | `dizayn-interera` | Дизайн интерьера | до 3 | да, 10–400 | | `virtualnyy-steydzhing` | Обставить пустую комнату | до 3 | да, 10–400 | | `dizayn-remonta` | Показать ремонт | до 3 | да, 10–400 | | `dizayn-kuhni` | Дизайн кухни | до 3 | да, 10–400 | | `dizayn-spalni` | Дизайн спальни | до 3 | да, 10–400 | | `dizayn-detskoy` | Дизайн детской | до 3 | да, 10–400 | | `dizayn-vannoy` | Дизайн ванной | до 3 | да, 10–400 | | `dizayn-fasada` | Дизайн фасада | до 3 | да, 10–400 | ### Креатив и стилизация | page | Что делает | Фото | Текст | |---|---|---|---| | `foto-v-stile-anime` | Фото в стиле аниме | до 3 | да, 10–300 | | `foto-v-multik` | Фото в мультик | до 3 | да, 10–300 | | `sharzh-iz-foto` | Шарж из фото | до 3 | да, 10–400 | | `foto-v-risunok` | Фото в рисунок | до 3 | да, 10–400 | | `ai-avatar` | Аватар по фото | до 3 | да, 10–400 | | `portret-pitomtsa` | Портрет питомца | до 3 | да, 10–400 | | `vozrastnoy-filtr` | Возрастной фильтр | до 3 | да, 10–300 | ### Требования к изображениям - Размер файла: до 15 МБ - Разрешение: до 10000 × 10000 px - Разрешение для увеличения: до 1200 × 1200 px - Форматы: JPEG, PNG, WEBP, GIF, BMP, TIFF, HEIC/HEIF ### Ограничения - Стоимость: 500 символов за запрос - Одновременных задач: 1 - Максимум фото за запрос: 3 Результат проходит проверку контента: при отклонении приходит `notice.type = "moderation"`, изображение не отдаётся и баланс не списывается. Три отклонения подряд блокируют новые запросы. ### Пример на Python ```python import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # Запрос синхронный: обработанное фото возвращается сразу. # Очереди на стороне сервиса нет — в работе может быть только одна задача. with open("product.jpg", "rb") as f: resp = requests.post( f"{BASE}/image-edit/process", headers=headers, files=[("images", f)], # для нескольких фото повторите поле images data={ "page": "udalit-fon-tovara", "background": "transparent", # transparent | white }, timeout=180, ) resp.raise_for_status() data = resp.json() if data["status"] == "error": raise SystemExit(data.get("message")) # Результат скачиваем по ссылке из ответа — тоже с токеном. image = requests.get(data["image_url"], headers=headers) image.raise_for_status() with open("result.png", "wb") as f: f.write(image.content) print("Готово, сохранено в result.png. Остаток символов:", data["balance"]) ``` --- ## Анализ фото ### Анализ фото (OCR) Синхронный сервис: загружаете изображение, выбираете подсервис — и получаете текстовый ответ одним запросом. Каждый подсервис решает свою задачу: распознать текст, определить растение, решить задачу с фото. Изображение **нигде не сохраняется**: файл проверяется в памяти, отправляется в модель и стирается. В историю запросов попадает только имя файла и текст ответа. ### Обработка изображения `POST /ocr/process` — требуется Bearer-токен, формат: multipart/form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `image` | Да | File | Один файл изображения. Ограничения — в таблице ниже. | | `page` | Да | String | Идентификатор подсервиса из списка ниже. Определяет, что именно модель сделает с изображением. | | `query` | Нет | String | Собственный запрос к изображению, от 10 до 300 символов. Если не передан — используется стандартный запрос выбранного подсервиса. | Ответ приходит одним JSON — это синхронный запрос, опрашивать статус не нужно: ```json { "status": "completed", "text": "Полный текст ответа модели", "job_id": "0f4c8e2a-6b1d-4f77-9c3e-2a5b7d8e1f04", "balance": 4500 } ``` Поле `balance` — остаток баланса в символах (число). Ответ модели формируется постепенно, поэтому запрос может выполняться десятки секунд. Установите таймаут клиента не менее 120 секунд. ### Подсервисы Значение параметра `page`: | page | Что делает | |---|---| | `opisat-izobrazhenie` | Описать изображение | | `proanalizirovat-izobrazhenie` | Проанализировать изображение | | `raspoznat-tekst-s-foto` | Распознать текст с фото | | `perevesti-tekst-s-foto` | Перевести текст с фото | | `raspoznat-rukopisnyy-tekst` | Распознать рукописный текст | | `opredelit-obekt-na-foto` | Определить объект на фото | | `nayti-mesto-po-foto` | Найти место по фото | | `opisat-vneshnost-cheloveka` | Описать внешность человека | | `opredelit-tip-lica-po-foto` | Определить тип лица | | `opredelit-shrift-po-foto` | Определить шрифт | | `opredelit-rastenie-po-foto` | Определить растение | | `opredelit-bolezn-rasteniya` | Определить болезнь растения | | `opredelit-pticu-po-foto` | Определить птицу | | `opredelit-zhivotnoe-po-foto` | Определить животное | | `opredelit-porodu-po-foto` | Определить породу | | `reshit-zadachu-po-foto` | Решить задачу по фото | ### Требования к изображению - Размер файла: до 15 МБ - Разрешение: до 10000 × 10000 px - Форматов: JPEG, PNG, WEBP, GIF, BMP, TIFF, HEIC/HEIF - Файлов за запрос: 1 Векторные форматы (SVG) не принимаются. При ошибке файла в ответе приходит `error_type`: `size` — превышен размер, `resolution` — превышено разрешение, `format` — неподдерживаемый формат, `invalid` — файл не является изображением. ### Ограничения - Стоимость: 500 символов за запрос - Одновременных задач: 1 - Длина своего запроса: 10 – 300 символов Результат проходит проверку контента: при отклонении приходит `notice.type = "moderation"` и баланс не списывается. Три отклонения подряд блокируют новые запросы (`notice.type = "moderation_block"`). ### Пример на Python ```python import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # Запрос синхронный: ответ приходит сразу, опрашивать статус не нужно. # В работе может быть только одна задача — дождитесь ответа перед следующим запросом. with open("photo.jpg", "rb") as f: resp = requests.post( f"{BASE}/ocr/process", headers=headers, files={"image": f}, data={ "page": "raspoznat-tekst-s-foto", # "query": "Извлеки только числа из таблицы", # необязательный свой запрос }, timeout=180, ) resp.raise_for_status() data = resp.json() if data["status"] == "error": raise SystemExit(data.get("message")) print(data["text"]) print("Остаток символов:", data["balance"]) ``` --- ## Презентации ### Генерация презентаций Асинхронный сервис: по теме или готовому тексту собирается презентация с текстом и изображениями. Результат доступен в форматах PPTX и PDF. ### Создание задачи `POST /create-presentation-job` — требуется Bearer-токен, формат: form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `topic` | Да* | String | Тема презентации, до 300 символов. *Нужно передать `topic` или `text` — хотя бы одно из двух. | | `text` | Да* | String | Готовый текст, по которому собирается презентация, до 24 000 символов. | | `slide_count` | Да | String | Количество слайдов: `10`, `15` или `20`. | | `template` | Да | String | Шаблон оформления — см. таблицу ниже. | ### Шаблоны оформления | template | Оформление | |---|---| | `basic` | Базовый | | `organic` | Бежевый | | `color` | Цветной | | `modern` | Строгий | | `black` | Чёрный | | `plain` | Без стиля | Ответ: ```json { "status": "completed", "message": "Подготовка к генерации примера", "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341" } ``` ### Получение результата `GET /ping-presentation-job?job_id=` — без токена Пока идёт генерация — в ответе есть числовой прогресс от 1 до 100: ```json { "status": "continue", "message": "Генерация слайда 4/10", "progress": 38, "notice": {"type": "generating", "progress": 38, "label": "Генерация слайда 4/10"} } ``` По готовности: ```json { "status": "completed", "result": { "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341", "title": "Дореволюционная Москва" }, "balance": "5 🖥" } ``` Идентификатор презентации совпадает с `job_id`, а `title` — это сгенерированное название, оно же станет именем скачиваемого файла. ### Скачивание презентации `GET /download-presentation?job_id=&format=pptx` — требуется Bearer-токен | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `job_id` | Да | String | Идентификатор задачи. | | `format` | Нет | String | `pptx` или `pdf`. По умолчанию — `pdf`. | Скачивание требует Bearer-токен — презентации недоступны по прямой ссылке. Файл отдаётся как вложение, имя файла — название презентации из поля `title`. ### Ограничения - Стоимость: 10 000 символов за презентацию - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Слайдов: 10, 15 или 20 Генерация презентации доступна только при балансе от 10 000 символов. Если баланса не хватает, приходит ошибка с `notice.type = "paywall_balance"`. ### Пример на Python ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # 1. Создаём задачу. Очереди на стороне сервиса нет: в работе только одна задача. payload = { "topic": "Дореволюционная Москва", # либо text — готовый текст до 24 000 символов "slide_count": "10", # 10, 15 или 20 "template": "organic", # basic | organic | color | modern | black | plain } resp = requests.post(f"{BASE}/create-presentation-job", headers=headers, data=payload) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] print("Задача создана:", job_id) # 2. Опрашиваем статус не чаще одного раза в секунду. while True: time.sleep(1) ping = requests.get(f"{BASE}/ping-presentation-job", params={"job_id": job_id}) ping.raise_for_status() data = ping.json() if data["status"] == "completed": print("Готово:", data["result"]["title"]) break if data["status"] == "error": raise SystemExit(data.get("message")) print("Прогресс:", data.get("progress"), data.get("message")) # 3. Скачиваем оба формата — обязательно с токеном. for fmt in ("pptx", "pdf"): file_resp = requests.get( f"{BASE}/download-presentation", headers=headers, params={"job_id": job_id, "format": fmt}, ) file_resp.raise_for_status() with open(f"presentation.{fmt}", "wb") as f: f.write(file_resp.content) print(f"Сохранено: presentation.{fmt}") ``` --- ## Песни ### Генерация песен Асинхронный сервис: по тексту песни и музыкальному стилю генерируется готовый аудиотрек с вокалом или без него. ### Создание задачи `POST /create-song-job` — требуется Bearer-токен, формат: form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `preset_style` | Да | String | Музыкальный пресет из списка ниже либо `__custom__` — тогда стиль берётся из поля `genre`. | | `genre` | Да | String | Описание музыкального стиля своими словами, до 250 символов. Учитывается только при `preset_style=__custom__`, но передать поле нужно всегда. | | `text` | Да* | String | Текст песни, от 10 до 2 500 символов. *Не требуется при `vocals=none` (инструментал). | | `title` | Да | String | Название песни, от 3 до 50 символов. | | `vocals` | Да | String | Вокал: `random` — случайный, `female` — женский, `male` — мужской, `none` — без вокала. | | `time_period` | Да | Integer | Длительность песни в секундах, от 30 до 240. | | `format_file` | Да | String | Формат файла: `mp3` или `wav`. | ### Музыкальные пресеты Значение `preset_style` передаётся строкой ровно как написано: `Поп`, `K-pop`, `Романтическая`, `Народная`, `Военно-патриотическая`, `Шансон`, `Детская`, `Хип-хоп / Рэп`, `Трэп`, `Дрилл`, `Фонк`, `Рок`, `Альтернативный рок`, `Панк`, `Металл`, `R&B`, `Соул`, `Регги`, `Реггетон`, `EDM`, `Диско`, `Хаус`, `Техно`, `Drum & Bass` Чтобы задать стиль своими словами, передайте `preset_style=__custom__` и опишите звучание в поле `genre` — например: «поп, данс-поп, яркие синты, ритм-гитары, хлопки, 115 bpm, бодрый, радиоформат». Ответ: ```json { "status": "completed", "message": "Подготовка к генерации", "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341" } ``` ### Получение результата `GET /ping-song-job?job_id=` — без токена Пока идёт генерация: ```json { "status": "continue", "message": "Генерация песни", "progress": 57, "notice": {"type": "generating", "progress": 57, "label": "Генерация песни"} } ``` По готовности: ```json { "status": "completed", "result": { "job_id": "ef3d4aa6-169a-470e-9814-cd93de65c341", "title": "Моя первая песня", "audio_data": "https://s3.timeweb.cloud/2b659743-song100/...", "video_data": "https://s3.timeweb.cloud/2b659743-song100/..." }, "balance": "5 🎶" } ``` | Поле | Описание | |---|---| | `audio_data` | Прямая ссылка на аудиофайл. Подписанная, действует 1 час, дополнительная авторизация не нужна. | | `video_data` | Ссылка на видеоверсию песни (аудио с фоном). | | `title` | Название песни — оно же имя файла при скачивании через `/download-song`. | ### Скачивание песни Есть два способа: перейти по ссылке `audio_data` в течение часа либо скачать файл через эндпоинт с токеном — эта ссылка не истекает. `GET /download-song?job_id=&format=mp3` — требуется Bearer-токен | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `job_id` | Да | String | Идентификатор задачи. | | `format` | Нет | String | `mp3` или `wav` — тот же формат, что запрашивали при создании. По умолчанию `mp3`. | ### Ограничения - Стоимость: 10 000 символов за песню - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Длительность: 30 – 240 секунд - Текст песни: 10 – 2 500 символов - Срок действия audio_data: 1 час ### Пример на Python ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # 1. Создаём задачу. Очереди на стороне сервиса нет: в работе только одна задача. payload = { "preset_style": "__custom__", # либо готовый пресет, например "Поп" "genre": "поп, данс-поп, яркие синты, бодрый хит, 115 bpm", "title": "Моя первая песня", # 3–50 символов "text": "Один два три четыре пять\nШесть семь восемь девять десять", "vocals": "female", # random | female | male | none "time_period": "60", # секунды, 30–240 "format_file": "mp3", # mp3 | wav } resp = requests.post(f"{BASE}/create-song-job", headers=headers, data=payload) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] print("Задача создана:", job_id) # 2. Опрашиваем статус не чаще одного раза в секунду. while True: time.sleep(1) ping = requests.get(f"{BASE}/ping-song-job", params={"job_id": job_id}) ping.raise_for_status() data = ping.json() if data["status"] == "completed": print("Готово:", data["result"]["title"]) break if data["status"] == "error": raise SystemExit(data.get("message")) print("Прогресс:", data.get("progress")) # 3. Скачиваем файл через эндпоинт с токеном — эта ссылка не истекает, # в отличие от audio_data (она действует 1 час). song = requests.get( f"{BASE}/download-song", headers=headers, params={"job_id": job_id, "format": "mp3"}, ) song.raise_for_status() with open("song.mp3", "wb") as f: f.write(song.content) print("Песня сохранена в song.mp3") ``` --- ## Видео ### Генерация видео Асинхронный сервис: ролик генерируется по текстовому описанию, по фото или по фото вместе с описанием. Создаём задачу, опрашиваем статус, скачиваем готовый MP4. ### Создание задачи `POST /create-video-job` — требуется Bearer-токен, формат: multipart/form-data | Поле | Обяз. | Тип | Описание | |---|---|---|---| | `query` | Да | String | Описание сцены на русском, от 10 до 20 000 символов. Описание автоматически дорабатывается перед генерацией. | | `page` | Нет | String | Идентификатор подсервиса из списка ниже. От него зависит, сколько фото принимается и как обрабатывается кадр. | | `seconds` | Нет | Integer | Длительность ролика в секундах, от 4 до 12. По умолчанию 4. | | `resolution` | Нет | String | Формат кадра, по умолчанию `16x9`. Значение `auto` подбирает формат по пропорциям первого фото. | | `images` | Нет | File[] | Фото для первого кадра. Максимум зависит от подсервиса (1–3). Поле повторяется для каждого файла. | | `main` | Нет | Integer | Индекс основного фото, по умолчанию `0`. | | `image_last` | Нет | File | Последний кадр — только для подсервиса `video-mezhdu-dvumya-kadrami`. Требует загруженного первого кадра. | ### Форматы кадра | resolution | Разрешение | Ориентация | |---|---|---| | `16x9` | 1344 × 768 | горизонтальное | | `3x2` | 1152 × 768 | горизонтальное | | `4x3` | 1024 × 768 | горизонтальное | | `9x7` | 992 × 768 | горизонтальное | | `1x1` | 768 × 768 | квадратное | | `7x9` | 768 × 992 | вертикальное | | `3x4` | 768 × 1024 | вертикальное | | `2x3` | 768 × 1152 | вертикальное | | `9x16` | 768 × 1344 | вертикальное | | `auto` | по пропорциям фото | — | Ответ: ```json { "status": "completed", "message": "Подготовка к генерации", "job_id": "8ac2f1e0-3d54-4b8a-9e17-c05f2b6d4a93" } ``` ### Получение результата `GET /ping-video-job?job_id=` — требуется Bearer-токен Пока идёт генерация — прогресс от 0 до 100: ```json { "status": "continue", "message": "Генерация видео", "progress": 42, "notice": {"type": "generating", "progress": 42, "label": "Генерация видео"} } ``` По готовности: ```json { "status": "completed", "balance": "5 🎬", "result": { "job_id": "8ac2f1e0-3d54-4b8a-9e17-c05f2b6d4a93", "video_url": "/vid/8ac2f1e0-3d54-4b8a-9e17-c05f2b6d4a93.mp4", "seconds": 8, "width": 1344, "height": 768, "seed": 1837462913, "demo": false } } ``` | Поле | Описание | |---|---| | `video_url` | Относительный путь к ролику — добавьте адрес сервиса, чтобы получить полную ссылку. | | `seconds`, `width`, `height` | Фактические параметры готового ролика. | | `seed` | Зерно генерации — по нему сцену можно воспроизвести повторно. | | `demo` | `true` — укороченный демо-ролик, скачивание недоступно. | ### Скачивание ролика `GET /vid/.mp4?download=1` — требуется Bearer-токен Требует Bearer-токен. Параметр `download=1` отдаёт файл вложением; без него ролик отдаётся для просмотра. Поддерживается заголовок `Range` — можно скачивать файл частями. Генерация занимает от одной до нескольких минут. Скачивание доступно при активной подписке; демо-ролики (`demo: true`) вернут **HTTP 403** с `notice.type = "paywall_demo"`. Готовый ролик хранится на сервере **4 суток**. ### Подсервисы Значение параметра `page`. В колонке «Фото» — сколько изображений принимает подсервис. ### Основные форматы | page | Что делает | Фото | |---|---|---| | `tekst-v-video` | Видео по текстовому описанию | — | | `foto-v-video` | Оживить фото | 1 | | `video-po-foto-i-opisaniyu` | Видео по фото и описанию | до 3 | | `video-mezhdu-dvumya-kadrami` | Переход между двумя кадрами | 2 + `image_last` | | `video-so-zvukom` | Видео со звуком | — | ### Товар и продажи | page | Что делает | Фото | |---|---|---| | `video-dlya-kartochki-wildberries` | Видео для карточки Wildberries | до 3 | | `video-dlya-kartochki-ozon` | Видео для карточки Ozon | до 3 | | `ozhivit-foto-tovara` | Оживить фото товара | до 3 | | `ugc-reklama-s-ii-akterom` | UGC-реклама с ИИ-актёром | до 3 | | `reklamnyy-rolik-dlya-biznesa` | Рекламный ролик для бизнеса | до 3 | ### Оживление фото | page | Что делает | Фото | |---|---|---| | `ozhivit-staroe-foto` | Оживить старое фото | 1 | | `memorialnoe-video` | Мемориальное видео | 1 | | `govoryashchee-foto` | Говорящее фото | 1 | | `poyushchee-i-tancuyushchee-foto` | Поющее и танцующее фото | 1 | ### Эффекты и тренды | page | Что делает | Фото | |---|---|---| | `ai-obyatie` | ИИ-объятие | 2 | | `ai-poceluy` | ИИ-поцелуй | 2 | | `video-s-pitomcem` | Видео с питомцем | 1 | | `kakim-budet-nash-rebenok` | Каким будет наш ребёнок | 2 | | `kak-ya-budu-vyglyadet-v-starosti` | Как я буду выглядеть в старости | 1 | | `sovmestnoe-video-iz-dvuh-foto` | Совместное видео из двух фото | 2 | | `video-so-znamenitostyu` | Видео со знаменитостью | 2 | | `figurka-i-kukla-iz-foto` | Фигурка или кукла из фото | 1 | | `omolodit-foto` | Омолодить фото | 1 | | `sebya-v-stile-videoigry` | Себя в стиле видеоигры | 1 | | `prevrashchenie-v-supergeroya` | Превращение в супергероя | 1 | | `kak-ya-budu-vyglyadet-esli-pohudeyu` | Как я буду выглядеть, если похудею | 1 | ### Анимация | page | Что делает | Фото | |---|---|---| | `anime-video-iz-foto` | Аниме-видео из фото | 1 | | `ozhivit-risunok` | Оживить рисунок | 1 | ### Аватары и бизнес-видео | page | Что делает | Фото | |---|---|---| | `ii-diktor-v-kadre` | ИИ-диктор в кадре | — | | `cifrovoy-dvoynik-iz-foto` | Цифровой двойник из фото | 1 | | `video-vizitka` | Видеовизитка | 1 | ### Поздравления и события | page | Что делает | Фото | |---|---|---| | `videopozdravlenie-s-dnem-rozhdeniya` | Поздравление с днём рождения | 1 | | `videopozdravlenie-s-novym-godom` | Поздравление с Новым годом | 1 | | `videopozdravlenie-s-8-marta` | Поздравление с 8 Марта | 1 | | `videopozdravlenie-s-23-fevralya` | Поздравление с 23 Февраля | 1 | | `svadebnoe-video-i-priglashenie` | Свадебное видео и приглашение | 2 | | `video-na-yubiley` | Видео на юбилей | 1 | | `video-na-godovshchinu` | Видео на годовщину | 2 | | `video-na-vypusknoy` | Видео на выпускной | 1 | | `videootkrytka` | Видеооткрытка | 1 | ### Видео для соцсетей | page | Что делает | Фото | |---|---|---| | `video-dlya-reels-shorts-tiktok` | Видео для Reels, Shorts и TikTok | до 3 | ### Требования к фото - Размер файла: до 15 МБ - Разрешение: до 10000 × 10000 px - Форматы: JPEG, PNG, WEBP, GIF, BMP, TIFF, HEIC/HEIF ### Ограничения - Стоимость: 10 000 символов за ролик - Одновременных задач: 1 - Частота опроса: не чаще 1 раза в секунду - Длительность: 4 – 12 секунд - Описание сцены: 10 – 20 000 символов - Хранение ролика: 4 суток Описание и загруженные фото проходят проверку контента до начала генерации. При отклонении приходит `notice.type = "moderation"`, баланс не списывается. ### Пример на Python ```python import time import requests TOKEN = "ВАШ_API_ТОКЕН" BASE = "https://robotext.io" headers = {"Authorization": f"Bearer {TOKEN}"} # 1. Создаём задачу. Очереди на стороне сервиса нет: в работе только одна задача, # новый запрос до её завершения будет отклонён. data = { "page": "foto-v-video", "query": "Камера медленно приближается, лёгкий ветер колышет листву", "seconds": "8", # 4–12 "resolution": "16x9", # либо auto — по пропорциям фото } with open("photo.jpg", "rb") as f: resp = requests.post( f"{BASE}/create-video-job", headers=headers, files=[("images", f)], # для генерации по одному тексту фото можно не передавать data=data, ) resp.raise_for_status() created = resp.json() if created.get("status") == "error": raise SystemExit(created.get("message")) job_id = created["job_id"] print("Задача создана:", job_id) # 2. Опрашиваем статус не чаще одного раза в секунду. # Генерация занимает от одной до нескольких минут. while True: time.sleep(1) ping = requests.get( f"{BASE}/ping-video-job", headers=headers, params={"job_id": job_id}, ) ping.raise_for_status() status = ping.json() if status["status"] == "completed": result = status["result"] print("Готово:", result["width"], "x", result["height"], result["seconds"], "сек") break if status["status"] == "error": raise SystemExit(status.get("message")) print("Прогресс:", status.get("progress"), status.get("message")) # 3. Скачиваем ролик — обязательно с токеном. video = requests.get( f"{BASE}{result['video_url']}", headers=headers, params={"download": "1"}, stream=True, ) video.raise_for_status() with open("video.mp4", "wb") as f: for chunk in video.iter_content(chunk_size=256 * 1024): f.write(chunk) print("Видео сохранено в video.mp4") ``` ---