Перейти к содержимому

Руководство по API

Начало работы с REST API East Agile Tracker: ключи пользователя и агента, создание и перемещение историй, идемпотентные записи, поиск, события и пагинация.

API East Agile Tracker спроектирован для агентов в той же мере, что и для людей. Всё, что вы можете делать в интерфейсе, вы можете делать через API — и несколько вещей, которые интерфейс не предоставляет, тоже здесь есть.

Это руководство проведёт вас от нуля до «скриптинга своего бэклога» менее чем за десять минут. Полный справочник по эндпоинтам см. в Спецификации API.

Вы аутентифицируетесь с помощью ключа в заголовке X-TrackerToken. Есть два вида ключей, которые вы выпускаете сами, и третий, который MCP-клиент получает за вас:

  • Пользовательские ключи (ea_user_…) — Действуют от вашего имени. Создавайте их в Account Settings → API Keys. Используйте их для персональных скриптов, CLI-инструментов, интеграций.
  • Ключи агента (ea_agent_…) — Действуют как именованный агент в одном проекте. Создавайте их в Project Settings → Agent. Используйте их для ИИ-агентов — Claude Code, Codex, своих собственных — которые должны участвовать в проекте как именованные члены команды.
  • MCP-токены (ea_mcp_…) — Access-токены OAuth 2.1, выдаваемые MCP-клиенту (Claude, IDE) после того, как вы одобрите его на странице согласия. Они действуют от вашего имени, и вы можете отозвать их в Account Settings → API Keys → Connected apps.

Одноразовое окно после создания личного API-ключа в настройках аккаунта; ключ на этом снимке скрыт

Форма создания ключа на вкладке Agent с именем и выбранной ролью member под инструкциями по настройке

Различия между двумя видами, которые вы выпускаете сами:

Пользовательский ключКлюч агента
ОбластьВсе ваши проектыОдин конкретный проект
Идентичность в журнале аудитаВаше имяИмя агента
РольВаша роль в каждом проектеЗадаётся при создании ключа (viewer, member или manager — никогда выше собственной роли выпускающего участника)
ОтзывОтзовите ключ; вы сохраняете доступ через другие ключи/сессииОтзовите или ротируйте ключ; агент теряет доступ немедленно
Лучше всего дляПерсональной автоматизации, скриптовИИ-агентов, которые должны отличаться от вас в истории

Authorization: Bearer … также работает, если вы предпочитаете такой стиль заголовка.

Получите свои проекты:

Окно терминала
curl https://api.eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: $TRACKER_TOKEN"

Или для ключа агента — перечислите проект, к которому он привязан:

Окно терминала
curl https://api.eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: ea_agent_xxxxx"

API — это JSON, REST-подобный, версионированный на /api/v1/. Одинаковые формы данных для людей и агентов.

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Onboarding redesign",
"description": "Q3 redesign of new-user onboarding",
"iteration_length_weeks": 1
}'

Ответ включает project_id и значения итераций по умолчанию, которые применил сервер (iteration_start_day, initial_velocity, iteration_length_weeks); GET /projects/{id} возвращает все настройки.

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Add OAuth login for Google",
"description": "## Acceptance\n- Google button on /login\n- Redirect back to original URL",
"story_type": "feature",
"estimate": "3",
"labels": ["auth"]
}'

estimate — это подпись значения шкалы в виде строки — "3" или "13" на шкале Fibonacci, — потому что она должна совпадать с точкой на шкале проекта. JSON-число отклоняется.

Эндпоинт перехода проверяет запрошенное перемещение и возвращает допустимые следующие состояния при ошибке:

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/transitions \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "to": "started" }'

Поле называется to (не to_state). Если перемещение недопустимо — скажем, вы попытались перепрыгнуть из unstarted прямо в accepted — ответ будет 422 invalid_transition со структурированными деталями ошибки:

{
"code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] }
}

Это одна из небольших вещей, которые делают API дружественным к агентам: агент может прочитать details.allowed и выбрать правильное следующее перемещение, не парся прозу.

rejected — терминальное состояние для эндпоинта переходов, который также отклоняет to: "rejected". Отклоняйте доставленную историю через POST …/stories/{sid}/reject; возвращайте отклонённую историю в работу через POST …/stories/{sid}/restart — это работает, пока история находится в текущей итерации.

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/comments \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "text": "Investigation done. Picking this up." }'

Комментарий приписывается тому, кто владеет API-ключом — если это ключ агента, автором комментария является агент.

Эндпоинты записи принимают заголовок Idempotency-Key (кроме загрузки вложений). Повторите тот же ключ с тем же телом в течение 24 часов — получите тот же ответ. Повторите тот же ключ с другим телом — получите 409 idempotency_conflict:

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "name": "Refactor auth middleware", "story_type": "chore" }'

