Сроки.PRO · API

API Сроки.PRO

Интеграционный HTTP-API для программного доступа к диаграммам Ганта. Рассчитан на автоматизацию и ИИ-агентов: читать/создавать/править проекты, считать даты и кэшфлоу серверным движком.

Базовый URL: https://sroki.pro/apiext.php · авторизация — по токену, без сессий и cookie.

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

Все запросы идут на единый эндпоинт apiext.php. Токен передаётся GET-параметром t в строке запроса (и на GET, и на POST — тела он не касается).

  • Формат токена — 32 hex-символа. Неверный формат или ненайденный токен → одинаковый ответ 404 not found (защита от перебора).
  • Доступ строго по владельцу токена: запросы к проектам всегда идут с условием WHERE user_id = <владелец токена>. Указать чужого владельца параметром нельзя.
  • Токен бессрочный — живёт, пока не удалён в кабинете.

Скоупы (права токена)

scopeЧто можно
readтолько чтение: list, get, расчёт schedule/cashflow. Запись → 403
writeтолько запись: update, create. Чтение → 403
readwriteвсё вместе

Пример вызова с токеном

# список проектов владельца токена
curl "https://sroki.pro/apiext.php?t=<TOKEN>&action=list"

Как получить токен

Токен выдаётся в кабинете (сессионный API api.php, вход по логину/паролю). Секрет показывается один раз при создании — сохраните его сразу.

action (api.php)МетодНазначение
api_token_listGET/POSTсписок токенов (без секрета): id, name, scope, created_at, last_used
api_token_createPOSTтело {"name":"...","scope":"read|write|readwrite"} → возвращает секрет
api_token_deletePOSTтело {"id":N} → удаляет токен
# 1) логин — создаёт сессионную cookie
curl -c cookies.txt -H "Content-Type: application/json" \
  -X POST "https://sroki.pro/auth.php?action=login" \
  -d '{"email":"you@example.com","password":"..."}'

# 2) создать токен readwrite (секрет вернётся только сейчас)
curl -b cookies.txt -H "Content-Type: application/json" \
  -X POST "https://sroki.pro/api.php?action=api_token_create" \
  -d '{"name":"n8n-integration","scope":"readwrite"}'
# → {"ok":true,"token":"<32 hex>","id":7,"name":"n8n-integration","scope":"readwrite"}

Действия

Разрешены только GET и POST. Действие задаётся параметром action (по умолчанию — list).

GET list · scope: read / readwrite

Список проектов владельца токена.

ПараметрОбяз.Описание
tдатокен
actionнетlist (или не передавать — действие по умолчанию)
curl "https://sroki.pro/apiext.php?t=<TOKEN>&action=list"

# ответ
{"ok":true,"projects":[
  {"slug":"remont-ofisa","title":"Ремонт офиса","updated_at":1786000000}
]}

GET get · scope: read / readwrite

Полный JSON проекта по слагу.

ПараметрОбяз.Описание
tдатокен
actionдаget
slugдаслаг проекта ^[A-Za-z0-9_-]{1,100}$; не найден/чужой → 404
curl "https://sroki.pro/apiext.php?t=<TOKEN>&action=get&slug=remont-ofisa"

# ответ (data — объект проекta schemaVersion 2)
{"ok":true,"slug":"remont-ofisa","title":"Ремонт офиса","updated_at":1786000000,
 "data":{"schemaVersion":2,"start":"2026-08-24","calendar":"rf",
   "nodes":[{"uid":"t1","name":"Демонтаж","dur":5},
            {"uid":"t2","name":"Электрика","dur":10,"pred":[{"uid":"t1"}]}]}}

GETPOST schedule · scope: read / readwrite

Пересчёт дат и критического пути серверным движком. Ничего не пишет в БД. GET — по сохранённому проекту (slug), POST — сухой прогон присланных данных.

Параметр / полеОбяз.Описание
slug (GET)да (GET)слаг проекта
data (POST-тело)да (POST)объект проекта с nodes; тело вида {"data":{...}}
# GET — по сохранённому проекту
curl "https://sroki.pro/apiext.php?t=<TOKEN>&action=schedule&slug=remont-ofisa"

# POST — сухой прогон, ничего не пишется
curl -X POST "https://sroki.pro/apiext.php?t=<TOKEN>&action=schedule" \
  -H "Content-Type: application/json" \
  -d '{"data":{"schemaVersion":2,"start":"2026-08-24","calendar":"rf",
       "nodes":[{"uid":"t1","name":"Демонтаж","dur":5}]}}'

# ответ
{"ok":true,"start":"2026-08-24","maxEnd":66,"finish":"2026-10-29","warnings":[],
 "rows":[{"uid":"t1","name":"Демонтаж","dur":5,"so":0,"eo":5,
          "critical":true,"ds":"2026-08-24","de":"2026-08-31"}]}

В каждой строке rows[i]: uid, name, dur, unit, so/eo (смещения в днях), critical, ms (веха), ds/de — готовые ISO-даты старта/финиша (их добавляет сам API, считать смещения не нужно).

