Справочник: кредиты и автоматизация
Здесь все эндпоинты платных действий платформы и того, что их запускает, — кредиты, промпты и задачи ИИ, релизы GitHub в чейнджлог и автоматические новости — с параметрами, ответами и отказами; в консоли это раздел «Автоматизация», а кредиты — «Настройки → Кредиты».
Во всех примерах API — https://onpress.pro/api/v2, SITE — id сайта (SITE_ID), OP_TOKEN — токен op_XXXX. Кредиты — эндпоинты /me/credits… без /site/$SITE: баланс ваш, а не сайта. Остальные пишутся от /site/$SITE и доступны администратору сайта. Как получить токен и в какой форме приходят отказы — на странице «Доступ и токен».
Кредиты
1 кредит = 1 ₽. Баланс принадлежит пользователю, а не сайту: один баланс тратится на все сайты, где вы администратор, и в каждом списании записан сайт. Новый пользователь начинает с нулевого баланса. Ничего платного не уходит без подтверждения цены там, где её заранее не видно: публикация релизов GitHub через ИИ просит confirm и expected_cost, новость стоит ровно столько, сколько показывает GET /news/auto.
Резерв, потом списание. Перед работой действие резервирует свою цену. Не хватает доступного остатка — отказ сразу, до всякой работы: 402 insufficient_credits с required (сколько нужно), available (сколько свободно), action и quantity. После успеха резерв списывается, при сбое снимается целиком. Доступный остаток — баланс минус открытые резервы.
Прайс
| Действие | Ключ | Кредитов |
|---|---|---|
| Запись чейнджлога через ИИ | github_ai | 5 |
| Новость без картинки | news | 5 |
| Новость с картинкой 16:9 | news_image | 20 |
| Съём одной позиции в выдаче | serp_position | 1 |
| Отправка одной страницы на индексацию | index_submit | 2 |
Позиции и отправка на индексацию описаны в справочнике SEO, здесь только их цена.
GET /me/credits
Отдаёт баланс, прайс, пределы пополнения и последние 10 движений. Например:
curl -s "$API/me/credits" -H "Authorization: Bearer $OP_TOKEN"
{
"success": true,
"balance": 20,
"held": 0,
"available": 20,
"prices": { "github_ai": 5, "news": 5, "news_image": 20, "serp_position": 1, "index_submit": 2 },
"transactions": [ { "id": 31, "type": "spend", "delta": -20, "balance_after": 5, "action": "news_image", "site_id": "x9HTLHECq", "site_domain": "example.com", "job_id": 15, "note": "news_image", "created_at": "2026-10-02T11:42:04Z" } ],
"packages": [
{ "id": "pack_100", "credits": 100, "price_rub": 100, "title": "100 кредитов" },
{ "id": "pack_500", "credits": 500, "price_rub": 500, "title": "500 кредитов", "popular": true },
{ "id": "pack_1000", "credits": 1000, "price_rub": 1000, "title": "1000 кредитов" },
{ "id": "pack_5000", "credits": 5000, "price_rub": 5000, "title": "5000 кредитов" }
],
"topup": { "min": 100, "max": 100000, "rub_per_credit": 1, "suggested": [100, 500, 1000, 5000] }
}
| Поле | Описание |
|---|---|
balance | всё начисленное минус списанное |
held | открытые резервы |
available | сколько можно потратить сейчас |
prices | прайс |
topup | пределы пополнения: min и max в кредитах, rub_per_credit — рублей за кредит, suggested — суммы для быстрого выбора |
packages | фиксированные пакеты кредитов; popular: true — пакет, который консоль выделяет |
GET /me/credits/transactions
Отдаёт историю движений, свежие сверху. Например, только списания:
curl -s "$API/me/credits/transactions?limit=2&direction=out" -H "Authorization: Bearer $OP_TOKEN"
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | int | 50 | от 1 до 200 |
before | int | — | следующая порция: next из прошлого ответа |
direction | string | all | in — только начисления, out — только списания, all — всё; со следующей порцией передавайте тот же |
{
"success": true,
"transactions": [
{ "id": 31, "type": "spend", "delta": -20, "balance_after": 5, "action": "news_image", "site_id": "x9HTLHECq", "site_domain": "example.com", "job_id": 15, "note": "news_image", "created_at": "2026-10-02T11:42:04Z" }
],
"next": 31
}
| Поле | Описание |
|---|---|
type | bonus — бонус платформы, topup — оплата пополнения, grant и adjust — начисление и коррекция поддержкой, spend — списание за действие, refund — возврат |
delta | изменение баланса: начисление больше нуля, списание меньше |
balance_after | баланс сразу после записи, без учёта резервов, открытых в тот момент |
action | ключ действия из прайса; у начислений null |
site_id, site_domain | сайт, за который списано; у начислений null |
job_id | задача ИИ, если списание за задачу |
next | id для следующей порции; null — дальше пусто |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
invalid_direction | 400 | direction не all, in и не out | исправьте параметр |
POST /me/credits/topup
Создаёт заказ на пополнение; деньги по этому вызову не двигаются. К оплате amount × rub_per_credit рублей. Кредиты зачисляются, когда платёжный сервис подтвердил платёж, повторное уведомление о том же платеже ничего не удваивает; ждать зачисления — опросом GET /me/credits/topups/{id}. Способ оплаты задаёт flow: widget — окно CloudPayments поверх своей страницы, без перехода; link — ссылка на страницу оплаты CloudPayments в payment_url. Например, 500 кредитов виджетом:
curl -s -X POST "$API/me/credits/topup" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"amount": 500, "flow": "widget"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
amount | int | — | кредитов, от topup.min до topup.max из GET /me/credits, сейчас от 100 до 100 000 |
package | string | — | id пакета из packages; если переданы оба поля, берётся amount |
flow | string | link | widget или link |
return_path | string | /settings/credits | для link: путь консоли без хоста, куда человек вернётся после оплаты с ?topup=ID, после неуспешной — ещё и с topup_failed=1 |
{
"success": true, "topup_id": 41, "invoice_id": "cr_41", "credits": 500, "price_rub": 500,
"widget": {
"public_id": "pk_XXXX", "invoice_id": "cr_41", "amount": 500, "currency": "RUB",
"description": "OnPress: 500 кредитов", "account_id": "user@example.com", "email": "user@example.com",
"data": { "kind": "credits", "topup_id": 41, "package": "custom" }
}
}
widget — всё, что нужно передать виджету cp.CloudPayments().pay('charge', …): public_id в publicId, invoice_id в invoiceId, amount, currency, description, account_id в accountId, email, data. Номер счёта менять нельзя: по нему платёж находит заказ. Со "flow": "link" вместо widget приходит payment_url.
| Код | Статус | Когда | Что делать |
|---|---|---|---|
invalid_amount | 400 | amount не целое или вне пределов; пределы в min и max | исправьте сумму |
unknown_package | 400 | нет amount, а пакета нет в списке; допустимые — в packages | передайте amount |
payment_link_failed | 502 | платёжный сервис не выдал ссылку (только link) | повторите позже |
payments_not_configured | 503 | оплата на сервере не подключена | напишите в поддержку |
GET /me/credits/topups/{id}
Отдаёт состояние своего заказа на пополнение. Опрашивайте раз в 2–3 секунды; обычно зачисление занимает несколько секунд. Например:
curl -s "$API/me/credits/topups/41?verify=1" -H "Authorization: Bearer $OP_TOKEN"
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
verify | string | — | 1 — неоплаченный заказ младше 48 часов сверяется с платёжным сервисом напрямую, не дожидаясь его уведомления; прошедший платёж зачисляется тут же. Не чаще раза в 4 секунды на заказ, чаще — ответ без provider |
{ "success": true, "topup_id": 41, "invoice_id": "cr_41", "status": "new", "credits": 500, "price_rub": 500,
"created_at": "2026-10-06T09:22:05.000Z", "paid_at": null,
"provider": { "status": "Declined", "reason": "InsufficientFunds", "message": "Недостаточно средств на карте", "credited": 0 } }
| Поле | Описание |
|---|---|
status | new — не оплачен или подтверждение ещё не пришло, paid — кредиты зачислены, failed — ссылку создать не удалось |
paid_at | когда зачислено |
provider | только с verify=1: что платёжный сервис знает о последней попытке — status (Completed, Declined, NotFound и другие статусы CloudPayments), reason, message — причина отказа банка для человека, credited |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
topup_not_found | 404 | заказа нет или он чужой | проверьте {id} |
payment_mismatch | 409 | сумма или счёт оплаты не совпали с заказом, зачисления нет | напишите в поддержку |
Промпты
Промпт — шаблон текста, по которому ИИ пишет для сайта, и модель, которая его исполняет. У каждого сайта свой текст; пока его не меняли, действует умолчание платформы. Плейсхолдер {{имя}} подставляется один раз, неизвестное имя становится пустой строкой. {{format}} в news_article служебный: в него приходят требования к форме ответа и причины, по которым прошлый ответ отклонён, — без него новости начнут отклоняться проверкой. Модели по умолчанию: текст — google/gemini-2.5-flash, картинка — google/gemini-3.1-flash-image.
| Ключ | Для чего | Плейсхолдеры |
|---|---|---|
github_changelog | запись чейнджлога из релиза | {{site_name}} {{repo}} {{tag}} {{date}} {{commits}} {{lang}} |
news_article | текст новости | {{site_name}} {{site_description}} {{lang}} {{topic}} {{category}} {{recent_titles}} {{tone}} {{format}} |
news_image | картинка к новости | {{site_name}} {{title}} {{excerpt}} {{category}} {{topic}} {{lang}} |
GET /ai/prompts
Отдаёт все промпты сайта списком prompts в форме одного промпта. Например:
curl -s "$API/site/$SITE/ai/prompts" -H "Authorization: Bearer $OP_TOKEN"
GET /ai/prompts/{key}
Отдаёт один промпт. Например:
curl -s "$API/site/$SITE/ai/prompts/github_changelog" -H "Authorization: Bearer $OP_TOKEN"
{
"success": true,
"prompt": {
"key": "github_changelog",
"title": "GitHub → changelog",
"description": "Превращает коммиты и релиз в запись changelog в markdown.",
"kind": "text",
"variables": [ { "name": "site_name", "description": "Название сайта" }, { "name": "repo", "description": "Репозиторий, owner/name" } ],
"model": "google/gemini-2.5-pro",
"default_model": "google/gemini-2.5-flash",
"text": "Write a release note in {{lang}} for {{repo}}:\n{{commits}}",
"default_text": "You write release notes for the product …",
"custom": true,
"updated_at": "2026-10-02T16:55:27Z"
}
}
| Поле | Описание |
|---|---|
kind | text или image |
variables | плейсхолдеры с описанием |
model, text | действующие модель и текст |
default_model, default_text | умолчание платформы |
custom | true — у сайта свой текст или модель |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
prompt_not_found | 404 | нет такого ключа, известные — в message | возьмите ключ из таблицы |
PUT /ai/prompts/{key}
Сохраняет свой текст промпта и, если нужно, модель. Текст и модель, совпавшие с умолчанием, снимают настройку сайта (custom: false). Новый текст действует со следующей задачи, ответ — промпт в той же форме. Например:
curl -s -X PUT "$API/site/$SITE/ai/prompts/github_changelog" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"text": "Write a release note in {{lang}} for {{repo}}:\n{{commits}}", "model": "google/gemini-2.5-pro"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
text | string | — | непустой текст, до 20 000 символов |
model | string | модель по умолчанию | идентификатор модели OpenRouter вида провайдер/имя; пусто — модель по умолчанию |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
invalid_prompt | 400 | пустой текст | передайте text |
prompt_too_long | 400 | текст длиннее 20 000 символов | сократите |
invalid_model | 400 | модель не похожа на провайдер/имя | исправьте model |
prompt_not_found | 404 | нет такого ключа | возьмите ключ из таблицы |
DELETE /ai/prompts/{key}
Удаляет текст и модель сайта, ответ — промпт с custom: false. Повторный сброс безопасен. Например:
curl -s -X DELETE "$API/site/$SITE/ai/prompts/github_changelog" -H "Authorization: Bearer $OP_TOKEN"
Задачи ИИ
Всё, что ИИ делает для сайта, — задача: запись чейнджлога, новость, картинка. Задачи идут в очереди по две одновременно. Статусы: queued — ждёт, running — выполняется, done — готово и оплачено, failed — сбой, кредиты не списаны, cancelled — снята из очереди. Задача, которую оборвал перезапуск сервиса, закрывается как failed с возвратом резерва. Код сбоя приходит в error задачи: ai_provider_error — модель не ответила, ai_empty_response — пустой ответ, ai_no_image — нет картинки, ai_not_configured — генерация на сервере не подключена.
GET /ai/jobs
Отдаёт задачи сайта, свежие сверху. Например, готовые:
curl -s "$API/site/$SITE/ai/jobs?status=done&limit=20" -H "Authorization: Bearer $OP_TOKEN"
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | int | 50 | от 1 до 200 |
before | int | — | следующая порция: next из прошлого ответа |
status | string | все | queued, running, done, failed, cancelled |
{
"success": true,
"jobs": [
{ "id": 15, "action": "news_image", "status": "done", "credits": 20, "error": null, "result_url": "https://example.com/news/…/", "model": "google/gemini-2.5-flash", "cost_usd": 0.0731, "created_at": "2026-10-02T11:40:12Z", "started_at": "2026-10-02T11:40:12Z", "finished_at": "2026-10-02T11:42:04Z" }
],
"next": null
}
| Поле | Описание |
|---|---|
credits | цена задачи |
result_url | что получилось: страница или черновик |
cost_usd | себестоимость вызовов модели |
GET /ai/jobs/{id}
Отдаёт задачу в форме строки списка плюс input — с чем запущена, output — что вернула (у картинок только mime и размер в байтах, без данных), и steps — каждый вызов модели: шаг, модель, токены, время. Например:
curl -s "$API/site/$SITE/ai/jobs/15" -H "Authorization: Bearer $OP_TOKEN"
| Код | Статус | Когда | Что делать |
|---|---|---|---|
job_not_found | 404 | на этом сайте такой задачи нет | проверьте {id} |
POST /ai/jobs
Ставит задачу в очередь и сразу резервирует кредиты; ответ приходит, не дожидаясь результата: {job, hold_id, reused}, дальше задачу смотрят по id. Эндпоинт только генерирует текст или картинку и кладёт результат в output, ничего не публикуя; чейнджлог и новости с публикацией запускают свои эндпоинты — GitHub и автоновости. Например:
curl -s -X POST "$API/site/$SITE/ai/jobs" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"action": "news", "vars": {"topic": "Как поставить задачу ассистенту"}, "idempotency_key": "news-2026-10-27"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
action | string | — | github_ai, news или news_image |
vars | object | {} | значения плейсхолдеров промпта |
idempotency_key | string | — | повтор с тем же ключом вернёт уже созданную задачу (reused: true) и не возьмёт кредиты второй раз |
| Код | Статус | Когда | Что делать |
|---|---|---|---|
unknown_action | 400 | нет такого действия, известные — в message | возьмите action из таблицы |
insufficient_credits | 402 | не хватает кредитов, задача не создана | пополните баланс |
POST /ai/jobs/{id}/cancel
Снимает из очереди задачу в queued; резерв возвращается, ответ — задача со статусом cancelled. Например:
curl -s -X POST "$API/site/$SITE/ai/jobs/15/cancel" -H "Authorization: Bearer $OP_TOKEN"
| Код | Статус | Когда | Что делать |
|---|---|---|---|
job_not_found | 404 | на этом сайте такой задачи нет | проверьте {id} |
job_not_cancellable | 409 | задача уже выполняется или закончена | — |
GitHub → чейнджлог
Релизы репозитория становятся записями чейнджлога сайта: страница /changelog/<слаг>/ на фрейме changelog__post и строка набора changelog в ленте с пагинацией; кэш обеих страниц сбрасывается сразу. Слаг — тег релиза (v15.5.4 → v15-5-4). Чтобы лента что-то показывала, на сайте нужна страница /changelog/.
Два режима. asis — «как есть»: текст релиза публикуется без переписывания, заголовок — имя релиза или тег, дата — дата релиза, метка (Feature, Fix или Improvement) подбирается по тексту; бесплатно. ai — «через ИИ», 5 кредитов за релиз: модель получает текст релиза, влитые pull request’ы и коммиты с прошлого релиза и пишет запись для пользователей по промпту github_changelog. Кредиты списываются только после публикации страницы. Платит тот, кто запустил, а при публикации по расписанию — тот, кто подключил репозиторий.
Доступ. Публичный репозиторий подключается без токена, приватный — с fine-grained токеном GitHub с правами только на чтение Contents и Metadata. Токен хранится зашифрованным и наружу не отдаётся, только маска ••••abcd. Токен полезен и для публичного репозитория: без него GitHub даёт 60 запросов в час на адрес сервера, с ним — 5000.
Один релиз — одна запись. Релиз узнаётся по своему id на GitHub: повторная публикация опубликованного релиза ничего не трогает и ничего не стоит (skipped: "already_published"), релиз в процессе отвечает skipped: "in_progress". Неудачную попытку можно повторить.
GET /integrations/github
Отдаёт состояние подключения. Без подключения — {"success": true, "providers": ["token", "app"], "ai_price": 5, "connected": false}. Например:
curl -s "$API/site/$SITE/integrations/github" -H "Authorization: Bearer $OP_TOKEN"
{
"success": true,
"providers": ["token", "app"],
"ai_price": 5,
"connected": true,
"provider": "token",
"repo": "vercel/next.js",
"private": false,
"token": null,
"mode": "asis",
"auto": false,
"ai_limit": 0,
"ai_spent_month": 0,
"prereleases": false,
"lang": null,
"site_lang": "en",
"auto_since": "2026-10-02T16:55:40Z",
"last_sync": null,
"counts": { "published": 0, "failed": 0, "pending": 0 },
"cron": { "interval": "hourly", "contour": "production" }
}
| Поле | Описание |
|---|---|
token | маска токена ••••abcd; null — без токена |
ai_spent_month | потрачено по расписанию в этом месяце |
auto_since | по расписанию берутся только релизы новее этого момента — подключения или включения auto |
counts | релизов в журнале по статусам |
cron | расписание: раз в час на боевом сервере |
PUT /integrations/github
Подключает репозиторий или меняет подключение; перед сохранением репозиторий проверяется на GitHub. Ответ — как у GET /integrations/github. По расписанию старые релизы разом не публикуются, а релиз, который не влезает в месячный лимит, пропускается без списания. Например, подключить репозиторий без расписания:
curl -s -X PUT "$API/site/$SITE/integrations/github" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"repo": "https://github.com/vercel/next.js", "mode": "asis", "auto": false}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
repo | string | — | owner/name или адрес на github.com; обязателен при первом подключении |
token | string | сохранённый | fine-grained токен; не передан — для того же репозитория остаётся сохранённый, "" — снять токен |
mode | string | asis | asis или ai |
auto | bool | true | публиковать новые релизы раз в час |
ai_limit | int | 0 | потолок кредитов в календарный месяц на публикацию по расписанию через ИИ |
prereleases | bool | false | брать пре-релизы |
lang | string | язык сайта по умолчанию | язык записей |
confirm | bool | false | подтверждение трат для mode: "ai" с auto: true |
mode: "ai" вместе с auto: true требует ai_limit больше нуля и confirm: true, иначе ответ — цена и лимит:
{ "success": false, "error": "confirmation_required", "message": "automatic publishing through AI spends credits (5 per release, up to 50 per month); repeat the request with \"confirm\": true", "price": 5, "ai_limit": 50 }
Отказы — в общей таблице GitHub.
DELETE /integrations/github
Снимает подключение и токен; опубликованные записи и журнал остаются. Ответ — {"success": true, "connected": false, "removed": true}. Например:
curl -s -X DELETE "$API/site/$SITE/integrations/github" -H "Authorization: Bearer $OP_TOKEN"
GET /integrations/github/releases
Отдаёт последние 100 релизов репозитория, без черновиков; список кэшируется на минуту. Например:
curl -s "$API/site/$SITE/integrations/github/releases?per_page=20&refresh=1" -H "Authorization: Bearer $OP_TOKEN"
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
page | int | 1 | номер страницы |
per_page | int | 20 | до 100 |
refresh | string | — | 1 — свежий список с GitHub |
all | string | — | 1 — с пре-релизами, даже если они выключены в подключении |
{
"success": true,
"repo": "vercel/next.js",
"page": 1,
"per_page": 1,
"more": true,
"total": 14,
"releases": [
{ "id": 399923971, "tag": "v16.3.8", "name": "v16.3.8", "published_at": "2026-09-30T16:13:46Z", "prerelease": false, "url": "https://github.com/vercel/next.js/releases/tag/v16.3.8", "author": "…", "excerpt": "This release contains security fixes…", "published": null, "failed": null }
]
}
published у опубликованного релиза — {status, mode, url, label, credits}, failed у неудачного — {error, attempts}.
POST /integrations/github/releases/publish
Публикует выбранные релизы. Через ИИ без confirm: true ответ — цена за ещё не опубликованные релизы, так её можно узнать, ничего не потратив. На нехватке кредитов публикация останавливается, сделанное остаётся. Например, один релиз через ИИ:
curl -s -X POST "$API/site/$SITE/integrations/github/releases/publish" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"release_ids": [399923971], "mode": "ai", "confirm": true, "expected_cost": 5}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
release_ids | array | — | id из списка релизов: до 30 за раз «как есть», до 5 через ИИ |
mode | string | режим подключения | asis или ai |
confirm | bool | false | подтверждение трат для ai |
expected_cost | int | — | цена, которую вы готовы заплатить; ниже реальной — 409 expected_cost_too_low |
{ "success": false, "error": "confirmation_required", "message": "publishing through AI spends credits: 5 for 1 release(s); repeat with \"confirm\": true and \"expected_cost\": 5", "cost": 5, "price": 5, "releases": 1 }
Ответ — {success, mode, results, balance}: по строке на релиз (release_id, tag, status, skipped, mode, credits, url, slug, label, job_id, у сбоя — error) и остаток кредитов.
POST /integrations/github/sync
Делает то же, что расписание, но сразу: публикует новые релизы после auto_since в режиме подключения. Через ИИ при найденных релизах нужен confirm: true, иначе 409 confirmation_required с ценой. В skipped причина — monthly_limit, already_published или in_progress. Например:
curl -s -X POST "$API/site/$SITE/integrations/github/sync" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"confirm": true}'
{ "success": true, "repo": "vercel/next.js", "mode": "asis", "found": 0, "published": [], "skipped": [], "failed": [], "balance": { "available": 20, "balance": 20, "held": 0 } }
GET /integrations/github/history
Отдаёт журнал: каждый релиз, который проходил через интеграцию, — release_id, tag, title, status (published, pending, failed), mode, trigger (manual — вручную, auto — по расписанию), credits, job_id, url, label, error, attempts и даты. more: true — есть следующая страница. Например:
curl -s "$API/site/$SITE/integrations/github/history?page=1&per_page=20" -H "Authorization: Bearer $OP_TOKEN"
DELETE /integrations/github/releases/{releaseId}
Убирает страницу записи, её строку из ленты и отметку о публикации — релиз можно опубликовать заново. Кредиты не возвращаются. Например, снять только отметку, оставив страницу:
curl -s -X DELETE "$API/site/$SITE/integrations/github/releases/399923971?remove_page=0" -H "Authorization: Bearer $OP_TOKEN"
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
remove_page | string | 1 | 0 — снять только отметку, страницу и строку ленты оставить |
Отказы GitHub
| Код | Статус | Когда | Что делать |
|---|---|---|---|
invalid_repo, invalid_token, invalid_mode, invalid_ai_limit, invalid_lang | 400 | неверное поле подключения | исправьте поле |
repo_required, release_ids_required | 400 | нет репозитория или списка релизов | передайте поле |
too_many_releases | 400 | список длиннее допустимого, предел в max | разбейте на части |
ai_limit_required | 400 | mode: "ai" с auto: true без ai_limit | передайте ai_limit больше нуля |
github_token_invalid | 401 | GitHub отверг токен | выпустите новый токен |
insufficient_credits | 402 | не хватает кредитов на режим ИИ | пополните баланс |
github_forbidden | 403 | GitHub не дал доступа | проверьте права токена |
github_not_connected | 404 | репозиторий не подключён | подключите через PUT |
github_repo_not_found | 404 | GitHub не видит репозиторий | проверьте имя и токен |
release_not_found | 404 | релиза нет среди последних 100 | — |
release_record_not_found | 404 | релиз не публиковался через интеграцию | — |
confirmation_required, expected_cost_too_low | 409 | трата не подтверждена или подтверждена не той суммой | повторите с confirm и ценой из ответа |
release_in_progress, publish_busy | 409 | релиз или чейнджлог сайта сейчас пишется | повторите позже |
github_rate_limited | 429 | исчерпан лимит GitHub, reset_at — когда восстановится | подождите или подключите токен |
github_token_unreadable | 500 | сохранённый токен не расшифровался | передайте токен заново |
provider_not_supported | 501 | провайдер app (приложение GitHub) | подключайтесь токеном |
github_unreachable, github_error, ai_job_failed, ai_empty | 502 | GitHub или модель не ответили как надо; кредиты не списаны | повторите позже |
github_not_configured | 503 | интеграция на сервере не подключена | напишите в поддержку |
Автоновости
ИИ пишет новость по теме сайта и кладёт её в раздел /news/: страница на фрейме news__post, дочерняя к странице раздела, с рубрикой. Цена — news, 5 кредитов, или news_image, 20 кредитов с картинкой 16:9; кредиты списываются только когда страница создана, любой сбой возвращает резерв.
Что делает задача. Читает сайт — название, описание, раздел новостей, рубрики, заголовки последних новостей, — пишет новость по промпту news_article и проверяет её: длина заголовка, лида и текста (150–750 слов, от трёх абзацев), язык, нет H1, ссылок, картинок, таблиц, цитат, процентов, выдуманных фактов о продукте. Не прошло — модель получает причины и пишет заново, до трёх попыток; после третьей задача падает с news_format_rejected без списания. С картинкой задача генерирует её по промпту news_image, кладёт в медиатеку с заголовком в alt и ставит превью страницы. Слаг уникален внутри раздела.
Публикация. mode: "publish" публикует страницу и пересобирает ленту из живых новостей раздела: список новостей, три свежих на главной, рубрики со счётчиками, пагинацию, «ещё новости». Страницы, которые показывают эти наборы, сразу собираются заново со сбросом кэша, и новость видна в /news/, в рубрике и на главной. mode: "draft" сохраняет черновик со ссылкой на предпросмотр, лента не меняется; кредиты списываются за генерацию, публикация черновика потом бесплатна.
GET /news/auto
Отдаёт настройки, варианты, цены, баланс и состояние расписания. Например:
curl -s "$API/site/$SITE/news/auto" -H "Authorization: Bearer $OP_TOKEN"
{
"success": true,
"settings": { "enabled": false, "per_week": 2, "categories": [], "with_image": true, "tone": "neutral", "lang": "en", "monthly_limit": 100, "auto_publish": true, "topics": "" },
"saved": false,
"owner_id": null,
"options": { "languages": [ { "slug": "en", "name": "English" }, { "slug": "ru", "name": "Русский" } ], "default_lang": "en", "lang": "en", "ready": false, "section": null, "categories": [], "tones": ["neutral", "friendly", "expert", "concise"] },
"prices": { "news": 5, "news_image": 20 },
"credits": { "available": 20, "balance": 20, "topup_path": "/settings/credits" },
"schedule": { "week_count": 0, "month_spent": 0, "month_limit": 100, "blocked": "disabled", "next_run_at": null, "interval_hours": 84, "last_run_at": null, "last_error": "" }
}
| Поле | Описание |
|---|---|
saved, owner_id | сохранялись ли настройки и кто их сохранил — он платит за расписание |
options.ready | есть ли у сайта раздел /news/ на этом языке |
options.categories | рубрики раздела: slug, title, url |
schedule.blocked | почему расписание сейчас не запустится: disabled — выключено, week_quota — недельная норма сделана, monthly_limit — месячный лимит исчерпан, backoff — пауза 6 часов после сбоя, null — ничего не мешает |
schedule.next_run_at | ближайший запуск |
PUT /news/auto
Сохраняет настройки; меняются только переданные поля. Платит тот, кто сохранил настройки, и он должен оставаться администратором сайта. Расписание работает на боевом сервере раз в час с 05:00 до 18:00 UTC: сайт в очереди, когда за 7 дней сделано меньше per_week новостей по расписанию и с прошлой прошло не меньше 90% интервала 7 дней / per_week. Ручные запуски в недельную норму и месячный лимит не входят. Ответ — как у GET /news/auto. Например:
curl -s -X PUT "$API/site/$SITE/news/auto" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"enabled": true, "per_week": 3, "categories": ["guides"], "with_image": true, "monthly_limit": 300}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
enabled | bool | false | расписание включено |
per_week | int | 2 | новостей в неделю, от 1 до 14 |
categories | array | [] | слаги рубрик; [] — все по очереди: берётся рубрика, где за 28 дней меньше всего новостей |
with_image | bool | true | с картинкой |
tone | string | neutral | neutral, friendly, expert или concise |
lang | string | язык сайта по умолчанию | язык новостей |
monthly_limit | int | 100 | потолок кредитов в календарный месяц на новости по расписанию, от 0 до 100 000; 0 — расписание ничего не запустит |
auto_publish | bool | true | публиковать сразу; false — складывать в черновики |
topics | string | "" | темы, которые ИИ предпочитает, до 400 символов |
Отказы — в общей таблице автоновостей; включить расписание без раздела /news/ на языке нельзя — 409 news_section_missing.
POST /news/auto/run
Ставит одну новость в очередь и сразу резервирует кредиты. Ответ — {job, reused, with_image, mode, category}; ход задачи — в задачах ИИ и в списке новостей. Например, черновик на заданную тему без картинки:
curl -s -X POST "$API/site/$SITE/news/auto/run" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"topic": "How to brief an assistant", "category": "guides", "with_image": false, "mode": "draft"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
topic | string | — | тема до 300 символов; без неё ИИ выбирает сам по теме сайта и topics |
category | string | наименее заполненная из рубрик расписания | слаг рубрики; "none" — без рубрики |
lang, tone, with_image | — | из настроек | как в настройках |
mode | string | draft | draft или publish |
idempotency_key | string | — | повтор с тем же ключом не запустит вторую новость |
Отказы до всякой траты: 400 invalid_topic, 402 insufficient_credits, 409 news_section_missing, 409 news_category_missing.
GET /news/auto/items
Отдаёт сделанные новости, свежие сверху. Например:
curl -s "$API/site/$SITE/news/auto/items?limit=20" -H "Authorization: Bearer $OP_TOKEN"
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | int | 50 | до 200 |
before | int | — | следующая порция: next из прошлого ответа |
У записи: id, job_id, status (queued, running, draft, published, failed), trigger (manual или cron), with_image, lang, category, title, url, preview_url у черновика, credits, error у сбоя, created_at, published_at.
POST /news/auto/items/{id}/publish
Публикует черновик с текущей датой и пересобирает ленту, бесплатно: кредиты взяты при генерации. Ответ — {item, link}. Например:
curl -s -X POST "$API/site/$SITE/news/auto/items/12/publish" -H "Authorization: Bearer $OP_TOKEN"
DELETE /news/auto/items/{id}
Удаляет черновик вместе со страницей или запись о сбое из списка; ответ — {id}. Опубликованная новость убирается как страница — через DELETE /pages/{ref}, здесь она отвечает 409 news_item_published. Например:
curl -s -X DELETE "$API/site/$SITE/news/auto/items/12" -H "Authorization: Bearer $OP_TOKEN"
POST /news/auto/feed
Собирает наборы ленты заново из живых страниц раздела — после того как новость удалили или поправили вручную; бесплатно. Ответ — {lang, section, posts, categories, written, rebaked}: сколько новостей и рубрик в ленте, какие наборы записаны и какие страницы собраны заново. Например:
curl -s -X POST "$API/site/$SITE/news/auto/feed" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d '{"lang": "en"}'
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
lang | string | язык из настроек автоновостей | лента какого языка |
Отказы автоновостей
| Код | Статус | Когда | Что делать |
|---|---|---|---|
invalid_per_week, invalid_monthly_limit, invalid_tone, invalid_lang, invalid_categories, invalid_topic | 400 | неверное поле | исправьте поле |
invalid_item | 400 | {id} не целое число | возьмите id из списка новостей |
insufficient_credits | 402 | не хватает кредитов; required, available | пополните баланс |
news_item_not_found | 404 | нет такой записи | проверьте {id} |
news_section_missing | 409 | нет раздела /news/ на языке | создайте раздел |
news_category_missing | 409 | рубрики нет в разделе | возьмите слаг из options.categories |
news_dataset_missing | 409 | у сайта нет набора ленты новостей | — |
news_already_published, news_not_a_draft, news_draft_empty | 409 | запись не черновик или черновик пуст | — |
news_item_published | 409 | удаление опубликованной новости | удалите страницу через DELETE /pages/{ref} |
news_format_rejected | 422 | в задаче: три ответа модели не прошли проверку, кредиты не списаны | запустите снова или поправьте промпт |
news_media_failed, news_write_failed | 502 | в задаче: картинка или страница не записались, кредиты не списаны | запустите снова |