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

Специфікація API

Повна довідка по кінцевих точках REST. Щодо туторіалів та прикладів дивіться Посібник з API.

Усе, що member проєкту може зробити у вебінтерфейсі, доступно тут — SPA споживає той самий API. Операції, що вимагають ролі owner, позначено (owner); усе інше потребує лише членства в проєкті (або, для читань, позначених (viewer), будь-якого рівня доступу).

https://eastagiletracker.com/api/v1

https://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 є автентифікованою — будь-який дійсний ключ працює, але вона не обмежена проєктом (ключ агента, прив’язаний до проєкту, теж її досягає).

Три рівні регулюють кінцеві точки, обмежені проєктом:

РівеньХто проходитьТипові операції
viewerviewer, member, ownerчитання (перелік/отримання історій, пошук, аналітика)
membermember, ownerусі записи робочих елементів (історії, завдання, коментарі, …)
ownerлише ownerналаштування проєкту, керування членством, ключі агентів, видалення, імпорт, журнал аудиту

Не-учасник отримує 404 unfound_resource (а не 403) на шляхах проєкту, тож ID проєктів не можна перелічити.

Самоописові кінцеві точки

Section titled “Самоописові кінцеві точки”
МетодШляхОпис
GET/openapi.jsonАктуальна специфікація OpenAPI 3. Без автентифікації.
GET/docsSwagger UI. Без автентифікації.
GET/metaІдентичність викликача (auth.kind/key_id/agent_id/project_id) + граф переходів за типом історій. Автентифікована (будь-який дійсний ключ; не обмежена проєктом). Викликайте її першою.

Обліковий запис / ідентичність

Section titled “Обліковий запис / ідентичність”

Ці діють на викликача і потребують лише дійсного ключа (без ролі в проєкті).

МетодШляхОпис
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Розв’язати токен запрошення → електронна пошта (без автентифікації)
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Контакт + внутрішньозастосунковий зворотний зв’язок

Довідкові дані (без автентифікації)

Section titled “Довідкові дані (без автентифікації)”

Стартові пошуки, що використовуються при створенні/оцінюванні історій. Стабільні ID.

МетодШляхОпис
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … 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) — дивіться Події

Учасники та ключі агентів

Section titled “Учасники та ключі агентів”
МетодШляхОпис
GET/projects/{id}/membershipsПерелічити учасників (viewer)
POST/projects/{id}/membershipsЗапросити учасника за електронною поштою (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. Перелік/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)

Пошук, аналітика, метрики, налаштування

Section titled “Пошук, аналітика, метрики, налаштування”
МетодШляхОпис
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, щоб відновитися.

МетодШляхОпис
POST/projects/{id}/import (+ /json)Завантаження multipart. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
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Коли
400invalid_parameterпоганий ввід; повідомлення в error, без details (більшість перевірок: порожнє/довжина/null-байт/email)
400validation_failedструктурована помилка вводу; details.fields — це масив імен полів, що порушують правило
401unauthenticatedвідсутній/недійсний токен
403unauthorized_operationавтентифіковано, але недостатня роль
404unfound_resourceне знайдено — також повертається не-учасникам
409conflictконфлікт ресурсу (наприклад, дублікат)
409idempotency_conflictIdempotency-Key повторно використано з іншим тілом
422invalid_transitionнеприпустимий рух стану; details несе { from, to, allowed }
500internal_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).