Skip to content

Espesipikasyon ng API

Ang kumpletong sanggunian ng REST endpoint. Para sa mga tutorial at halimbawa, tingnan ang Gabay sa API.

Lahat ng kayang gawin ng isang miyembro ng proyekto sa web UI ay magagamit dito — ang SPA ay kumukonsumo ng parehong API na ito. Ang mga operasyong nangangailangan ng tungkuling manager ay minamarkahang (manager); lahat ng iba ay nangangailangan lamang ng membership sa proyekto (o, para sa mga read na minarkahang (viewer), anumang antas ng akses). Pinapangalanan ng mga talahanayan sa ibaba ang bawat grupo ng route na ini-mount ng server; ang mga ibinubuod sa iisang linya ay buong inilalarawan sa live na openapi.json.

https://eastagiletracker.com/api/v1

Naghahatid ang https://api.eastagiletracker.com/api/v1 ng magkaparehong API. Lahat ng request at response ay JSON, maliban sa ilang file-upload endpoint na tumatanggap ng multipart.

Dalawang grupo ang nasa isang antas na mas mataas, sa ilalim ng /api sa halip na /api/v1: ang authentication surface (/api/auth/*) at ang mga pampublikong form (/api/contact, /api/feedback). Nagbabalik ng 404 ang kanilang mga anyong /api/v1/….

Bawat na-authenticate na request ay nagpapadala ng kredensyal sa pamamagitan ng isa sa:

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

Nagsisimula ang mga user key sa ea_user_, ang mga agent key sa ea_agent_, at ang mga MCP access token sa ea_mcp_. Tingnan ang Gabay sa API → Tatlong uri ng kredensyal.

Mga endpoint na walang authentication: /openapi.json, /docs, ang mga endpoint na /api/auth/*, at ang mga reference-data na lookup (/story_types, /story_states, /effort_scales, /priority_scales). Ang /meta ay authenticated — gumagana ang anumang wastong key, ngunit hindi ito scoped-sa-proyekto (naaabot din ito ng project-bound na agent key).

Apat na antas ang nagkokontrol sa mga endpoint na scoped-sa-proyekto:

AntasSino ang pumapasaKaraniwang mga operasyon
public viewersinuman, sa isang proyektong pampubliko ang visibilitymga read ng board: stories, iterations, search, aktibidad ng story at epic (na naka-redact ang mga detalye ng aktor)
viewerviewer, member, managermga read (list/get stories, search, metrics, listahan ng export format)
membermember, managerlahat ng write ng work-item (stories, tasks, comments, …), ang event stream
managermanager lamangmga setting ng proyekto, pamamahala ng membership, agent keys, delete, import, pag-download ng export, backups, audit log

Hawak ng mga agent ang parehong mga tungkulin gaya ng mga miyembro — viewer, member, o manager — na nililimitahan sa tungkulin ng miyembrong nag-mint ng key. Ang isang hindi-miyembro ay tumatanggap ng 404 unfound_resource (hindi 403) sa mga path ng pribadong proyekto, kaya hindi maiisa-isa ang mga project ID.

MethodPathPaglalarawan
GET/openapi.jsonAng buháy na OpenAPI 3 spec, kasama ang mga request body. Walang authentication.
GET/docsSwagger UI. Walang authentication.
GET/metaIdentidad ng caller (auth.kind/key_id/agent_id/project_id) + ang story-type transition graph. Authenticated (anumang wastong key; hindi scoped-sa-proyekto). Tawagin ito muna.
GET/api/health · /api/configLiveness, at ang pampublikong configuration ng deployment (single-org mode, kung aling mga opsyonal na feature ang naka-on, pangalan ng instance). Walang authentication, nasa labas ng /v1.

Mga session endpoint, walang authentication maliban kung nakasaad. Ang SPA ang nagpapatakbo ng mga ito; karaniwang API key ang ginagamit ng mga script sa halip.

MethodPathPaglalarawan
POST/auth/registerMagrehistro ng bagong account — binabantayan ng reCAPTCHA; pagkatapos ay dumadaan ang account sa SMS challenge
POST/auth/sms/challenge · /auth/sms/status · /auth/sms/bypassIpadala / suriin ang SMS code ng sign-up (kontrolado ng operator ang bypass)
GET/auth/configKung aling mga paraan ng pag-sign in ang inaalok ng deployment
POST/auth/loginMag-sign in gamit ang email + password; nagbabalik ng session JWT, o isang TOTP challenge
POST/auth/login/totpTapusin ang pag-sign in gamit ang authenticator code o recovery code
POST/auth/passkey/login/start · /auth/passkey/login/finishPasswordless na WebAuthn sign-in
GET/auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchangeOAuth sign-in gamit ang GitHub o Google
POST/auth/refresh · /auth/refresh/revokeI-rotate ang refresh token / bawiin ito
POST/auth/logoutMag-sign out (binabawi ang refresh token)
POST/auth/forgot-password · /auth/reset-passwordHumiling ng reset na email / gamitin ang reset token
POST/auth/accept-invite/lookup · /auth/accept-inviteLutasin ang invitation token → email / tanggapin ang imbitasyon sa proyekto (pagkatapos mag-authenticate)

Ang mga ito ay kumikilos sa caller at nangangailangan lamang ng wastong key (walang tungkulin sa proyekto).

MethodPathPaglalarawan
GET/meProfile ng kasalukuyang user
PUT/meI-update ang profile
DELETE/meI-delete ang account — tinatanggihan habang ikaw ang nag-iisang owner ng isang org o ng isang proyektong may iba pang miyembro
GET/me/deletion-impactAno ang aalisin ng pag-delete ng account at ano ang humaharang dito
PUT/me/passwordBaguhin ang password
PUT/me/settingsI-update ang mga setting (theme, mga kagustuhan sa abiso)
POST/me/avatarMag-upload ng avatar (multipart)
POST/me/api-token/regenerateIikutin ang iyong API token — pinapawalang-bisa ang umiiral na mga session/key
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}Pamahalaan ang user (ea_user_) na mga API key
GET/me/totp · POST /me/totp/setup · /me/totp/verify · /me/totp/disableEnrollment sa two-factor (TOTP); ibinabalik ng verify ang mga recovery code nang isang beses
GET/me/passkeys · POST /me/passkeys/register/start · /me/passkeys/register/finish · DELETE /me/passkeys/{credential_id}Enrollment at pag-alis ng passkey
GET/me/oauth_grants · DELETE /me/oauth_grants/{grant_id}Mga connected app — ang mga MCP client at OAuth app na pinahintulutan mo
GET/me/activityAng iyong aktibidad sa lahat ng proyekto
GET/me/storiesMga story na pag-aari mo, hiniling mo, o sinusundan mo sa bawat proyektong naaabot ng token — role=owned|requested|following, state=, cursor= / limit= (max 200)
GET/me/mentions · POST /me/mentions/{mention_id}/ackAng inbox ng @-banggit (unacked=true para mag-filter) at ang pag-acknowledge — kasama rin sa feed ng notipikasyon sa ibaba
GET/me/data-exportGDPR na self-export ng iyong datos
GET/me/consent · POST /me/consentBasahin / itala ang consent ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptMga nakabinbing clickwrap na dokumento / itala ang pagtanggap
GET / PUT/agent/meAng sariling identidad at profile ng isang agent key, nababasa at nae-edit ng agent (ang katapat sa panig-agent ng /me)
POST/api/contact · /api/feedback · /api/feedback/with-screenshotContact + in-app na feedback. Nasa labas ng /v1; may rate limit kada IP

Mga seed na lookup na ginagamit kapag lumilikha/nagtatantiya ng mga story. Mga stable na ID.

MethodPathPaglalarawan
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scalesmga magagamit na estimate scale
GET/effort_scales/{scale_id}/valuesang mga point value sa isang scale
GET/priority_scales · /priority_scales/{scale_id}/valuesang mga priority scale at ang mga halaga nito (dito nireresolba ang priority_id ng isang story)

Sa hosted na serbisyo lamang — tumatakbo sa single-organization mode ang isang self-hosted na install at hindi nito ini-mount ang mga ito (maliban sa listahan ng org). Mga tungkulin sa org ang mga tungkulin: owner, admin, member.

MethodPathPaglalarawan
GET / POST/organizationsIlista ang iyong mga organisasyon / gumawa ng isa
GET / PUT / DELETE/organizations/{oid}Basahin, palitan ang pangalan (pangalan + slug; owner o admin), i-delete
GET / POST/organizations/{oid}/memberships · PUT / DELETE …/memberships/{member_id}Mga miyembro at imbitasyon; may role ceiling ang mga imbitasyon (hindi kailanman lampas sa caller; hindi kailanman iniimbitahan ang owner)
POST/organizations/{oid}/memberships/bulk-role · …/memberships/bulk-removeBaguhin ang role ng hanggang 200 miyembro o alisin sila nang sabay-sabay. Lahat o wala: tinatanggihan ang buong batch kung aalisin nito ang huling owner o iiwan ang isang project nang walang may-ari; sa reassign_confirmed ay ikaw ang magiging may-ari ng mga project na iyon
DELETE/organizations/{oid}/invitations/{invitation_id}Bawiin ang isang nakabinbing imbitasyon
POST/organizations/{oid}/transfer-ownershipIpasa ang tungkuling owner sa ibang miyembro
PUT/organizations/{oid}/memberships/{member_id}/anonymizationItago ang pangalan / email / avatar ng isang miyembro sa buong org
GET/organization-invitations/{token} · POST …/{token}/acceptLutasin / tanggapin ang isang imbitasyon sa org na ipinadala sa email
POST/organizations/{oid}/export · GET / POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/downloadOwner-only na export ng org: isang zip na may SQL dump at bawat attachment, pinapatakbo bilang isang job
MethodPathPaglalarawan
GET/projectsIlista ang iyong mga proyekto (limit ≤ 200)
POST/projectsGumawa ng proyekto
GET/projects/{id}Kunin ang mga detalye ng proyekto (viewer)
PUT/projects/{id}I-update ang mga setting ng proyekto (manager)
DELETE/projects/{id}Mag-delete ng proyekto (manager)
POST/projects/{id}/pinI-pin / i-unpin ang proyekto sa iyong listahan ng proyekto
POST/projects/{id}/transfer-organizationIlipat ang proyekto sa ibang organisasyon (manager)
POST/projects/{id}/slack/testMagpadala ng test message sa Slack feed ng proyekto (manager)
GET / POST/projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seedMga pampublikong showcase project: suriin kung maaari mong i-claim ang isa, i-claim ito, i-seed ito
GET/projects/{id}/audit-logPagbasa ng audit log — project history kasama ang per-story / per-epic na aktibidad sa pamamagitan ng surface=; nag-iiba ang access ayon sa surface, tingnan sa ibaba
GET/projects/{id}/eventsCursor-paginated na event stream (member) — tingnan ang Events

Mga query parameter ng audit log: event_type= (isang uri o comma-separated na listahan), limit= (≤ 1000), before= (keyset cursor, ISO-8601 created_at), surface= (project_history, story_activities, epic_activities), target_id= (ang id ng story/epic — kailangan kapag surface=story_activities o epic_activities). Access: ang hindi na-filter na log at surface=project_history ay (manager); ang story_activities / epic_activities ay mababasa ng sinumang miyembro ng proyekto, at anonymous sa mga pampublikong proyekto na may na-redact na PII ng actor.

MethodPathPaglalarawan
GET/projects/{id}/membershipsIlista ang mga miyembro (viewer)
POST/projects/{id}/membershipsMag-imbita ng miyembro sa pamamagitan ng email (manager)
PUT/projects/{id}/memberships/{mid}I-update ang tungkulin (manager)
DELETE/projects/{id}/memberships/{mid}Mag-alis ng miyembro (manager)
GET/projects/{id}/addable-members · POST /projects/{id}/members/add-existingMga miyembro ng org na wala pa sa proyekto / magdagdag ng isa nang walang email na imbitasyon (manager)
POST/projects/{id}/members/joinSumasali ang isang owner o admin ng org sa isang proyekto sa kanilang org bilang manager, o ipino-promote ang sarili bilang isa (ang aksyong Make me owner sa listahan ng proyekto)
PUT/projects/{id}/members/{mid}/anonymizationItago ang pangalan / email / avatar ng isang miyembro sa proyektong ito (manager)
GET / POST/projects/{id}/agent_keysIlista / mag-mint ng mga agent key — mga manager, o ang mga tungkuling pinapapasok ng creator-roles policy ng proyekto
DELETE/projects/{id}/agent_keys/{kid}Magbawi ng agent key
GET/projects/{id}/agent_keys/onboardingAng onboarding bundle: mga prompt at config file para sa mga karaniwang agent client
GET/projects/{id}/agents · GET / PUT /projects/{id}/agents/{aid}Ang mga agent ng proyekto at ang kanilang mga profile (pangalan, initial, paglalarawan, kulay)
POST/projects/{id}/agents/{aid}/rotate-key · /projects/{id}/agents/{aid}/avatarI-rotate ang key ng isang agent (pinananatili ang identidad at kasaysayan) / i-upload ang avatar nito

Lahat ng story write ay nangangailangan ng tungkuling member.

MethodPathPaglalarawan
GET/projects/{id}/storiesIlista ang mga story (paginated, mafi-filter) (viewer)
POST/projects/{id}/storiesGumawa ng story
GET/projects/{id}/stories/{sid}Kunin ang isang story (viewer)
PUT/projects/{id}/stories/{sid}I-update ang isang story
DELETE/projects/{id}/stories/{sid}Mag-delete ng story
POST/projects/{id}/stories/{sid}/transitionsBaguhin ang estado nang may validation
POST/projects/{id}/stories/{sid}/reject · /projects/{id}/stories/{sid}/restartTanggihan ang isang delivered na story / ibalik sa started ang isang tinanggihan (terminal ang rejected para sa /transitions)
POST/projects/{id}/stories/{sid}/archive · /projects/{id}/stories/{sid}/unarchiveI-archive / i-unarchive ang isang story
POST/projects/{id}/stories/bulk_transitionI-transition ang maraming story (1–100) nang sabay-sabay
POST/projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-moveI-archive, i-delete, i-duplicate, o ilipat (sa isang panel / posisyon) ang maraming story
POST/projects/{id}/stories/{sid}/duplicateI-duplicate ang isang story
GET / POST / DELETE/projects/{id}/stories/{sid}/epics · …/epics/{eid}Ang pagiging kasapi ng story sa mga epic
GET/short-links/{code} · /story-referencesLutasin ang isang /s/<code> na short link sa story nito / lutasin ang hanggang 100 story reference (#id, mga URL) sa mga story na nababasa ng caller

Mga query parameter ng listahan ng story: archived= (exclude bilang default / include / only — ang tatlong-estadong filter ng naka-archive; pumapalit sa deprecated na include_archived=true, na alias na ngayon ng archived=include), include_done=true (isinasama ang mga story ng Done panel na naka-freeze sa mga nakaraang iteration, hindi kasama bilang default). Sumusunod ang pagination (cursor= / limit= / offset=) at ang mga sparse fieldset (fields=) sa Pagination at Field projection.

Create (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. Ang estimate ay ang label ng halaga sa scale bilang isang string ("3", "13"); tinatanggihan ang isang JSON number. Tinatanggap ng labels ang ["auth"] o [{ "name": "auth" }]; nililikha ang hindi kilalang mga label. Mga default: story_type=feature, current_state=unstarted.

Update (PUT …/stories/{sid}): parehong mga field, lahat opsyonal, kasama ang "position" (float), "force_state_change" (bool), at "expected_updated_at" (RFC 3339 — tinatanggihan ang pag-save ng paglalarawan nang may 409 stale_write kung nagbago ang story mula nang basahin mo ito). Iginagalang din ng mga story write ang If-Match laban sa ETag ng story; ang hindi pagtugma ay 412 precondition_failed.

Transition (POST …/transitions): { "to": "<state>" }. Ang field ay to. Nagbabalik ng { story_id, state }. Ilegal na galaw → 422 invalid_transition na may details: { from, to, allowed }.

Bulk transition (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>" }. Bawat story ay hinuhusgahan nang nag-iisa; nagbabalik ng { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

Lahat ay member. Ang List/GET sa karamihan ay (viewer).

MethodPathBody / mga tala
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) } o { comment_emoji }. Tumatanggap ang GET ng fields= (allowlist: comment_id, story_comment_id, story_id, comment_text, comment_emoji, member, created) pati ng 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}{ url, link_type?, title? } — ang link_typerelates_to, duplicates, blocks, is_blocked_by, pull_request, branch, other; awtomatikong nabibigyan ng uri ang mga GitHub /pull/ at /tree/ na URL
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}Create: { reviewer_id? / reviewer_agent_id?, comment? } — alisin pareho upang italaga ang sarili mo. Update: { status, comment? }
GET / POST/projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid}{ member_id? / agent_id? } — alisin pareho upang idagdag ang caller
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 upload — video ≤ 200 MB, PDF / Word / Excel ≤ 25 MB, mga larawan / CSV / teksto ≤ 10 MB; ang list ay (viewer)
GET / POST/projects/{id}/stories/{sid}/link-attachments · DELETE …/link-attachments/{laid}Mga link attachment — isang panlabas na URL na itinatago kasama ng mga file attachment sa halip na bilang code link
GET/attachments/{token} · /api/avatars/{token}Mga token-addressed na read ng isang attachment o avatar — ang mga URL na ibinibigay ng API; hindi kailangan ng X-TrackerToken

Parehong hugis gaya ng mga story, bawas ang state machine. member para sa mga write, (viewer) para sa mga read.

MethodPathPaglalarawan
GET / POST/projects/{id}/epics · GET / PUT / DELETE …/epics/{eid}May dalang pangalan, Markdown na paglalarawan, at isang backing label na nag-uugnay sa kanilang mga story ang mga epic
GET / POST / PUT / DELETE…/epics/{eid}/comments · …/comments/{cid}Mga comment ng epic
GET / POST / DELETE…/epics/{eid}/owners · …/followers (+ mga variant na /agents/{aid})Mga owner at follower, miyembro man o agent — naipapasa sa mga story nito ang mga owner ng isang epic
GET / POST / DELETE…/epics/{eid}/attachments (+ /json) · …/link-attachmentsMga attachment, parehong mga limitasyon gaya ng mga story
GET/projects/{id}/analytics/epics · …/analytics/epics/{eid}Progreso kada epic: burnup, throughput, kalusugan, forecast (viewer)

member para sa mga write, (viewer) para sa mga read.

MethodPathPaglalarawan
GET / POST/projects/{id}/labelsIlista / lumikha ng label
PUT / DELETE/projects/{id}/labels/{lid}I-update / i-delete ang label
POST/projects/{id}/labels/{lid}/archiveI-archive (soft-hide) ang label

Bukas ang mga read sa anumang tungkulin sa proyekto, at anonymous sa isang pampublikong proyekto.

MethodPathPaglalarawan
GET/projects/{id}/iterationsIlista ang mga iteration (≤ 500 kada pahina; may dalang ETag at ang mga continuation header na X-Tracker-Pagination-* kapag naputol)
GET/projects/{id}/iterations/{itid}Isang iteration
GET/projects/{id}/iterations/first-previewAng mga petsang makukuha ng unang iteration, ipinapakita sa kumpirmasyon ng pag-seed
POST/projects/{id}/iterationsGumawa ng manu-manong iteration (member)
DELETE/projects/{id}/iterations/{itid}Mag-delete ng iteration (manager)
PUT/projects/{id}/iterations/{itid}/velocityI-override ang velocity ng isang iteration nang hindi binabago ang strategy ng proyekto (manager)
GET/projects/{id}/iterations/{itid}/done-storiesAng mga tinanggap na story ng isang saradong iteration, paginated
MethodPathPaglalarawan
GET/projects/{id}/search?q=…Makapangyarihang paghahanap — full-text + mga facet / date-range / people qualifier (DSL na istilong GitHub); nagbabalik ng { results, total, limit, offset }. Alias ng q ang query; nagpa-paginate ang limit= (default 50, max 1000) / offset=; nag-aayos ang sort= ayon sa relevance (default), created, created_asc, state, o updated. (viewer) — tingnan ang Gabay
GET/projects/{id}/metrics/{velocity,burndown,story-types,contributors}Ang mga serye ng Metrics page (viewer); nasa ilalim ng /analytics/epics sa itaas ang mga metric ng epic
GET/projects/{id}/backlog/groupingAng mga ipinoproyektong grupo ng iteration ng Backlog (viewer)
GET / PUT/projects/{id}/preferencesAng iyong mga kagustuhan sa board para sa proyektong ito — anumang tungkulin sa proyekto, sarili mong hilera lamang
MethodPathPaglalarawan
GET/projects/{id}/eventsCursor-paginated na event stream (member) — nakakakuha ng 403 ang mga viewer

Mga query parameter: since=<event_id>, types=story.created,story.transitioned,comment.added,…, limit= (≤ 500), cursor=. Kasama sa tugon ang next_cursor. Ipasa ang huling event_id na nakita mo bilang since upang magpatuloy.

Ang pinag-isang in-app na feed ng notipikasyon: mga first-class na hilera ng notipikasyon (mga hiling ng review, aktibidad ng story, mga imbitasyon, …) na pinagsama sa inbox ng @-banggit sa iisang stream, pinakabago muna. May prefix ng pinagmulan ang mga id ng feed (nt-… / sc-… / ec-…). Binabasa ng mga session ng miyembro at ng mga key na ea_user_* ang kanilang mga hilerang panig-miyembro; ng mga key na ea_agent_* ang kanilang mga hilerang panig-agent.

MethodPathPaglalarawan
GET/me/notificationsAng iyong feed ng notipikasyon. Mga filter: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); mag-page gamit ang cursor= / limit=
GET/me/notifications/unread-countKabuuang hindi pa nababasa — { unread_count, by_category: { mentions, reviews, stories, invitations } }
POST/me/notifications/read-allMarkahan lahat bilang nabasa; ibinabalik ang mga sariwang bilang
POST/me/notifications/{id}/ackMarkahan ang isang item bilang nabasa (idempotent)
POST/me/notifications/{id}/acceptTanggapin ang imbitasyon sa proyekto / organisasyon mula mismo sa feed (mga token ng miyembro lamang)
POST/me/notifications/{id}/declineTanggihan ang imbitasyon sa proyekto / organisasyon (mga token ng miyembro lamang)
GET/me/notifications/resolve-invite?token=…Itugma ang token ng imbitasyong ipinadala sa email sa id ng iyong notipikasyon — { "id": "nt-…" } o { "id": null }
GET/me/notifications/streamLive na push — Server-Sent Events (text/event-stream); tingnan sa ibaba

Ang stream endpoint ay hindi JSON endpoint kaya wala ito sa OpenAPI spec: pinananatili nitong bukas ang koneksyon at naglalabas ng frame na walang payload ({"type":"notification","kind":…}) tuwing may bagong dumarating, bilang hudyat sa client na kunin muli ang feed. Pinuputol ang mga koneksyon sa panig ng server pagkatapos ng 45 minuto — muling kumonekta at muling mag-authenticate. Mga session ng miyembro at mga key na ea_user_* lamang; tumatanggap ng 403 ang mga key na ea_agent_*.

MethodPathPaglalarawan
POST/projects/{id}/importMga file na pinagmulan: source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. Multipart file=. Synchronous — sumasagot gamit ang mga bilang ng resulta.
POST/projects/{id}/import/jsonJSON body; hindi kailangan ng file ng source=githubowner, repo, opsyonal na token, at ang mga opt-in na flag na include_pull_requests / include_milestones / include_releases / include_dependencies; nagpapadala ng file_base64 ang mga file na pinagmulan. Asynchronous: nagbabalik ng 202 { import_id, status }. Kumukuha ang server sa pamamagitan ng GraphQL API ng GitHub, na tumatanggi sa mga anonymous na tumatawag, kaya laging may token na nakakarating sa GitHub — ang sa iyo, o ang shared na token ng deployment. Tingnan ang Gabay.
GET/projects/{id}/imports/{import_id}I-poll ang isang job: dumadaan ang status sa pending → fetching → writing → done | failed, na may progress_current / progress_total habang kumukuha at ang mga bilang ng resulta sa done

Iisang import ang tumatakbo kada proyekto sa isang pagkakataon; ang ikalawang POST habang may tumatakbo pa ay 409 import_already_running. Ini-preview ng dry_run: true (JSON body o dry_run=true multipart) ang anumang pinagmulan: ipina-parse, nireresolba, ide-de-dupe, naglalabas ng parehong mga bilang na { imported, skipped, errors, unmatched }, pagkatapos ay ibinabalik sa dati — walang isinusulat. Mga hangganan: 10 MiB na body, at 5,000 story kada import para sa mga pinagmulang nakabatay sa file (lampas sa alinman → 400, walang isinusulat). Walang hangganan ang pinagmulang GitHub — nagko-commit ito nang tipak-tipak sa halip na sa iisang transaksyon. Idempotent ang muling pag-import kada source id — ang mga hilerang na-import na ay nilalaktawan, hindi ni-doble.

MethodPathPaglalarawan
GET/projects/{id}/export/formatsMga nakarehistrong format: { id, name, content_type, drops, includes_archived }. Anumang tungkulin sa proyekto.
GET/projects/{id}/export/{format}Mag-download ng isa (manager). Interchange: eat (buong katapatan), jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json; mga dokumento: pdf, docx.
GET/projects/{id}/export/attachmentsBawat attachment bilang isang browsable na zip (pinapanatili ng mga file ang orihinal na pangalan; JSON + CSV na manifest) (manager).

Ang mga document export (pdf, docx) ay tumatanggap ng karagdagang query parameter: page_size= (letter bilang default / a4 / legal / folio), from= / to= (mga hangganan ng story window — RFC 3339 o payak na YYYY-MM-DD; nasa saklaw ang story kapag pumapasok dito ang created o completed_at nito), include_icebox= / include_backlog= (parehong false bilang default, kaya ipinapakita lang ng naibabahaging export ang naka-iskedyul / kasalukuyang ginagawang trabaho). Binabalewala ang mga ito ng mga interchange na CSV format.

MethodPathPaglalarawan
GET / POST/projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/healthIlista ang mga snapshot, kumuha ng isa ngayon, basahin ang isa, at ang buod ng kalusugan ng retention
GET / POST/projects/{id}/restores · POST …/restores/partial · GET …/restores/{restore_id}I-restore ang isang buong snapshot, o mga piling table mula rito, at i-poll ang restore

Nasa sensitive na rate-limit tier (sa ibaba) ang mga POST.

Ang East Agile Tracker ay isang OAuth 2.1 provider para sa mga MCP client. Natutuklasan ito ng isang client sa /.well-known/oauth-authorization-server at /.well-known/oauth-protected-resource/mcp, ipinapadala ka sa /oauth/authorize (ang consent page), ipinapalit ang code sa /oauth/token, at pagkatapos ay nagsasalita ng MCP sa /mcp gamit ang nakuhang ea_mcp_* token. Inililista at binabawi ang mga grant sa /me/oauth_grants. May sariling rate-limit tier ang mga provider endpoint.

wss://eastagiletracker.com/ws/control?token=<session JWT>

Para sa interaktibong UI remote-control ({ "action": "get_state", "id": "req-1" }). Ang token ay isang browser session JWT — tinatanggihan ang isang API key nang may 401 bago ang upgrade. Hindi isang data channel — lahat ng read/write ay dumadaan sa REST. Single-instance lamang; hindi naka-fan-out sa mga replica.

Tinatanggap ng mga write endpoint (POST, PUT, DELETE) ang header na Idempotency-Key. Parehong key + parehong body ay nag-rereplay ng naka-cache na tugon (24-oras na window); parehong key + isang kaibang body ay nagbabalik ng 409 idempotency_conflict. Saklaw ang key ng kredensyal na nagpadala nito. Hindi inilalapat sa GET/HEAD/OPTIONS, /openapi.json at /docs, /api/auth/*, o mga multipart upload sa mga path na /attachments. Hindi kailanman naka-cache ang mga tugong huminto bago ang sagot ng domain — 401, 403, 404, 429, at bawat 5xx — kaya naaabot ng isang retry pagkatapos ng alinman sa mga ito ang handler; ang 400, 409, 412, at 422 ay sagot ng domain at nire-replay gaya ng isang tagumpay.

Tinatanggap ng mga list endpoint ang cursor=<opaque> at limit=<n>. Kapag itinakda, ang tugon ay { "items": [...], "next_cursor": "<str|null>" }; ipasa pabalik ang next_cursor upang mag-page. Nag-iiba kada endpoint ang hangganan ng limit: 200 sa mga story, comment, at proyekto; 500 sa mga event; 1000 sa search at sa audit log.

Ang isang karaniwang listahan (walang cursor/limit) na kinailangang putulin ang tugon nito ay nagsasabi nito sa mga header — X-Tracker-Pagination-Truncated, X-Tracker-Pagination-Limit, X-Tracker-Pagination-Offset, at X-Tracker-Pagination-Next-Offset; ipasa pabalik ang huli bilang offset= para sa susunod na pahina. Walang header ng kabuuang bilang.

Tinatanggap ng mga list endpoint ang fields= (comma-separated) upang magbalik lamang ng mga tiyak na field. Palaging kasama ang story_id; ang hindi kilalang pangalan ng field ay nagbabalik ng 400 validation_failed na may mga nagkakasalang pangalan sa details.fields.

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

Bawat JSON na error ay may code at error; ang ilan ay nagdaragdag ng details:

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
StatuscodeKailan
400invalid_parametermasamang input; mensahe sa error, walang details (karamihan sa validation: blank/length/null-byte/email)
400validation_failedstructured na input error; ang details.fields ay isang array ng mga nagkakasalang pangalan ng field
401unauthenticatednawawala/imbalidong token
403unauthorized_operationna-authenticate ngunit hindi sapat na tungkulin
404unfound_resourcehindi nahanap — ibinabalik din sa mga hindi-miyembro
409conflictsalungatan sa rekurso (hal. duplicate)
409idempotency_conflictIdempotency-Key na muling ginamit na may kaibang body
409stale_write · import_already_runningnagbago ang story mula sa iyong expected_updated_at · may import nang tumatakbo
412precondition_failedhindi tumugma ang If-Match sa kasalukuyang ETag ng rekurso; dala ng details ang expected at current
413request_too_largelumampas ang body sa size limit ng route
422invalid_transitionilegal na galaw ng estado; dala ng details ang { from, to, allowed }
429rate_limitedmasyadong maraming request mula sa IP na ito sa isang route na may rate limit; header na Retry-After
500internal_errorpagkakamali ng server — generic na mensahe; ligtas ulitin
503not_configuredwala sa deployment ang integration na kailangan ng route na ito (SMS, object storage, …)

Ang details.fields ay isang JSON na array ng mga pangalan ng field (hal. ["to"]), kung minsan ay may dagdag na mga key tulad ng max. Walang field→message na mapa.

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

Kada client IP, sa ilang route lamang; walang rate limit ang authenticated na API traffic sa ibang lugar. Mga default (bawat pares ay sustained rate at burst, naaayos ng operator):

  • Auth/api/auth/*: 0.5 req/s, burst 20.
  • OAuth provider/oauth/*: 1 req/s, burst 60.
  • Public/api/contact: 0.2 req/s, burst 10.
  • Feedback/api/feedback: tatlong magkapatong na tier — isang submit kada 15 s, 10 kada oras, 36 kada araw.
  • Avatars — ang unauthenticated na avatar redirect: 20 req/s, burst 200.
  • Sensitive — ang mga backup at restore na POST: ~0.002 req/s, burst 5.

Ang isang nalampasang limit ay nagbabalik ng 429 na may header na Retry-After at ang karaniwang JSON na error envelope, code: "rate_limited".