Przejdź do głównej zawartości

Przewodnik po API

Pierwsze kroki z REST API East Agile Tracker: klucze użytkownika i agenta, tworzenie i przesuwanie historii, idempotentne zapisy, wyszukiwanie, zdarzenia i paginacja.

API East Agile Tracker jest zaprojektowane dla agentów w równym stopniu co dla ludzi. Wszystko, co możesz zrobić w interfejsie, możesz zrobić przez API — a kilka rzeczy, których interfejs nie udostępnia, też tu jest.

Ten przewodnik przeprowadza Cię od zera do „skryptowania backlogu” w mniej niż dziesięć minut. Pełną referencję endpointów znajdziesz w Specyfikacji API.

Uwierzytelniasz się kluczem w nagłówku X-TrackerToken. Są dwa rodzaje kluczy, które wybijasz sam, i trzeci, który klient MCP uzyskuje za Ciebie:

  • Klucze użytkownika (ea_user_…) — Działają jako Ty. Twórz je w Account Settings → API Keys. Używaj ich do osobistych skryptów, narzędzi CLI, integracji.
  • Klucze agentów (ea_agent_…) — Działają jako nazwany agent w jednym projekcie. Twórz je w Project Settings → Agent. Używaj ich dla agentów AI — Claude Code, Codex, własnych — którzy powinni uczestniczyć w projekcie jako wymienieni z imienia członkowie zespołu.
  • Tokeny MCP (ea_mcp_…) — Tokeny dostępu OAuth 2.1 wydawane klientowi MCP (Claude, IDE) po tym, jak zatwierdzisz go na stronie zgody. Działają jako Ty, a odebrać je możesz w Account Settings → API Keys → Connected apps.

Jednorazowe okno po utworzeniu osobistego klucza API w Ustawieniach konta; klucz jest na tym zrzucie zamaskowany

Formularz tworzenia klucza na karcie Agent z nazwą i wybraną rolą member, pod instrukcjami konfiguracji

Różnice między tymi dwoma, które wybijasz sam:

Klucz użytkownikaKlucz agenta
ZasięgWszystkie Twoje projektyJeden konkretny projekt
Tożsamość w dzienniku audytuTwoje imięImię agenta
RolaTwoja rola w każdym projekcieUstawiana przy tworzeniu klucza (viewer, member lub manager — nigdy powyżej roli członka, który go wybija)
OdbieranieOdbierz klucz; zachowujesz dostęp przez inne klucze/sesjeOdbierz lub zrotuj klucz; agent natychmiast traci dostęp
Najlepszy doOsobistej automatyzacji, skryptówAgentów AI, którzy powinni być odróżnialni od Ciebie w historii

Authorization: Bearer … również działa, jeśli wolisz ten styl nagłówka.

Pobierz swoje projekty:

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

Albo, dla klucza agenta, wylistuj projekt, do którego jest przypisany:

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

API jest w JSON, w stylu REST, wersjonowane pod /api/v1/. Te same kształty dla ludzi i agentów.

Okno terminala
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
}'

Odpowiedź zawiera project_id oraz domyślne ustawienia iteracji zastosowane przez serwer (iteration_start_day, initial_velocity, iteration_length_weeks); GET /projects/{id} zwraca pełne ustawienia.

Okno terminala
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 to etykieta wartości ze skali podana jako łańcuch znaków — "3" albo "13" w skali Fibonacci — ponieważ musi odpowiadać punktowi na skali projektu. Liczba JSON jest odrzucana.

Endpoint przejścia waliduje żądany ruch i zwraca dozwolone następne stany w przypadku błędu:

Okno terminala
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" }'

Pole to to (a nie to_state). Jeśli ruch jest niedozwolony — powiedzmy, że spróbowałeś przeskoczyć z unstarted prosto do accepted — odpowiedzią jest 422 invalid_transition ze strukturyzowanymi szczegółami błędu:

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

To jedna z drobnych rzeczy, które czynią API przyjaznym dla agentów: agent może odczytać details.allowed i wybrać właściwy następny ruch bez zeskrobywania prozy.

rejected jest stanem terminalnym dla endpointu przejść, który odrzuca też to: "rejected". Odrzuć dostarczoną historię przez POST …/stories/{sid}/reject; przywróć odrzuconą historię do pracy przez POST …/stories/{sid}/restart, co działa, dopóki historia jest w bieżącej iteracji.

Okno terminala
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." }'

Komentarz jest przypisywany temu, kto jest właścicielem klucza API — jeśli to klucz agenta, autorem komentarza jest agent.

Endpointy zapisu akceptują nagłówek Idempotency-Key (z wyjątkiem przesyłania załączników). Ponów ten sam klucz z tym samym ciałem w ciągu 24 godzin, a otrzymasz tę samą odpowiedź. Ponów ten sam klucz z innym ciałem, a otrzymasz 409 idempotency_conflict:

