Полный справочник по REST-эндпоинтам. Туториалы и примеры см. в Руководстве по API.
Всё, что участник проекта может делать в веб-интерфейсе, доступно здесь — SPA потребляет тот же самый API. Операции, требующие роли owner, помечены (owner); всему остальному нужно лишь членство в проекте (или, для операций чтения, помеченных (viewer), любой уровень доступа).
https://eastagiletracker.com/api/v1https://api.eastagiletracker.com/api/v1 обслуживает идентичный API. Все запросы и ответы — это JSON, за исключением нескольких эндпоинтов загрузки файлов, которые принимают multipart.
Аутентификация
Заголовок раздела «Аутентификация»Каждый аутентифицированный запрос отправляет API-ключ одним из способов:
X-TrackerToken: <key>Authorization: Bearer <key>
Пользовательские ключи начинаются с ea_user_. Ключи агентов начинаются с ea_agent_. См. Руководство по API → Два вида ключей.
Эндпоинты без аутентификации: /openapi.json, /docs, эндпоинты /auth/* и справочные данные (/story_types, /story_states, /effort_scales, …). /meta требует аутентификации — подходит любой действительный ключ, но он не ограничен проектом (привязанный к проекту ключ агента тоже до него дотягивается).
Три уровня управляют эндпоинтами, ограниченными проектом:
| Уровень | Кто проходит | Типичные операции |
|---|---|---|
| viewer | viewer, member, owner | чтение (список/получение историй, поиск, аналитика) |
| member | member, owner | все операции записи рабочих элементов (истории, задачи, комментарии, …) |
| owner | только owner | настройки проекта, управление членством, ключи агентов, удаление, импорт, журнал аудита |
Не-участник получает 404 unfound_resource (а не 403) на путях проекта, так что ID проектов не перечислимы.
Самоописывающиеся эндпоинты
Заголовок раздела «Самоописывающиеся эндпоинты»| Метод | Путь | Описание |
|---|---|---|
| GET | /openapi.json | Актуальная спецификация OpenAPI 3. Без аутентификации. |
| GET | /docs | Swagger UI. Без аутентификации. |
| GET | /meta | Идентичность вызывающего (auth.kind/key_id/agent_id/project_id) + граф переходов для типов историй. Требует аутентификации (любой действительный ключ; не ограничен проектом). Вызывайте это первым. |
Аккаунт / идентичность
Заголовок раздела «Аккаунт / идентичность»Эти действуют от имени вызывающего и требуют лишь действительного ключа (без роли в проекте).
| Метод | Путь | Описание |
|---|---|---|
| POST | /auth/register | Зарегистрировать новый аккаунт |
| POST | /auth/login | Войти, возвращает токен сессии |
| POST | /auth/logout | Выйти |
| POST | /auth/forgot-password | Запросить письмо для сброса пароля |
| POST | /auth/reset-password | Использовать токен сброса для установки нового пароля |
| GET | /auth/verify-email | Подтвердить адрес электронной почты |
| POST | /auth/accept-invite/lookup | Разрешить токен приглашения → email (без аутентификации) |
| POST | /auth/accept-invite | Принять приглашение в проект (после аутентификации) |
| GET | /me | Профиль текущего пользователя |
| PUT | /me | Обновить профиль |
| DELETE | /me | Удалить аккаунт |
| PUT | /me/password | Сменить пароль |
| PUT | /me/settings | Обновить настройки (тема, предпочтения уведомлений) |
| POST | /me/avatar | Загрузить аватар (multipart) |
| POST | /me/api-token/regenerate | Ротировать ваш API-токен — аннулирует существующие сессии/ключи |
| GET | /me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id} | Управление пользовательскими (ea_user_) API-ключами |
| GET | /me/activity | Ваша активность по всем проектам |
| GET | /me/data-export | GDPR-самоэкспорт ваших данных |
| GET | /me/consent · POST /me/consent | Прочитать / записать согласие ({ consent_type, granted }) |
| GET | /legal/pending · POST /legal/accept | Ожидающие clickwrap-документы / запись принятия |
| POST | /contact · POST /feedback · POST /feedback/with-screenshot | Контакт + обратная связь внутри приложения |
Справочные данные (без аутентификации)
Заголовок раздела «Справочные данные (без аутентификации)»Стартовые справочники, используемые при создании/оценке историй. Стабильные ID.
| Метод | Путь | Описание |
|---|---|---|
| GET | /story_types | feature, bug, chore, release (+ allow_points) |
| GET | /story_states | unstarted … accepted, rejected |
| GET | /effort_scales | доступные шкалы оценки |
| GET | /effort_scales/{scale_id}/values | значения баллов в шкале |
Проекты
Заголовок раздела «Проекты»| Метод | Путь | Описание |
|---|---|---|
| GET | /projects | Список ваших проектов |
| POST | /projects | Создать проект |
| GET | /projects/{id} | Получить детали проекта (viewer) |
| PUT | /projects/{id} | Обновить настройки проекта (owner) |
| DELETE | /projects/{id} | Удалить проект (owner) |
| GET | /projects/{id}/audit-log | Поток активности проекта (owner) |
| GET | /projects/{id}/events | Поток событий с курсорной пагинацией (viewer) — см. Events |
Участники и ключи агентов
Заголовок раздела «Участники и ключи агентов»| Метод | Путь | Описание |
|---|---|---|
| GET | /projects/{id}/memberships | Список участников (viewer) |
| POST | /projects/{id}/memberships | Пригласить участника по email (owner) |
| PUT | /projects/{id}/memberships/{mid} | Обновить роль (owner) |
| DELETE | /projects/{id}/memberships/{mid} | Удалить участника (owner) |
| GET / POST | /projects/{id}/agent_keys | Список / выпуск ключей агентов (owner) |
| DELETE | /projects/{id}/agent_keys/{kid} | Отозвать ключ агента (owner) |
Истории
Заголовок раздела «Истории»Всем операциям записи историй нужна роль member.
| Метод | Путь | Описание |
|---|---|---|
| GET | /projects/{id}/stories | Список историй (с пагинацией, фильтруемый) (viewer) |
| POST | /projects/{id}/stories | Создать историю |
| GET | /projects/{id}/stories/{sid} | Получить одну историю (viewer) |
| PUT | /projects/{id}/stories/{sid} | Обновить историю |
| DELETE | /projects/{id}/stories/{sid} | Удалить историю |
| POST | /projects/{id}/stories/{sid}/transitions | Сменить состояние с валидацией |
| POST | /projects/{id}/stories/bulk_transition | Перевести много историй (1–100) сразу |
| POST | /projects/{id}/stories/bulk-delete | Удалить много историй |
| POST | /projects/{id}/stories/bulk-duplicate | Дублировать много историй |
| POST | /projects/{id}/stories/{sid}/duplicate | Дублировать одну историю |
Create (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. labels принимает ["auth"] или [{ "name": "auth" }]; неизвестные метки создаются. Значения по умолчанию: story_type=feature, current_state=unstarted.
Update (PUT …/stories/{sid}): те же поля, все опциональные, плюс "position" (float) и "force_state_change" (bool).
Transition (POST …/transitions): { "to": "<state>", "reason"? }. Поле называется to. Возвращает { story_id, state }. Недопустимое перемещение → 422 invalid_transition с details: { from, to, allowed }.
Bulk transition (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>", "reason"? }. Каждая история оценивается независимо; возвращает { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.
Подресурсы истории
Заголовок раздела «Подресурсы истории»Все member. List/GET для большинства — (viewer).
| Метод | Путь | Тело / примечания |
|---|---|---|
| GET / POST | /projects/{id}/stories/{sid}/tasks · PUT/DELETE …/tasks/{tid} | { description (or task_desc), complete?, task_order? } |
| GET / POST | /projects/{id}/stories/{sid}/comments · PUT/DELETE …/comments/{cid} | { text (or comment_text) } или { comment_emoji } |
| GET / POST | /projects/{id}/stories/{sid}/blockers · PUT/DELETE …/blockers/{bid} | { blocker_desc, resolved? } |
| GET / POST | /projects/{id}/stories/{sid}/links · DELETE …/links/{lid} | { url, link_type?, title? } |
| GET / POST | /projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid} | { reviewer_id? / reviewer_agent_id?, status, comment? } |
| GET / POST | /projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid} | { member_id? / agent_id? } — опустите оба, чтобы добавить вызывающего |
| GET / POST | /projects/{id}/stories/{sid}/followers · DELETE …/followers/{mid} · DELETE …/followers/agents/{aid} | { member_id? / agent_id? } |
| GET / POST | /projects/{id}/stories/{sid}/labels · DELETE …/labels/{lid} | { name } |
| GET / POST | /projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid} | multipart-загрузка (≤ 2 ГБ каждая); список — (viewer) |
member для записи, (viewer) для чтения.
| Метод | Путь | Описание |
|---|---|---|
| GET / POST | /projects/{id}/labels | Список / создание метки |
| PUT / DELETE | /projects/{id}/labels/{lid} | Обновление / удаление метки |
| POST | /projects/{id}/labels/{lid}/archive | Архивировать (мягко скрыть) метку |
Итерации
Заголовок раздела «Итерации»| Метод | Путь | Описание |
|---|---|---|
| GET | /projects/{id}/iterations | Список итераций (member) |
| POST | /projects/{id}/iterations | Создать ручную итерацию (owner) |
| DELETE | /projects/{id}/iterations/{itid} | Удалить итерацию (owner) |
Поиск, аналитика, метрики, предпочтения
Заголовок раздела «Поиск, аналитика, метрики, предпочтения»| Метод | Путь | Описание |
|---|---|---|
| GET | /projects/{id}/search?query=… | Поиск по синтаксису фильтров (viewer) — см. Руководство |
| GET | /projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections} | Аналитика (viewer). Детализация по итерации принимает ?iteration_id= |
| GET | /projects/{id}/metrics/{velocity,burndown,story-types} | Метрики (viewer) |
| GET / PUT | /projects/{id}/preferences | Ваши предпочтения доски для этого проекта (member) |
События
Заголовок раздела «События»| Метод | Путь | Описание |
|---|---|---|
| GET | /projects/{id}/events | Поток событий с курсорной пагинацией (viewer) |
Параметры запроса: since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. Ответ включает next_cursor. Передайте последний увиденный event_id как since, чтобы возобновить.
Импорт (owner)
Заголовок раздела «Импорт (owner)»| Метод | Путь | Описание |
|---|---|---|
| POST | /projects/{id}/import (+ /json) | Multipart-загрузка. source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json. |
WebSocket
Заголовок раздела «WebSocket»wss://eastagiletracker.com/ws/control?token=<key>Для интерактивного удалённого управления интерфейсом ({ "action": "get_state", "id": "req-1" }). Не канал данных — все чтения/записи идут через REST. Только для одного инстанса; не распределяется между репликами.
Идемпотентность
Заголовок раздела «Идемпотентность»Эндпоинты записи (POST, PUT, DELETE) принимают заголовок Idempotency-Key. Тот же ключ + то же тело воспроизводят кэшированный ответ (окно 24 часа); тот же ключ + другое тело возвращают 409 idempotency_conflict. Не применяется к GET/HEAD/OPTIONS, /auth/* или путям /attachments. Ответы 5xx никогда не кэшируются — повтор достигает обработчика.
Пагинация
Заголовок раздела «Пагинация»Эндпоинты списков принимают cursor=<opaque> и limit=<n≤200>. Когда заданы, ответ — это { "items": [...], "next_cursor": "<str|null>" }; передайте next_cursor обратно для перехода на страницу. Некоторые списки также возвращают заголовок X-Tracker-Pagination-Total.
Проекция полей
Заголовок раздела «Проекция полей»Эндпоинты списков принимают fields= (через запятую), чтобы возвращать только конкретные поля. story_id включается всегда; неизвестное имя поля возвращает 400 validation_failed с нарушающими именами в details.fields.
GET /projects/123/stories?fields=story_id,name,current_state,ownersФормат ошибок
Заголовок раздела «Формат ошибок»У каждой JSON-ошибки есть code и error; некоторые добавляют details:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`", "details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }| Статус | code | Когда |
|---|---|---|
| 400 | invalid_parameter | плохой ввод; сообщение в error, без details (большинство валидаций: пусто/длина/null-байт/email) |
| 400 | validation_failed | структурированная ошибка ввода; details.fields — это массив имён нарушающих полей |
| 401 | unauthenticated | отсутствующий/недействительный токен |
| 403 | unauthorized_operation | аутентифицирован, но недостаточная роль |
| 404 | unfound_resource | не найдено — также возвращается не-участникам |
| 409 | conflict | конфликт ресурса (например, дубликат) |
| 409 | idempotency_conflict | Idempotency-Key повторно использован с другим телом |
| 422 | invalid_transition | недопустимое перемещение состояния; details несёт { from, to, allowed } |
| 500 | internal_error | сбой сервера — обобщённое сообщение; безопасно повторять |
details.fields — это JSON-массив имён полей (например, ["to"]), иногда с дополнительными ключами вроде max. Карты «поле→сообщение» нет.
{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }Ограничения частоты
Заголовок раздела «Ограничения частоты»На ключ (на IP для эндпоинтов без аутентификации), токен-бакет GCRA:
- Auth —
/auth/*: 0.5 запр/с, всплеск 20. - Public —
/contact,/feedback: 0.2 запр/с, всплеск 10. - Sensitive — сброс пароля: ~0.002 запр/с, всплеск 5.
Превышенный лимит возвращает 429 Too Many Requests с заголовком Retry-After и простым текстовым телом (не JSON-конвертом ошибки).