Przejdź do głównej zawartości

Specyfikacja API

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 owner są oznaczone (owner); wszystko inne wymaga jedynie członkostwa w projekcie (lub, dla odczytów oznaczonych (viewer), dowolnego poziomu dostępu).

https://eastagiletracker.com/api/v1

https://api.eastagiletracker.com/api/v1 serwuje identyczne API. Wszystkie żądania i odpowiedzi są w JSON, z wyjątkiem kilku endpointów przesyłania plików, które akceptują multipart.

Każde uwierzytelnione żądanie wysyła klucz API za pomocą jednego z:

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

Klucze użytkownika zaczynają się od ea_user_. Klucze agentów zaczynają się od ea_agent_. Zobacz Przewodnik po API → Dwa rodzaje kluczy.

Endpointy nieuwierzytelnione: /openapi.json, /docs, endpointy /auth/* oraz lookupy danych referencyjnych (/story_types, /story_states, /effort_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).

Trzy poziomy bramkują endpointy o zasięgu projektu:

PoziomKto przechodziTypowe operacje
viewerviewer, member, ownerodczyty (listowanie/pobieranie historii, wyszukiwanie, analityka)
membermember, ownerwszystkie zapisy elementów pracy (historie, zadania, komentarze, …)
ownertylko ownerustawienia projektu, zarządzanie członkostwem, klucze agentów, usuwanie, import, dziennik audytu

Osoba niebędąca członkiem otrzymuje 404 unfound_resource (a nie 403) na ścieżkach projektu, więc identyfikatory projektów nie są wyliczalne.

MetodaŚcieżkaOpis
GET/openapi.jsonŻywa specyfikacja OpenAPI 3. 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.

Te operują na wywołującym i wymagają jedynie prawidłowego klucza (bez roli projektowej).

MetodaŚcieżkaOpis
POST/auth/registerZarejestruj nowe konto
POST/auth/loginZaloguj się, zwraca token sesji
POST/auth/logoutWyloguj się
POST/auth/forgot-passwordPoproś o e-mail resetujący hasło
POST/auth/reset-passwordUżyj tokenu resetującego, aby ustawić nowe hasło
GET/auth/verify-emailZweryfikuj adres e-mail
POST/auth/accept-invite/lookupRozwiąż token zaproszenia → e-mail (nieuwierzytelnione)
POST/auth/accept-inviteZaakceptuj zaproszenie do projektu (po uwierzytelnieniu)
GET/meProfil bieżącego użytkownika
PUT/meZaktualizuj profil
DELETE/meUsuń konto
PUT/me/passwordZmień hasło
PUT/me/settingsZaktualizuj ustawienia (motyw, preferencje powiadomień)
POST/me/avatarPrześlij awatar (multipart)
POST/me/api-token/regenerateZrotuj swój token API — unieważnia istniejące sesje/klucze
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}Zarządzaj kluczami API użytkownika (ea_user_)
GET/me/activityTwoja aktywność we wszystkich projektach
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
POST/contact · POST /feedback · POST /feedback/with-screenshotKontakt + opinia w aplikacji

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
MetodaŚcieżkaOpis
GET/projectsWylistuj swoje projekty
POST/projectsUtwórz projekt
GET/projects/{id}Pobierz szczegóły projektu (viewer)
PUT/projects/{id}Zaktualizuj ustawienia projektu (owner)
DELETE/projects/{id}Usuń projekt (owner)
GET/projects/{id}/audit-logStrumień aktywności projektu (owner)
GET/projects/{id}/eventsStrumień zdarzeń stronicowany kursorem (viewer) — zobacz Zdarzenia
MetodaŚcieżkaOpis
GET/projects/{id}/membershipsWylistuj członków (viewer)
POST/projects/{id}/membershipsZaproś członka przez e-mail (owner)
PUT/projects/{id}/memberships/{mid}Zaktualizuj rolę (owner)
DELETE/projects/{id}/memberships/{mid}Usuń członka (owner)
GET / POST/projects/{id}/agent_keysWylistuj / wybij klucze agentów (owner)
DELETE/projects/{id}/agent_keys/{kid}Odbierz klucz agenta (owner)

Wszystkie zapisy historii wymagają roli member.

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/bulk_transitionPrzejdź wieloma historiami (1–100) naraz
POST/projects/{id}/stories/bulk-deleteUsuń wiele historii
POST/projects/{id}/stories/bulk-duplicateZduplikuj wiele historii
POST/projects/{id}/stories/{sid}/duplicateZduplikuj jedną historię

Tworzenie (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. 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) i "force_state_change" (bool).

Przejście (POST …/transitions): { "to": "<state>", "reason"? }. 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>", "reason"? }. 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).

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 / 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? } — 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}{ name }
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}przesyłanie multipart (≤ 2 GB każdy); listowanie to (viewer)

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

MetodaŚcieżkaOpis
GET / POST/projects/{id}/labelsWylistuj / utwórz etykietę
PUT / DELETE/projects/{id}/labels/{lid}Zaktualizuj / usuń etykietę
POST/projects/{id}/labels/{lid}/archiveZarchiwizuj (miękko ukryj) etykietę
MetodaŚcieżkaOpis
GET/projects/{id}/iterationsWylistuj iteracje (member)
POST/projects/{id}/iterationsUtwórz ręczną iterację (owner)
DELETE/projects/{id}/iterations/{itid}Usuń iterację (owner)
MetodaŚcieżkaOpis
GET/projects/{id}/search?query=…Wyszukiwanie składnią filtrów (viewer) — zobacz Przewodnik
GET/projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections}Analityka (viewer). Szczegółowa analiza iteracji przyjmuje ?iteration_id=
GET/projects/{id}/metrics/{velocity,burndown,story-types}Metryki (viewer)
GET / PUT/projects/{id}/preferencesTwoje preferencje tablicy dla tego projektu (member)
MetodaŚcieżkaOpis
GET/projects/{id}/eventsStrumień zdarzeń stronicowany kursorem (viewer)

Parametry zapytania: since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. Odpowiedź zawiera next_cursor. Przekaż ostatni widziany event_id jako since, aby wznowić.

MetodaŚcieżkaOpis
POST/projects/{id}/import (+ /json)Przesyłanie multipart. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
wss://eastagiletracker.com/ws/control?token=<key>

Do interaktywnego zdalnego sterowania interfejsem ({ "action": "get_state", "id": "req-1" }). Nie jest kanałem danych — wszystkie odczyty/zapisy idą przez REST. Tylko pojedyncza instancja; nierozprowadzane między replikami.

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. Nie stosowane do GET/HEAD/OPTIONS, /auth/* ani ścieżek /attachments. Odpowiedzi 5xx nigdy nie są buforowane — ponowienie dociera do handlera.

Endpointy listujące akceptują cursor=<opaque> i limit=<n≤200>. Gdy ustawione, odpowiedź to { "items": [...], "next_cursor": "<str|null>" }; przekaż next_cursor z powrotem, aby stronicować. Niektóre listy zwracają też nagłówek X-Tracker-Pagination-Total.

Endpointy listujące akceptują fields= (rozdzielone przecinkami), aby zwrócić tylko określone pola. story_id jest zawsze dołączane; 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, bez details (większość walidacji: puste/długość/bajt null/e-mail)
400validation_failedstrukturyzowany błąd wejścia; details.fields to tablica nazw wadliwych pól
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
422invalid_transitionniedozwolony ruch stanu; details niesie { from, to, allowed }
500internal_errorusterka serwera — komunikat ogólny; bezpieczne do ponowienia

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 klucz (per IP dla endpointów nieuwierzytelnionych), kubełek tokenów GCRA:

  • Auth/auth/*: 0.5 req/s, burst 20.
  • Public/contact, /feedback: 0.2 req/s, burst 10.
  • Sensitive — resetowanie hasła: ~0.002 req/s, burst 5.

Przekroczony limit zwraca 429 Too Many Requests z nagłówkiem Retry-After oraz ciałem w postaci tekstowej (a nie kopertą błędu JSON).