Okno terminala
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" }'

To krytyczne dla agentów w pętlach ponawiania — awaria w połowie zapisu, ponowienie z tym samym kluczem, brak zduplikowanych historii. Odpowiedź 5xx, 401, 403, 404 lub 429 nigdy nie jest buforowana, więc ponowienie po niej wykonuje żądanie jeszcze raz.

Przesuwaj wiele historii naraz. Każda historia jest oceniana niezależnie; jeden niedozwolony ruch nie powoduje porażki pozostałych.

Okno terminala
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"
}'

Dla agentów, którzy chcą reagować na to, co robią ludzie, odpytuj endpoint zdarzeń:

Okno terminala
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"

Odpowiedź to { items, next_since_id, next_cursor }: każde zdarzenie niesie wykonawcę, zasób i zmianę. Zapisz next_since_id i przy następnym odpytaniu przekaż go jako since_id, aby wznowić tam, gdzie skończyłeś (since jest akceptowany jako starszy alias). Bez webhooków, bez zeskrobywania, bez pominiętych zdarzeń. Strumień wymaga roli member — viewer dostaje 403.

GET /projects/{id}/search?q=<query> uruchamia potężne wyszukiwanie pełnotekstowe i strukturalne po historiach projektu. Język zapytań jest wzorowany na kwalifikatorach wyszukiwania issue w GitHubie — więc składnia, którą Ty (albo agent AI) już znasz z GitHuba, w większości przenosi się tutaj.

Okno terminala
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'

Odpowiedzią jest koperta JSON, historie uszeregowane według trafności, gdy zapytanie zawiera wolny tekst, a w przeciwnym razie w kolejności tablicy:

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

total to pełna liczba dopasowań, a nie rozmiar strony. Stronicuj za pomocą limit (domyślnie 50, maks. 1000) oraz offset; porządkuj przez sort=relevance (domyślnie), created, created_asc, updated lub state.

  • Tekst swobodny dopasowuje tytuł, referencję i opis historii (pełnotekstowo, ze stemmingiem i rankingiem). Dokładną frazę ujmij w "cudzysłowy".
  • Kwalifikatory mają postać field:value. Alternatywy rozdziel przecinkiem (OR w obrębie jednego pola): type:bug,chore. Kwalifikatory rozdziel spacją (AND pomiędzy nimi).
  • Neguj dowolny człon lub kwalifikator wiodącym -: -label:wontfix.
  • Zakresy dla dat i punktów: domknięty a..b albo otwarty >x / <x.
KwalifikatorPrzykładDopasowuje
type:type:bug,choretyp(y) historii
state:state:started,finishedstan(y) przepływu pracy
label:label:"my label"etykietę
epic:epic:"Checkout"historie w epiku
priority:priority:p1priorytet
points:points:3 · points:1..5 · points:>3wartość estymacji albo zakres
iteration:iteration:42identyfikator iteracji
created: updated: started: completed: release:created:2026-05-01..2026-06-01 · updated:>2026-06-01datę albo zakres (z dokładnością do dnia); release: to data wydania historii
owner: requester: follower: reviewer: commenter: mention:owner:claire · owner:@meosobę po imieniu lub e-mailu — członków i agentów, łącznie z mention:; @me to Ty (z kluczem agenta — członek, który utworzył klucz)
has:blockerhas:blockerma otwarty bloker
is:is:unestimated · is:icebox · is:backlog · is:blockedflagę

mywork: jest aliasem owner: — mywork:me to owner:@me. Starszy kwalifikator scheduled: został wycofany i jest po cichu ignorowany; używaj release:.

Przecinkowe OR (type:bug,chore) dotyczy kwalifikatorów aspektowych; kwalifikatory osobowe (owner: requester: follower: reviewer: commenter: mention:) przyjmują jedną wartość.

payment crash tekst swobodny "payment" ORAZ "crash"
"exact phrase" fraza
type:bug,chore state:started bugs albo chores w stanie started
owner:@me -label:wontfix moje, z pominięciem etykiety wontfix
points:3..8 created:2026-05-01..2026-05-31 estymacja 3-8, utworzone w maju
follower:tomas has:blocker tomas obserwuje i jest zablokowane
is:backlog updated:>2026-06-01 pozycje backlogu ruszane od 1 czerwca

Ten sam łańcuch zapytania napędza pole wyszukiwania na tablicy (które otwiera kolumnę z wynikami na żywo) oraz to API — jedna gramatyka dla ludzi i agentów. Przeszukiwanie treści komentarzy, zadań i blokerów jest w planach; dziś tekst swobodny obejmuje własny tytuł, referencję i opis historii.

Żywa specyfikacja OpenAPI 3 znajduje się pod:

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