Это критически важно для агентов в циклах повторов — упасть в середине записи, повторить с тем же ключом, никаких дублирующихся историй. Ответ 5xx, 401, 403, 404 или 429 никогда не кэшируется, поэтому повтор после него снова выполняет запрос.

Перемещайте множество историй сразу. Каждая история оценивается независимо; одно недопустимое перемещение не проваливает остальные.

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/bulk_transition \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"story_ids": [101, 102, 103],
"to": "delivered"
}'

Для агентов, которые хотят реагировать на действия людей, опрашивайте эндпоинт событий:

Окно терминала
curl "https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/events?since_id=$LAST_EVENT_ID&types=story.created,story.transitioned,comment.added" \
-H "X-TrackerToken: $TRACKER_TOKEN"

Ответ — { items, next_since_id, next_cursor }: каждое событие содержит актора, ресурс и изменение. Сохраните next_since_id и передайте его как since_id при следующем опросе, чтобы возобновить с того места, где остановились (since принимается как старый псевдоним). Никаких вебхуков, никакого парсинга, никаких пропущенных событий. Потоку нужна роль member — viewer получает 403.

GET /projects/{id}/search?q=<query> выполняет мощный полнотекстовый + структурированный поиск по историям проекта. Язык запросов смоделирован по квалификаторам поиска issues в GitHub — так что синтаксис, который вы (или ИИ-агент) уже знаете по GitHub, в основном переносится.

Окно терминала
curl -G "https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/search" \
-H "X-TrackerToken: $TRACKER_TOKEN" \
--data-urlencode 'q=payment crash type:bug,chore owner:@me created:>2026-05-01'

Ответ — JSON-конверт; истории ранжированы по релевантности, если в запросе есть свободный текст, а иначе идут в порядке доски:

{ "results": [ /* canonical story objects */ ], "total": 42, "limit": 50, "offset": 0 }

total — это полное число совпадений, а не размер страницы. Листайте с помощью limit (по умолчанию 50, максимум 1000) и offset; упорядочивайте через sort=relevance (по умолчанию), created, created_asc, updated или state.

  • Свободный текст совпадает с заголовком, ссылкой и описанием истории (полнотекстовый, со стеммингом и ранжированием). Заключайте точную фразу в "кавычки".
  • Квалификаторы имеют вид field:value. Разделяйте альтернативы запятой (ИЛИ внутри поля): type:bug,chore. Разделяйте квалификаторы пробелами (И между ними).
  • Отрицайте любой терм или квалификатор ведущим -: -label:wontfix.
  • Диапазоны для дат и баллов: включительный a..b или открытый >x / <x.
КвалификаторПримерСовпадает с
type:type:bug,choreтип(ы) истории
state:state:started,finishedсостояние(я) workflow
label:label:"my label"метка
epic:epic:"Checkout"истории в эпике
priority:priority:p1приоритет
points:points:3 · points:1..5 · points:>3значение оценки или диапазон
iteration:iteration:42id итерации
created: updated: started: completed: release:created:2026-05-01..2026-06-01 · updated:>2026-06-01дата или диапазон (с точностью до дня); release: — дата релиза истории
owner: requester: follower: reviewer: commenter: mention:owner:claire · owner:@meчеловек по имени или email — участники и агенты, включая mention:; @me — это вы (с ключом агента — участник, создавший ключ)
has:blockerhas:blockerесть открытый блокер
is:is:unestimated · is:icebox · is:backlog · is:blockedфлаг

mywork: — псевдоним для owner: — mywork:me это owner:@me. Старый квалификатор scheduled: выведен из употребления и молча игнорируется; используйте release:.

ИЛИ через запятую (type:bug,chore) применяется к фасетным квалификаторам; квалификаторы людей (owner: requester: follower: reviewer: commenter: mention:) принимают одно значение.

payment crash full text "payment" AND "crash"
"exact phrase" a phrase
type:bug,chore state:started bugs or chores that are started
owner:@me -label:wontfix mine, excluding the wontfix label
points:3..8 created:2026-05-01..2026-05-31 estimated 3-8, created in May
follower:tomas has:blocker tomas follows it and it's blocked
is:backlog updated:>2026-06-01 backlog items touched since Jun 1

Та же строка запроса управляет и полем поиска на доске (которое открывает живую колонку результатов), и этим API — одна грамматика для людей и агентов. Поиск по содержимому комментариев, задач и блокеров — в планах; сегодня свободный текст охватывает заголовок, ссылку и описание самой истории.

Актуальная спецификация OpenAPI 3 находится по адресу:

https://api.eastagiletracker.com/api/v1/openapi.json

Swagger UI находится по адресу:

https://api.eastagiletracker.com/api/v1/docs/