GETPOST cashflow · scope: read / readwrite

Кэшфлоу: баланс, пик потребности, прибыль, разбивка по периодам. Без записи. Параметры как у schedule, плюс:

ПараметрОбяз.Описание
unitнетmonth (по умолчанию) или week — разбивка buckets
curl "https://sroki.pro/apiext.php?t=<TOKEN>&action=cashflow&slug=remont-ofisa&unit=month"

# ответ (сокращённо)
{"ok":true,"start":"2026-08-24","unit":"month",
 "cf":{"peak":{"iso":"2026-08-24","balance":-40000},
       "profit":620000,"breakeven":"2026-09-14","cashStart":0,
       "buckets":[{"label":"авг 2026","in":0,"out":40000,"net":-40000,"balanceEnd":-40000}],
       "events":[{"uid":"t1","name":"Демонтаж","iso":"2026-08-24","at":"start","amount":-40000}]}}

POST update · scope: write / readwrite

Обновляет существующий проект владельца (перезаписывает title/data целиком).

Поле телаОбяз.Описание
slugда^[A-Za-z0-9_-]{1,100}$, иначе 400 bad slug
dataдаобъект проекта; должен содержать nodes, иначе 400 bad data
Патча нет — присылайте весь объект data целиком. Типовой поток: get → изменить объект → update.
curl -X POST "https://sroki.pro/apiext.php?t=<TOKEN>&action=update" \
  -H "Content-Type: application/json" \
  -d '{"slug":"remont-ofisa","data":{"schemaVersion":2,"title":"Ремонт офиса",
       "start":"2026-08-24","calendar":"rf","nodes":[...]}}'

# ответ
{"ok":true,"slug":"remont-ofisa"}

POST create · scope: write / readwrite

Создаёт новый проект у владельца токена.

Поле телаОбяз.Описание
dataдаобъект проекта с nodes
titleнетесли нет — берётся data.title
slugнетесли задан и занят → 409 slug already exists; если не задан — генерится из title транслитом с авто-суффиксом
curl -X POST "https://sroki.pro/apiext.php?t=<TOKEN>&action=create" \
  -H "Content-Type: application/json" \
  -d '{"title":"Новый проект","data":{"schemaVersion":2,
       "start":"2026-09-01","calendar":"rf","nodes":[]}}'

# ответ
{"ok":true,"slug":"novyy-proekt","created":1}

Превью (dry-run)

Отдельного флага apply/commit нет. Роль сухого прогона играет само действие:

  • POST schedule / POST cashflow с телом {"data":{...}} — только считают, в БД ничего не пишут.
  • Реальная запись — только update / create.

«Показать, что изменится» = прогнать новые данные через schedule/cashflow, сравнить с get, и только потом update. Сам сервер diff «было→стало» не строит — это делает клиентская CLI-обёртка.

Ошибки

Всегда JSON {"ok":false,"error":"..."} с соответствующим HTTP-кодом.

КодerrorКогда
404not foundтокен неверного формата / не найден; проект не найден или чужой
403forbidden: token scope is read-onlyread-токен пытается писать
403forbidden: token scope is write-onlywrite-токен пытается читать
400bad jsonтело POST не JSON-объект / нет ключа data
400bad datadata без nodes
400bad slugслаг не проходит формат
409slug already existscreate с занятым слагом
405method not allowedметод не GET/POST
500server errorнепойманное исключение сервера
Действует лимит запросов: не более 120 запросов в минуту на токен (при превышении — HTTP 429). Запись (create/update) требует активной подписки владельца токена, иначе HTTP 402. Удаления проекта через API нет (только правка/создание своих).

Формат проекта (schemaVersion 2)

Объект data, верхний уровень:

ПолеТипНазначение
schemaVersionintвсегда 2
titlestringназвание проекта
startISO YYYY-MM-DDдата старта — точка отсчёта всех дат (дефолт 2026-01-01)
calendarstringrf — производственный календарь РФ; иначе none (только выходные)
cashStartintстартовый баланс для кэшфлоу (дефолт 0)
nodesarrayдерево задач (обязательно)

Узел nodes[i] (рекурсивно через children):

ПолеТипНазначение
uidstringуникальный id узла (для связей); если пусто — сервер сгенерит
namestringназвание задачи
durnumberдлительность в единицах unit
unitstringrab (раб. дни, дефолт) / cal (кал. дни) / month
predarrayпредшественники: [{"uid":"...","lag":0}]; uid:"start" = старт проекта
childrenarrayвложенные подзадачи (узел с детьми — контейнер, срок из детей)
casharrayплатежи: [{"amount":15000,"at":"start|finish","lag":0}]; amount<0 — расход
colorstringhex-цвет полосы (дефолт #2E75B6)
milestoneboolвеха (нулевая длительность)
mustStartISOжёсткая дата «не раньше»
deadlineISOдедлайн (движок помечает просрочку)