Swagger UI znajduje się pod:

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

/openapi.json i /docs są nieuwierzytelnione — agent może odczytać kontrakt, zanim będzie miał klucz. Gdy już ma klucz, /api/v1/meta (które wymaga prawidłowego klucza) zwraca jego tożsamość oraz graf przejść per typ historii; lookupy danych referencyjnych (/story_types, /story_states, /effort_scales, /priority_scales) są również nieuwierzytelnione. Razem pozwalają agentom odpowiedzieć na pytanie „co mogę tu zrobić?” bez błędów 403 metodą prób i błędów.

Serwowany openapi.json niesie schematy ciał żądań dla endpointów zapisu, wraz z maxLength każdego pola, więc klient może zwalidować dane przed wysłaniem. Specyfikacja streszcza te same kształty.

Jeśli skryptujesz masową migrację:

Okno terminala
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"

Obsługiwane źródła plikowe: pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat (własny eksport East Agile Tracker — format do przenoszenia w obie strony). Endpoint multipart działa synchronicznie i odpowiada liczbami wyników.

GitHub importuje z API zamiast z pliku, przez endpoint JSON — bez file, wystarczą współrzędne repozytorium:

Okno terminala
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
}'

Endpoint JSON jest asynchroniczny: odpowiada 202 z { "import_id", "status" }, a Ty odpytujesz GET /projects/{id}/imports/{import_id}, aż zadanie osiągnie done albo failed. W jednym projekcie działa naraz tylko jeden import — drugie wywołanie w trakcie trwającego to 409 import_already_running. Cała pętla, wraz z polami postępu zadania, jest w Zapełnij projekt z repozytorium GitHub.

token jest opcjonalny w żądaniu, ale samo pobieranie zawsze się uwierzytelnia — idzie przez API GraphQL GitHuba, które nie ma warstwy anonimowej. Pomiń token, a serwer podstawi swój token platformowy: wyłącznie repozytoria publiczne, współdzielony przez każdego wywołującego i odrzucany z import_github_shared_quota_low, gdy jego budżet GraphQL spadnie poniżej 500 punktów. Repozytorium prywatne albo wdrożenie, w którym nie skonfigurowano tokenu platformowego (import_github_no_token), wymaga twojego. Którykolwiek token zadziała, służy wyłącznie do wywołań w górę do GitHuba i nigdy nie jest przechowywany ani zwracany. Pełne szczegóły, łącznie z nieuwierzytelnionym pułapem REST 60 żądań u GitHuba, są w Zapełnij projekt z repozytorium GitHub.

Podgląd na sucho (dry-run). Dodaj "dry_run": true (JSON) albo -F "dry_run=true" (multipart) do dowolnego źródła. Import parsuje, rozwiązuje i deduplikuje dokładnie tak jak prawdziwe uruchomienie, produkuje te same liczby wyników (imported, skipped, errors, unmatched), po czym cofa wszystko — nic nie jest zapisywane. W endpointcie JSON liczby pojawiają się na odpytywanym zadaniu, niezależnie od tego, czy to przebieg próbny.

Limity. Plik importu jest ograniczony do 10 MiB i 5000 historii (400 import_too_large / import_too_many_records, bez żadnego zapisu); import z GitHuba nie ma limitu historii. Ponowny import pliku jest bezpieczny — wiersze już zaimportowane (dopasowane po identyfikatorze źródłowym) są pomijane, a nie duplikowane.

Każda rola w projekcie może wylistować formaty; pobranie któregoś wymaga roli manager:

Okno terminala
# 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

Identyfikatory formatów wymiany: eat, jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json, plus formaty dokumentów pdf oraz docx. Każdy załącznik można pobrać jako jeden zip z GET /projects/{id}/export/attachments.

Wszystkie błędy są w JSON, z co najmniej:

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

Wiele odpowiedzi błędów zawiera również obiekt details — details.fields (tablica nazw wadliwych pól) przy validation_failed oraz details.allowed (obok from/to) przy 422 invalid_transition. Korzystaj z nich. 429 rate_limited niesie nagłówek Retry-After w tej samej kopercie JSON.

Endpointy listujące akceptują limit i cursor. Kursor jest nieprzezroczysty; przekaż next_cursor z poprzedniej odpowiedzi. Limit limit zależy od endpointu — 200 dla historii, komentarzy i projektów, 500 dla zdarzeń, 1000 dla dziennika audytu; wyszukiwanie stronicuje przez limit (≤ 1000) i offset. Zwykła (bezkursorowa) lista, która musiała przyciąć odpowiedź, mówi o tym w nagłówkach: X-Tracker-Pagination-Truncated, -Limit, -Offset oraz -Next-Offset, który przekazujesz z powrotem jako offset= dla następnej strony. Nie ma nagłówka z łączną liczbą.