/openapi.json и /docs не требуют аутентификации — агент может прочитать контракт прежде, чем у него появится ключ. Как только у него есть ключ, /api/v1/meta (которому требуется действительный ключ) возвращает его идентичность и граф переходов для каждого типа историй; справочные данные (/story_types, /story_states, /effort_scales, /priority_scales) также не требуют аутентификации. Вместе они позволяют агентам ответить на вопрос «что я могу здесь делать?» без проб, ошибок и 403.

Обслуживаемый openapi.json содержит схемы тел запросов для эндпоинтов записи, включая maxLength каждого поля, так что клиент может проверить данные перед отправкой. Спецификация резюмирует те же формы.

Если вы скриптуете массовую миграцию:

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/import \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-F "source=pivotal" \
-F "file=@pivotal_export.csv"

Поддерживаемые файловые источники: pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat (собственный экспорт East Agile Tracker — формат для полного цикла туда-обратно). Multipart-эндпоинт работает синхронно и отвечает счётчиками результата.

GitHub импортирует из API, а не из файла, через JSON-эндпоинт — без file, только координаты репозитория:

Окно терминала
curl -X POST https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/import/json \
-H "X-TrackerToken: $TRACKER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"owner": "octocat",
"repo": "hello-world",
"token": "ghp_…",
"include_pull_requests": false,
"include_milestones": false,
"include_releases": false,
"include_dependencies": false
}'

JSON-эндпоинт асинхронный: он отвечает 202 с { "import_id", "status" }, и вы опрашиваете GET /projects/{id}/imports/{import_id}, пока задача не достигнет done или failed. В проекте одновременно выполняется только один импорт — второй вызов, пока один в работе, даёт 409 import_already_running. Весь цикл, с полями прогресса задачи, — в Наполнении проекта из репозитория GitHub.

token необязателен в запросе, но сама выборка всегда проходит аутентификацию — она идёт через GraphQL API GitHub, где анонимного уровня нет. Опустите token, и сервер подставит платформенный токен: только публичные репозитории, общий для всех вызывающих, и отклоняемый с import_github_shared_quota_low, когда его бюджет GraphQL опускается ниже 500 очков. Приватный репозиторий или развёртывание, где платформенный токен не настроен (import_github_no_token), требует вашего. Какой бы токен ни использовался, он применяется только для вызовов к GitHub и никогда не сохраняется и не возвращается. Полные подробности, включая неаутентифицированный REST-потолок GitHub в 60 запросов, — в Наполнение проекта из репозитория GitHub.

Предпросмотр в режиме dry-run. Добавьте "dry_run": true (JSON) или -F "dry_run=true" (multipart) к любому источнику. Импорт разбирает, сопоставляет и устраняет дубликаты ровно так же, как настоящий запуск, формирует те же счётчики результата (imported, skipped, errors, unmatched), а затем откатывает всё — ничего не записывается. На JSON-эндпоинте счётчики приходят на опрашиваемую задачу, сухой это прогон или нет.

Ограничения. Файл импорта ограничен 10 МиБ и 5000 историй (400 import_too_large / import_too_many_records, ничего не записывается); у импорта из GitHub ограничения на число историй нет. Повторный импорт файла безопасен — строки, уже импортированные (сопоставленные по id в источнике), пропускаются, а не дублируются.

Перечислить форматы может любая роль проекта; для скачивания нужна роль manager:

Окно терминала
# The registered export formats: { id, name, content_type, drops, includes_archived }
curl https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/formats \
-H "X-TrackerToken: $TRACKER_TOKEN"
# Download one format (eat is the full-fidelity round-trip CSV)
curl https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/eat \
-H "X-TrackerToken: $TRACKER_TOKEN" -o project-export.csv

Id форматов обмена: eat, jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json, плюс форматы документов pdf и docx. Каждое вложение можно скачать одним zip через GET /projects/{id}/export/attachments.

Все ошибки — это JSON, как минимум с:

{
"code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`"
}

Многие ответы с ошибками также включают объект details — details.fields (массив имён нарушающих полей) при validation_failed и details.allowed (наряду с from/to) при 422 invalid_transition. Используйте их. 429 rate_limited несёт заголовок Retry-After в том же JSON-конверте.

Эндпоинты списков принимают limit и cursor. Курсор непрозрачен; передавайте next_cursor из предыдущего ответа. Лимит limit задаётся для каждого эндпоинта — 200 у историй, комментариев и проектов, 500 у событий, 1000 у журнала аудита; поиск пагинируется через limit (≤ 1000) и offset. Обычный (не курсорный) список, которому пришлось усечь ответ, сообщает об этом в заголовках: X-Tracker-Pagination-Truncated, -Limit, -Offset и -Next-Offset, последний из которых вы передаёте обратно как offset= для следующей страницы. Заголовка с общим количеством нет.