Przejdź do głównej zawartości

Specyfikacja API

Pełna dokumentacja endpointów REST API East Agile Tracker: uwierzytelnianie i role, projekty, historie, epiki, iteracje, zdarzenia, import i eksport.

Kompletna referencja endpointów REST. Samouczki i przykłady znajdziesz w Przewodniku po API.

Wszystko, co member projektu może zrobić w interfejsie webowym, jest dostępne tutaj — SPA korzysta z tego samego API. Operacje wymagające roli manager są oznaczone (manager); wszystko inne wymaga jedynie członkostwa w projekcie (lub, dla odczytów oznaczonych (viewer), dowolnego poziomu dostępu). Poniższe tabele wymieniają każdą grupę tras montowaną przez serwer; te streszczone w jednym wierszu są w pełni opisane w żywym openapi.json.

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

API ma własny host: eastagiletracker.com serwuje aplikację webową i odpowiada na /api/v1/… kodem 404. Wszystkie żądania i odpowiedzi są w JSON, z wyjątkiem kilku endpointów przesyłania plików, które akceptują multipart.

Dwie grupy znajdują się poziom wyżej, pod /api zamiast /api/v1: powierzchnia uwierzytelniania (/api/auth/*) oraz publiczny formularz kontaktowy (/api/contact). Ich warianty /api/v1/… zwracają 404.

Każde uwierzytelnione żądanie wysyła poświadczenie za pomocą jednego z:

  • X-TrackerToken: <key>
  • Authorization: Bearer <key>

Klucze użytkownika zaczynają się od ea_user_, klucze agentów od ea_agent_, a tokeny dostępu MCP od ea_mcp_. Zobacz Przewodnik po API → Trzy rodzaje poświadczeń.

Endpointy nieuwierzytelnione: /openapi.json, /docs, endpointy /api/auth/* oraz lookupy danych referencyjnych (/story_types, /story_states, /effort_scales, /priority_scales). /meta jest uwierzytelnione — działa każdy prawidłowy klucz, ale nie jest przypisane do projektu (klucz agenta związany z projektem również do niego dociera).

Cztery poziomy bramkują endpointy o zasięgu projektu:

PoziomKto przechodziTypowe operacje
public viewerkażdy, w projekcie o widoczności publicznejodczyty tablicy: historie, iteracje, wyszukiwanie, aktywność historii i epików (z utajnionymi danymi wykonawcy)
viewerviewer, member, managerodczyty (listowanie/pobieranie historii, wyszukiwanie, metryki, lista formatów eksportu)
membermember, managerwszystkie zapisy elementów pracy (historie, zadania, komentarze, …), strumień zdarzeń
managertylko managerustawienia projektu, zarządzanie członkostwem, klucze agentów, usuwanie, import, pobieranie eksportów, kopie zapasowe, dziennik audytu

Agenci mają te same role co członkowie — viewer, member lub manager — ograniczone rolą członka, który wybił klucz. Osoba niebędąca członkiem otrzymuje 404 unfound_resource (a nie 403) na ścieżkach prywatnych projektów, więc identyfikatory projektów nie są wyliczalne.

MetodaŚcieżkaOpis
GET/openapi.jsonŻywa specyfikacja OpenAPI 3, łącznie z ciałami żądań. Nieuwierzytelniona.
GET/docsSwagger UI. Nieuwierzytelniona.
GET/metaTożsamość wywołującego (auth.kind/key_id/agent_id/project_id) + graf przejść per typ historii. Uwierzytelnione (dowolny prawidłowy klucz; nieprzypisane do projektu). Wywołaj to jako pierwsze.
GET/api/health · /api/configStan działania oraz publiczna konfiguracja wdrożenia (tryb jednej organizacji, włączone funkcje opcjonalne, nazwa instancji). Nieuwierzytelnione, poza /v1.

Endpointy sesji, nieuwierzytelnione, o ile nie zaznaczono inaczej. Korzysta z nich SPA; skrypty zwykle używają zamiast tego klucza API.

MetodaŚcieżkaOpis
POST/auth/registerZarejestruj nowe konto — chronione przez reCAPTCHA; konto przechodzi następnie wyzwanie SMS
POST/auth/sms/challenge · /auth/sms/status · /auth/sms/bypassWyślij / sprawdź kod SMS przy rejestracji (bypass kontroluje operator)
GET/auth/configJakie metody logowania oferuje wdrożenie
POST/auth/loginZaloguj się e-mailem + hasłem; zwraca JWT sesji albo wyzwanie TOTP
POST/auth/login/totpDokończ logowanie kodem z aplikacji uwierzytelniającej lub kodem odzyskiwania
POST/auth/passkey/login/start · /auth/passkey/login/finishLogowanie WebAuthn bez hasła
GET/auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchangeLogowanie OAuth przez GitHub lub Google
POST/auth/refresh · /auth/refresh/revokeZrotuj token odświeżający / unieważnij go
POST/auth/logoutWyloguj się (wymaga uwierzytelnienia; unieważnia token odświeżający tej sesji)
POST/auth/forgot-password · /auth/reset-passwordPoproś o e-mail resetujący / użyj tokenu resetującego
POST/auth/accept-invite/lookup · /auth/accept-inviteRozwiąż token zaproszenia → e-mail / zaakceptuj zaproszenie do projektu (po uwierzytelnieniu)
POST/auth/oauth/link/preview · …/link/confirm · /auth/oauth/merge/preview · …/merge/confirmPołącz konto GitHub lub Google z istniejącym kontem albo scal dwa konta
POST/auth/email_addresses/primary/preview · …/primary/confirmDokończ zmianę głównego e-maila z linku potwierdzającego wysłanego e-mailem

Te operują na wywołującym i nie wymagają roli projektowej. Wymagają tożsamości członka — klucz agenta dostaje 401 (agenci używają /agent/me). Wywołania zmieniające poświadczenia — hasło, TOTP, passkeys, usunięcie konta, zmiana e-maila, regeneracja tokenu — wymagają sesji przeglądarki; klucz API dostaje 403.

MetodaŚcieżkaOpis
GET/meProfil bieżącego użytkownika
PUT/meZaktualizuj profil
DELETE/meUsuń konto — odrzucane, dopóki jesteś jedynym właścicielem organizacji lub projektu z innymi członkami
GET/me/deletion-impactCo usunięcie konta by usunęło i co je blokuje
PUT/me/passwordZmień hasło
PUT/me/settingsZaktualizuj ustawienia (motyw, preferencje powiadomień)
POST / DELETE/me/avatarPrześlij (multipart) / usuń swój awatar
POST/me/api-token/regenerateWyloguj każdą sesję i zwróć nowy token sesji; klucze API pozostają nienaruszone
GET / POST/me/email_addresses · GET …/email_addresses/offers · PUT …/email_addresses/primaryTwoje adresy e-mail; przyjmij adres połączonego dostawcy jako alternatywny; poproś o zmianę głównego adresu (potwierdzaną e-mailem)
GET/me/oauth_identities · DELETE …/oauth_identities/{provider} · POST …/oauth_identities/{provider}/linkPołączone konta logowania (GitHub, Google): wylistuj, odłącz, rozpocznij łączenie
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}Zarządzaj kluczami API użytkownika (ea_user_)
GET/me/totp · POST /me/totp/setup · /me/totp/verify · /me/totp/disableKonfiguracja uwierzytelniania dwuskładnikowego (TOTP); verify zwraca kody odzyskiwania jednorazowo
GET/me/passkeys · POST /me/passkeys/register/start · /me/passkeys/register/finish · DELETE /me/passkeys/{credential_id}Rejestracja i usuwanie passkeyów
GET/me/oauth_grants · DELETE /me/oauth_grants/{grant_id}Połączone aplikacje — klienci MCP i aplikacje OAuth, które autoryzowałeś
GET/me/activityTwoja aktywność we wszystkich projektach
GET/me/storiesHistorie, których jesteś właścicielem, zgłaszającym lub obserwującym, we wszystkich projektach dostępnych dla tokenu — role=owned|requested|following, state=, cursor= / limit= (maks. 200)
GET/me/mentions · POST /me/mentions/{mention_id}/ackSkrzynka @-wzmianek (unacked=true, aby filtrować) i potwierdzanie — wzmianki trafiają też do feedu powiadomień poniżej
GET/me/data-exportSamodzielny eksport Twoich danych zgodny z RODO
GET/me/consent · POST /me/consentOdczyt / zapis zgody ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptOczekujące dokumenty clickwrap / zapis akceptacji
GET / PUT/agent/meWłasna tożsamość i profil klucza agenta, do odczytu i edycji przez agenta (agentowy odpowiednik /me)
POST/api/contact · /api/v1/feedback · /api/v1/feedback/with-screenshotKontakt + opinia w aplikacji; limit szybkości per IP

Lookupy zasiewane używane przy tworzeniu/estymowaniu historii. Stabilne identyfikatory.

MetodaŚcieżkaOpis
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scalesdostępne skale estymacji
GET/effort_scales/{scale_id}/valueswartości punktowe w skali
GET/priority_scales · /priority_scales/{scale_id}/valuesskale priorytetów i ich wartości (tu rozwiązuje się priority_id historii)

Tylko usługa hostowana — instalacja samodzielnie hostowana działa w trybie jednej organizacji i nie montuje tych endpointów (poza listą organizacji). Role są rolami organizacyjnymi: owner, admin, member.

MetodaŚcieżkaOpis
GET / POST/organizationsWylistuj swoje organizacje / utwórz nową
GET / PUT / DELETE/organizations/{oid}Odczytaj, zmień nazwę (nazwa + slug; owner lub admin), usuń
GET / POST/organizations/{oid}/memberships · PUT / DELETE …/memberships/{member_id}Członkowie i zaproszenia; zaproszenia mają sufit roli (nigdy powyżej roli wywołującego; do roli owner nikogo się nie zaprasza)
POST/organizations/{oid}/memberships/bulk-role · …/memberships/bulk-removeZmiana roli lub usunięcie do 200 członków naraz. Wszystko albo nic: partia, która usunęłaby ostatniego ownera lub zostawiła projekt bez właściciela, jest odrzucana w całości; z reassign_confirmed zamiast tego stajesz się właścicielem tych projektów
DELETE/organizations/{oid}/invitations/{invitation_id}Cofnij oczekujące zaproszenie
POST/organizations/{oid}/transfer-ownershipPrzekaż rolę owner innemu członkowi
GET/organization-invitations/{token} · POST …/{token}/acceptRozwiąż / zaakceptuj zaproszenie do organizacji wysłane e-mailem
GET/organizations/{oid}/export · POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/downloadEksport organizacji tylko dla właściciela: zip ze zrzutem SQL i każdym załącznikiem, uruchamiany jako zadanie
MetodaŚcieżkaOpis
GET/projectsWylistuj swoje projekty (limit ≤ 200)
POST/projectsUtwórz projekt
GET/projects/{id}Pobierz szczegóły projektu (viewer)
PUT/projects/{id}Zaktualizuj ustawienia projektu (manager)
DELETE/projects/{id}Usuń projekt (manager)
POST / DELETE/projects/{id}/pinPrzypnij / odepnij projekt na swojej liście projektów
POST/projects/{id}/transfer-organizationPrzenieś projekt do innej organizacji — wywołujący musi być Menedżerem projektu oraz właścicielem lub administratorem organizacji docelowej
POST/projects/{id}/slack/testWyślij wiadomość testową do kanału Slack projektu (manager)
GET / POST/projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seedPubliczne projekty pokazowe: sprawdź, czy możesz przejąć projekt, przejmij go, zasiej go danymi (zasiewanie jest dla administratorów produktu; każdy inny dostaje 404)
GET/projects/{id}/audit-logOdczyt audit logu — historia projektu plus aktywność per historia / per epic przez surface=; dostęp zależy od surface, zobacz poniżej
GET/projects/{id}/eventsStrumień zdarzeń stronicowany kursorem (member) — zobacz Zdarzenia

Parametry zapytania audit logu: event_type= (jeden typ lub lista rozdzielona przecinkami), limit= (domyślnie 50, przycinany do 1000), before= (kursor keyset <ISO-8601>|<audit_id> — przekaż next_cursor poprzedniej strony), surface= (project_history, story_activities, epic_activities), target_id= (id historii/epica — wymagane, gdy surface=story_activities lub epic_activities). Dostęp: niefiltrowany log to (manager); surface=project_history to (viewer), z usuniętymi e-mailami członków, gdy projekt je ukrywa; story_activities / epic_activities może czytać każdy członek projektu, a w projektach publicznych także anonimowo, z usuniętymi danymi osobowymi aktora.

MetodaŚcieżkaOpis
GET/projects/{id}/membershipsWylistuj członków (viewer)
POST/projects/{id}/membershipsZaproś członka przez e-mail (manager)
PUT/projects/{id}/memberships/{mid}Zaktualizuj rolę (manager)
DELETE/projects/{id}/memberships/{mid}Usuń członka (manager)
POST/projects/{id}/memberships/bulk-role · …/memberships/bulk-removeZmień rolę wielu członków naraz albo ich usuń (manager)
GET/projects/{id}/addable-members · POST /projects/{id}/members/add-existingCzłonkowie organizacji, których jeszcze nie ma w projekcie / dodaj jednego bez zaproszenia e-mailem — (manager) oraz właściciel lub administrator organizacji
POST/projects/{id}/members/joinOwner lub admin organizacji dołącza do projektu w swojej organizacji jako manager albo awansuje się do tej roli (akcja Make me owner na liście projektów)
GET / POST/projects/{id}/agent_keysWylistuj (manager) / wybij klucze agentów — osoby, których rola jest w creator-roles policy projektu; klucze agentów nie mogą wybijać kluczy
PUT / DELETE/projects/{id}/agent_keys/{kid}Edytuj nazwę, rolę lub response hints klucza / odbierz go (manager)
GET/projects/{id}/agent_keys/onboardingPakiet onboardingowy: prompty i pliki konfiguracyjne dla popularnych klientów agentowych
GET/projects/{id}/agents · GET / PUT / DELETE /projects/{id}/agents/{aid}Agenci projektu i ich profile (nazwa, inicjały, opis, kolor); DELETE odbiera agenta i wszystkie jego klucze — menedżer lub twórca agenta
POST/projects/{id}/agents/{aid}/rotate-key · /projects/{id}/agents/{aid}/avatarZrotuj klucz agenta (tożsamość i historia zostają) / prześlij jego awatar

Wszystkie zapisy historii wymagają roli member. Utworzenie historii z datami wstecznymi, pochodzeniem importu (import_source / import_external_id) albo zewnętrznymi właścicielami lub zgłaszającym wymaga (manager).

MetodaŚcieżkaOpis
GET/projects/{id}/storiesWylistuj historie (stronicowane, filtrowalne) (viewer)
POST/projects/{id}/storiesUtwórz historię
GET/projects/{id}/stories/{sid}Pobierz jedną historię (viewer)
PUT/projects/{id}/stories/{sid}Zaktualizuj historię
DELETE/projects/{id}/stories/{sid}Usuń historię
POST/projects/{id}/stories/{sid}/transitionsZmień stan z walidacją
POST/projects/{id}/stories/{sid}/reject · /projects/{id}/stories/{sid}/restartOdrzuć dostarczoną historię / przywróć odrzuconą do started (rejected jest stanem końcowym dla /transitions)
POST/projects/{id}/stories/{sid}/archive · /projects/{id}/stories/{sid}/unarchiveZarchiwizuj / przywróć z archiwum jedną historię
POST/projects/{id}/stories/bulk-unarchivePrzywróć z archiwum wiele historii
POST/projects/{id}/stories/bulk_transitionPrzejdź wieloma historiami (1–100) naraz
POST/projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-moveZarchiwizuj, usuń, zduplikuj lub przenieś (do panelu / na pozycję) wiele historii
POST/projects/{id}/stories/{sid}/duplicateZduplikuj jedną historię
POST / DELETE/projects/{id}/stories/{sid}/epics · …/epics/{eid}Przynależność historii do epików
GET/short-links/{code} · /story-referencesRozwiąż krótki link /s/<code> do jego historii / rozwiąż do 100 odwołań — codes= (kody krótkich linków rozdzielone przecinkami) i ids= (project_id:story_id rozdzielone przecinkami) — na historie, które wywołujący może odczytać

Parametry zapytania listy historii: archived= (exclude domyślnie / include / only — trójstanowy filtr archiwum; zastępuje przestarzałe include_archived=true, będące teraz aliasem archived=include), include_done=true (dopuszcza historie panelu Done zamrożone na minionych iteracjach, domyślnie wykluczone). Stronicowanie (cursor= / limit= / offset=) i rzadkie zestawy pól (fields=) działają zgodnie z sekcjami Stronicowanie i Projekcja pól.

Tworzenie (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. estimate to etykieta wartości skali jako ciąg znaków ("3", "13"); liczba JSON jest odrzucana. labels akceptuje ["auth"] lub [{ "name": "auth" }]; nieznane etykiety są tworzone. Wartości domyślne: story_type=feature, current_state=unstarted.

Aktualizacja (PUT …/stories/{sid}): te same pola, wszystkie opcjonalne, plus "position" (float), "force_state_change" (bool) i "expected_version" (liczba całkowita, version historii — zapis opisu jest odrzucany z 409 stale_write, jeśli opis zmienił się po tej wersji). Starsze "expected_updated_at" (RFC 3339) jest przestarzałe i działa jeszcze przez jedno wydanie: wysłane z opisem i bez expected_version powoduje odrzucenie zapisu z 409 stale_write, chyba że jest równe updated_at historii. Zapisy historii respektują też If-Match względem ETag historii; niezgodność daje 412 precondition_failed.

Przejście (POST …/transitions): { "to": "<state>" }. Pole to to. Zwraca { story_id, state }. Niedozwolony ruch → 422 invalid_transition z details: { from, to, allowed }.

Przejście zbiorcze (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>" }. Każda historia jest oceniana niezależnie; zwraca { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

Wszystkie member. Listowanie/GET dla większości to (viewer). Usunięcie załącznika lub załącznika-linku wymaga osoby, która go przesłała, albo (manager).

MetodaŚcieżkaCiało / uwagi
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) } lub { comment_emoji }. GET przyjmuje fields= (lista dozwolonych: comment_id, story_comment_id, story_id, comment_text, comment_emoji, member, created) oraz cursor= / limit= (≤ 200) / order=asc|desc
GET / POST/projects/{id}/stories/{sid}/blockers · PUT/DELETE …/blockers/{bid}{ blocker_desc, resolved? }
GET / POST/projects/{id}/stories/{sid}/links · PUT/DELETE …/links/{lid}Tworzenie: { url, link_type?, title? }; aktualizacja: { url, title? } — link_type ∈ relates_to, duplicates, blocks, is_blocked_by, pull_request, branch, other; adresy URL GitHuba z /pull/ i /tree/ są typowane automatycznie
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}Tworzenie: { reviewer_id? / reviewer_agent_id?, comment? } — pomiń oba, aby przypisać siebie. Aktualizacja: { status, comment? }
GET / POST/projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid}{ member_id? / agent_id? } — pomiń oba, aby dodać wywołującego
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}{ label_id } — istniejąca etykieta projektu; etykiety twórz przez POST /projects/{id}/labels albo wyślij labels w PUT historii
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}przesyłanie multipart — wideo ≤ 200 MB, PDF / Word / Excel ≤ 25 MB, obrazy / CSV / tekst ≤ 10 MB; listowanie to (viewer)
GET / POST/projects/{id}/stories/{sid}/link-attachments · DELETE …/link-attachments/{laid}Załączniki-linki — zewnętrzny adres URL przechowywany obok załączników plikowych, a nie jako powiązanie z kodem
GET/attachments/{token} · /api/v1/avatars/{token}Odczyty załącznika lub awatara adresowane tokenem — adresy URL, które wydaje API; X-TrackerToken nie jest potrzebny

Ten sam kształt co historie, bez maszyny stanów. member dla zapisów oraz list komentarzy, właścicieli i obserwujących; (viewer) dla listy epiców, pojedynczego epica i list załączników.

MetodaŚcieżkaOpis
GET / POST/projects/{id}/epics · GET / PUT / DELETE …/epics/{eid}Epiki mają nazwę, opis w Markdown i powiązaną etykietę, która łączy ich historie
GET / POST / PUT / DELETE…/epics/{eid}/comments · …/comments/{cid}Komentarze epików
GET / POST / DELETE…/epics/{eid}/owners · …/followers (+ warianty /agents/{aid})Właściciele i obserwujący, członkowie lub agenci — właściciele epiku przechodzą na jego historie
GET / POST / DELETE…/epics/{eid}/attachments (+ /json) · …/link-attachmentsZałączniki, te same limity co w historiach
GET/projects/{id}/analytics/epics · …/analytics/epics/{eid}Postęp per epik: burnup, przepustowość, kondycja, prognoza (viewer)

member dla zapisów, (viewer) dla odczytów.

MetodaŚcieżkaOpis
GET / POST/projects/{id}/labelsWylistuj / utwórz etykietę
GET / PUT / DELETE/projects/{id}/labels/{lid}Odczytaj / zaktualizuj / usuń etykietę
POST/projects/{id}/labels/{lid}/archiveZarchiwizuj (miękko ukryj) etykietę

Odczyty są otwarte dla każdej roli w projekcie, a w projekcie publicznym także anonimowo.

MetodaŚcieżkaOpis
GET/projects/{id}/iterationsWylistuj iteracje (≤ 500 na stronę; przy obcięciu niesie ETag i nagłówki kontynuacji X-Tracker-Pagination-*)
GET/projects/{id}/iterations/{itid}Jedna iteracja
GET/projects/{id}/iterations/first-previewOkno, prognozowana prędkość i wypełnienie z Backlogu iteracji, którą utworzyłby zapis inicjujący, albo bieżącej iteracji, jeśli istnieje (member)
POST/projects/{id}/iterationsUtwórz ręczną iterację (manager)
DELETE/projects/{id}/iterations/{itid}Usuń iterację (manager)
PUT/projects/{id}/iterations/{itid}/velocityNadpisz prędkość jednej iteracji bez zmiany strategii projektu (manager)
GET/projects/{id}/iterations/{itid}/done-storiesZaakceptowane historie zamkniętej iteracji, stronicowane
MetodaŚcieżkaOpis
GET/projects/{id}/search?q=…Potężne wyszukiwanie — pełnotekstowe + kwalifikatory aspektów / zakresów dat / osób (DSL w stylu GitHuba); zwraca { results, total, limit, offset }. query to alias q; limit= (domyślnie 50, maks. 1000) / offset= stronicują; sort= porządkuje według relevance (domyślnie), created, created_asc, state lub updated. (viewer) — zobacz Przewodnik
GET/projects/{id}/metrics/{velocity,burndown,story-types,contributors}Serie danych strony Metrics (viewer); metryki epików są pod /analytics/epics powyżej
GET/projects/{id}/backlog/groupingPrognozowane grupy iteracji Backlogu (viewer)
GET / PUT/projects/{id}/preferencesTwoje preferencje tablicy dla tego projektu — dowolna rola w projekcie, tylko Twój własny wiersz
MetodaŚcieżkaOpis
GET/projects/{id}/eventsStrumień zdarzeń stronicowany kursorem (member) — viewerzy dostają 403

Parametry zapytania: since_id=<event_id> (since to starszy alias; since_id wygrywa, gdy wysłane są oba), types=story.created,story.transitioned,comment.added,…, limit= (domyślnie 100, ≤ 500), cursor=. Odpowiedź to { items, next_since_id, next_cursor }: zapisz next_since_id i przekaż go z powrotem jako since_id, aby wznowić; next_cursor jest null na ostatniej stronie.

Ujednolicony feed powiadomień w aplikacji: pełnoprawne wiersze powiadomień (prośby o review, aktywność na story, zaproszenia, …) połączone ze skrzynką @-wzmianek w jeden strumień, od najnowszych. Id w feedzie mają prefiks źródła (nt-… / sc-… / ec-…). Sesje członków i klucze ea_user_* czytają swoje wiersze członkowskie; klucze ea_agent_* swoje wiersze agentowe.

MetodaŚcieżkaOpis
GET/me/notificationsTwój feed powiadomień. Filtry: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); stronicuj przez cursor= / limit=
GET/me/notifications/unread-countSumy nieprzeczytanych — { unread_count, by_category: { mentions, reviews, stories, invitations } }
POST/me/notifications/read-allOznacz wszystko jako przeczytane; zwraca świeże liczniki
POST/me/notifications/{id}/ackOznacz jeden element jako przeczytany (idempotentne)
POST/me/notifications/{id}/acceptZaakceptuj zaproszenie do projektu / organizacji z poziomu feedu (tylko tokeny członkowskie)
POST/me/notifications/{id}/declineOdrzuć zaproszenie do projektu / organizacji (tylko tokeny członkowskie)
GET/me/notifications/resolve-invite?token=…Zamień e-mailowy token zaproszenia na id Twojego powiadomienia — { "id": "nt-…" } albo { "id": null }
GET/me/notifications/streamPush na żywo — Server-Sent Events (text/event-stream); patrz niżej

Endpoint stream nie jest endpointem JSON i dlatego nie ma go w specyfikacji OpenAPI: utrzymuje otwarte połączenie i przy każdym nowym zdarzeniu wysyła ramkę bez payloadu ({"type":"notification","kind":…}), sygnalizując klientowi, by pobrał feed ponownie. Połączenia są zamykane po stronie serwera po 45 minutach — połącz się i uwierzytelnij ponownie. Tylko sesje członków i klucze ea_user_*; klucze ea_agent_* dostają 403.

MetodaŚcieżkaOpis
POST/projects/{id}/importŹródła plikowe: source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. Multipart file=. Synchroniczny — odpowiada liczbami wyników.
POST/projects/{id}/import/jsonCiało JSON; source=github nie potrzebuje pliku — owner, repo, opcjonalnie token oraz opt-in flagi include_pull_requests / include_milestones / include_releases / include_dependencies, oraz include_comments (domyślnie true); źródła plikowe wysyłają file_base64. Asynchroniczny: zwraca 202 { import_id, status }. Serwer pobiera przez API GraphQL GitHuba, które odrzuca anonimowych wywołujących, więc do GitHuba zawsze trafia token — twój albo współdzielony token wdrożenia. Zobacz Przewodnik.
GET/projects/{id}/imports/{import_id}Odpytuj zadanie: status przechodzi pending → fetching → writing → done | failed, z progress_current / progress_total podczas pobierania i liczbami wyników przy done

W projekcie działa naraz jeden import JSON; drugi POST …/import/json, gdy jeden trwa, daje 409 import_already_running. Z check_unpointed_estimates: true (źródła plikowe; ignorowane dla github) plik zawierający oszacowania błędów lub zadań, których projekt nie punktuje, jest odrzucany z 409 import_unpointed_estimates i details.count zanim ruszy jakiekolwiek zadanie; bez flagi import odrzuca te oszacowania i zgłasza { code: "estimates_unpointed_dropped", count } w warnings wyniku. dry_run: true (ciało JSON lub dry_run=true w multipart) podglądowo uruchamia dowolne źródło: parsuje, rozwiązuje, deduplikuje, zwraca te same liczby { imported, skipped, errors, unmatched }, po czym cofa zmiany — nic nie jest zapisywane. Limity: plik 10 MiB (400 import_too_large) i 5000 historii na import dla źródeł plikowych (400 import_too_many_records); nic nie jest zapisywane. Ciało żądania powyżej 16 MiB jest odrzucane wcześniej z 413 request_too_large. Źródło GitHub nie ma limitu — zapisuje partiami zamiast w jednej transakcji. Ponowny import jest idempotentny per identyfikator źródłowy — już zaimportowane wiersze są pomijane, a nie duplikowane.

MetodaŚcieżkaOpis
GET/projects/{id}/export/formatsZarejestrowane formaty: { id, name, content_type, drops, includes_archived }. Dowolna rola w projekcie.
GET/projects/{id}/export/{format}Pobierz jeden (manager). Wymiana: eat (pełna wierność), jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json; dokumenty: pdf, docx.
GET/projects/{id}/export/attachmentsKażdy załącznik jako jeden przeglądalny zip (pliki zachowują oryginalne nazwy; manifest JSON + CSV) (manager).

Eksporty dokumentów (pdf, docx) przyjmują dodatkowe parametry zapytania: page_size= (letter domyślnie / a4 / legal / folio), from= / to= (granice okna historii — RFC 3339 lub samo YYYY-MM-DD; historia mieści się w zakresie, gdy jej created lub completed_at w niego wpada), include_icebox= / include_backlog= (oba domyślnie false, więc eksport do udostępnienia pokazuje tylko pracę zaplanowaną / w toku). Formaty wymiany CSV je ignorują.

MetodaŚcieżkaOpis
GET / POST/projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/healthWylistuj migawki, wykonaj jedną teraz, odczytaj jedną oraz podsumowanie kondycji retencji
POST/projects/{id}/restores · POST …/restores/partial · GET …/restores/{restore_id}Przywróć całą migawkę albo wybrane tabele z jednej i odpytuj przebieg przywracania

Te POST podlegają wrażliwemu poziomowi limitu szybkości (poniżej).

East Agile Tracker jest dostawcą OAuth 2.1 dla klientów MCP. Klient odkrywa go pod /.well-known/oauth-authorization-server i /.well-known/oauth-protected-resource/mcp, kieruje Cię do /oauth/authorize (strona zgody), wymienia kod pod /oauth/token, a następnie komunikuje się przez MCP pod /mcp z uzyskanym tokenem ea_mcp_*. Uprawnienia są listowane i odbierane pod /me/oauth_grants. Endpointy dostawcy mają własny poziom limitu szybkości.

Endpointy zapisu (POST, PUT, DELETE) akceptują nagłówek Idempotency-Key. Ten sam klucz + to samo ciało odtwarza zbuforowaną odpowiedź (okno 24-godzinne); ten sam klucz + inne ciało zwraca 409 idempotency_conflict. Klucz jest przypisany do poświadczenia, które go wysłało. Nie stosowane do GET/HEAD/OPTIONS, /openapi.json i /docs, /api/auth/*, /mcp, żadnej ścieżki zawierającej /attachments ani żadnego żądania multipart/*; żądanie bez poświadczenia nigdy nie jest buforowane. Odpowiedzi, które zakończyły się przed odpowiedzią domeny, nigdy nie są buforowane — 401, 403, 404, 429 i każde 5xx — więc ponowienie po którejkolwiek z nich dociera do handlera; 400, 409, 412 i 422 są odpowiedzią domeny i są odtwarzane jak sukces.

Endpointy listujące akceptują cursor=<opaque> i limit=<n>. Gdy ustawione, odpowiedź to { "items": [...], "next_cursor": "<str|null>" }; przekaż next_cursor z powrotem, aby stronicować. 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 zamiast kursora i zwraca { results, total, limit, offset }.

Zwykła lista (bez cursor/limit), która musiała obciąć odpowiedź, sygnalizuje to w nagłówkach — X-Tracker-Pagination-Truncated, X-Tracker-Pagination-Limit, X-Tracker-Pagination-Offset i X-Tracker-Pagination-Next-Offset; przekaż ostatni z nich jako offset=, aby pobrać następną stronę. Nie ma nagłówka z łączną liczbą.

Listy historii, komentarzy i projektów akceptują fields= (rozdzielone przecinkami), aby zwrócić tylko określone pola. Identyfikator zasobu jest zawsze dołączany (story_id, story_comment_id i comment_id, project_id); nieznana nazwa pola zwraca 400 validation_failed z wadliwymi nazwami w details.fields.

GET /projects/123/stories?fields=story_id,name,current_state,owners

Każdy błąd JSON ma code i error; niektóre dodają details:

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
StatuscodeKiedy
400invalid_parameterbłędne wejście; komunikat w error. Walidacja pól (puste/długość/bajt null/e-mail) dodaje details.fields i details.constraint; details pomija tylko zwykły błąd nieprawidłowego żądania
400validation_failedstrukturyzowany błąd wejścia; details.fields to tablica nazw wadliwych pól
400kody domenoweodmowa specyficzna dla trasy, z własnym kodem i bez details — np. unsupported_export_format, import_too_large, import_unknown_source
401unauthenticatedbrakujący/nieprawidłowy token
403unauthorized_operationuwierzytelniony, ale niewystarczająca rola
404unfound_resourcenie znaleziono — zwracane również osobom niebędącym członkami
409conflictkonflikt zasobu (np. duplikat)
409idempotency_conflictIdempotency-Key użyty ponownie z innym ciałem
409stale_write · import_already_running · import_unpointed_estimatesopis zmienił się po Twoim expected_version (albo expected_updated_at już się nie zgadza) · import już trwa · plik zawiera oszacowania błędów lub zadań, których projekt nie punktuje (details.count)
412precondition_failedIf-Match nie pasował do bieżącego ETag zasobu; details niesie expected i current
413request_too_largeciało przekracza limit rozmiaru trasy
422invalid_transitionniedozwolony ruch stanu; details niesie { from, to, allowed }
429rate_limitedzbyt wiele żądań z tego IP na trasie z limitem szybkości; nagłówek Retry-After
500internal_errorusterka serwera — komunikat ogólny; bezpieczne do ponowienia
502upstream_errorusługa, od której zależy trasa (np. GitHub), zawiodła
503not_configuredwdrożeniu brakuje integracji, której ta trasa potrzebuje (SMS, magazyn obiektów, …)

details.fields to tablica JSON nazw pól (np. ["to"]), czasem z dodatkowymi kluczami jak max. Nie ma mapy pole→komunikat.

{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }

Per IP klienta, na kilku trasach; uwierzytelniony ruch API poza nimi nie ma limitu szybkości. Wartości domyślne (każda para to stała szybkość i burst, regulowane przez operatora):

  • Auth — /api/auth/*: 0.5 req/s, burst 20.
  • Dostawca OAuth — /oauth/*: 1 req/s, burst 60.
  • Public — /api/contact: 0.2 req/s, burst 10.
  • Feedback — /api/v1/feedback i /api/v1/feedback/with-screenshot: trzy nałożone poziomy — jedno zgłoszenie na 15 s, 10 na godzinę, 36 na dobę.
  • Awatary — nieuwierzytelnione przekierowanie awatara: 20 req/s, burst 200.
  • Sensitive — POST kopii zapasowych i przywracania: ~0.002 req/s, burst 5.

Przekroczony limit zwraca 429 z nagłówkiem Retry-After i standardową kopertą błędu JSON, code: "rate_limited".