Перейти до вмісту

Посібник з API

Початок роботи з REST API East Agile Tracker: ключі користувача й агента, створення та переміщення історій, ідемпотентні записи, пошук, події та пагінація.

API East Agile Tracker спроєктовано для агентів не менше, ніж для людей. Усе, що ви можете зробити в інтерфейсі, ви можете зробити через API — а ще там є кілька речей, яких інтерфейс не показує.

Цей посібник проведе вас від нуля до «скриптування свого беклогу» менш ніж за десять хвилин. Повну довідку по кінцевих точках дивіться в Специфікації API.

Три види облікових даних

Section titled “Три види облікових даних”

Ви автентифікуєтеся за допомогою ключа в заголовку X-TrackerToken. Є два види ключів, які ви створюєте самі, і третій, який MCP-клієнт отримує за вас:

  • Користувацькі ключі (ea_user_…) — діють як ви. Створюйте їх в Account Settings → API Keys. Використовуйте їх для особистих скриптів, інструментів CLI, інтеграцій.
  • Ключі агентів (ea_agent_…) — діють як названий агент в одному проєкті. Створюйте їх в Project Settings → Agent. Використовуйте їх для AI-агентів — 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 — ніколи не вище за власну роль учасника, що створює ключ)
ВідкликанняВідкличте ключ; ви зберігаєте доступ через інші ключі/сесіїВідкличте або ротуйте ключ; агент негайно втрачає доступ
Найкраще дляОсобиста автоматизація, скриптиAI-агенти, яких слід відрізняти від вас в історії

Authorization: Bearer … також працює, якщо ви віддаєте перевагу цьому стилю заголовка.

Отримайте свої проєкти:

Terminal window
curl https://api.eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: $TRACKER_TOKEN"

Або для ключа агента — перелічіть проєкт, до якого він прив’язаний:

Terminal window
curl https://api.eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: ea_agent_xxxxx"

API — це JSON, у стилі REST, версіонований за /api/v1/. Однакові структури для людей і агентів.

Terminal window
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} повертає всі налаштування.

Terminal window
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-число відхиляється.

Проведення історії через життєвий цикл

Section titled “Проведення історії через життєвий цикл”

Кінцева точка переходу перевіряє запитаний рух і повертає дозволені наступні стани при помилці:

Terminal window
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, що працює, поки історія в поточній ітерації.

Terminal window
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:

Terminal window
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 ніколи не кешується, тож повтор після неї знову виконує запит.

Переміщайте багато історій за раз. Кожна історія оцінюється незалежно; один неприпустимий рух не провалює інші.

Terminal window
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"
}'

Слідкування за потоком подій

Section titled “Слідкування за потоком подій”

Для агентів, які хочуть реагувати на те, що роблять люди, опитуйте кінцеву точку подій:

Terminal window
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 — тож синтаксис, який ви (або AI-агент) уже знаєте з GitHub, здебільшого переноситься.

Terminal window
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стан(и) робочого процесу
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 кожного поля, тож клієнт може перевірити дані перед надсиланням. Специфікація підсумовує ті самі структури.

Імпорт з іншого трекера

Section titled “Імпорт з іншого трекера”

Якщо ви скриптуєте масову міграцію:

Terminal window
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, лише координати репозиторію:

Terminal window
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-ендпоінті підрахунки надходять в опитуване завдання, хоч це dry-run, хоч ні.

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

Перелічити формати може будь-яка роль у проєкті; для завантаження потрібна роль manager:

Terminal window
# 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= для наступної сторінки. Заголовка із загальною кількістю немає.