Lewati ke konten

Spesifikasi API

Referensi lengkap endpoint REST API East Agile Tracker: autentikasi dan peran, proyek, story, epic, iterasi, event, impor, dan ekspor.

Referensi endpoint REST lengkap. Untuk tutorial dan contoh, lihat Panduan API.

Segala sesuatu yang dapat dilakukan member proyek di UI web tersedia di sini — SPA mengonsumsi API yang sama ini. Operasi yang memerlukan peran manager ditandai (manager); selebihnya hanya membutuhkan keanggotaan proyek (atau, untuk pembacaan yang ditandai (viewer), tingkat akses apa pun). Tabel-tabel di bawah menyebutkan setiap grup route yang dipasang server; grup yang diringkas dalam satu baris dijelaskan lengkap di openapi.json langsung.

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

API memiliki host-nya sendiri: eastagiletracker.com menyajikan aplikasi web dan menjawab /api/v1/… dengan 404. Semua request dan respons berupa JSON, kecuali beberapa endpoint unggah-file yang menerima multipart.

Dua grup berada satu tingkat di atasnya, di bawah /api alih-alih /api/v1: permukaan autentikasi (/api/auth/*) dan formulir kontak publik (/api/contact). Ejaan /api/v1/… mereka mengembalikan 404.

Setiap request terautentikasi mengirim kredensial melalui salah satu dari:

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

Kunci pengguna dimulai dengan ea_user_, kunci agen dengan ea_agent_, dan token akses MCP dengan ea_mcp_. Lihat Panduan API → Tiga jenis kredensial.

Endpoint tidak terautentikasi: /openapi.json, /docs, endpoint /api/auth/*, dan lookup data-referensi (/story_types, /story_states, /effort_scales, /priority_scales). /meta bersifat terautentikasi — kunci valid apa pun berfungsi, tetapi tidak dicakup-proyek (kunci agen yang terikat-proyek pun menjangkaunya).

Empat tingkat menggerbangi endpoint yang dicakup-proyek:

TingkatSiapa yang lolosOperasi tipikal
public viewersiapa pun, pada proyek yang visibilitasnya publikpembacaan papan: story, iterasi, pencarian, aktivitas story dan epic (dengan detail aktor disamarkan)
viewerviewer, member, managerpembacaan (daftar/dapatkan story, pencarian, metrik, daftar format ekspor)
membermember, managersemua write work-item (story, task, komentar, …), aliran event
managerhanya managerpengaturan proyek, manajemen keanggotaan, kunci agen, hapus, impor, unduhan ekspor, cadangan, log audit

Agen memegang peran yang sama dengan anggota — viewer, member, atau manager — dibatasi pada peran anggota yang mencetak kuncinya. Non-member menerima 404 unfound_resource (bukan 403) pada path proyek privat, sehingga ID proyek tidak dapat dienumerasi.

MetodePathDeskripsi
GET/openapi.jsonSpesifikasi OpenAPI 3 langsung, termasuk request body. Tidak terautentikasi.
GET/docsSwagger UI. Tidak terautentikasi.
GET/metaIdentitas pemanggil (auth.kind/key_id/agent_id/project_id) + graf transisi tipe-story. Terautentikasi (kunci valid apa pun; tidak dicakup-proyek). Panggil ini lebih dulu.
GET/api/health · /api/configLiveness, dan konfigurasi publik deployment (mode organisasi-tunggal, fitur opsional yang aktif, nama instans). Tidak terautentikasi, di luar /v1.

Endpoint sesi, tidak terautentikasi kecuali dinyatakan lain. SPA yang menggerakkannya; skrip biasanya memakai kunci API sebagai gantinya.

MetodePathDeskripsi
POST/auth/registerDaftarkan akun baru — dijaga reCAPTCHA; akun kemudian melewati tantangan SMS
POST/auth/sms/challenge · /auth/sms/status · /auth/sms/bypassKirim / periksa kode SMS pendaftaran (bypass digerbangi operator)
GET/auth/configMetode masuk mana yang ditawarkan deployment
POST/auth/loginMasuk dengan email + kata sandi; mengembalikan JWT sesi, atau tantangan TOTP
POST/auth/login/totpSelesaikan proses masuk dengan kode autentikator atau kode pemulihan
POST/auth/passkey/login/start · /auth/passkey/login/finishMasuk WebAuthn tanpa kata sandi
GET/auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchangeMasuk OAuth dengan GitHub atau Google
POST/auth/refresh · /auth/refresh/revokeRotasi refresh token / cabut
POST/auth/logoutKeluar (terautentikasi; mencabut refresh token sesi ini)
POST/auth/forgot-password · /auth/reset-passwordMinta email reset / gunakan token reset
POST/auth/accept-invite/lookup · /auth/accept-inviteSelesaikan token undangan → email / terima undangan proyek (setelah autentikasi)
POST/auth/oauth/link/preview · …/link/confirm · /auth/oauth/merge/preview · …/merge/confirmHubungkan akun GitHub atau Google ke akun yang sudah ada, atau gabungkan dua akun
POST/auth/email_addresses/primary/preview · …/primary/confirmSelesaikan perubahan email utama dari tautan konfirmasi yang dikirim lewat email

Ini bertindak pada pemanggil dan tidak membutuhkan peran proyek. Mereka membutuhkan identitas anggota — kunci agen mendapat 401 (agen memakai /agent/me). Panggilan yang mengubah kredensial — kata sandi, TOTP, passkey, penghapusan akun, perubahan email, regenerasi token — membutuhkan sesi browser; kunci API mendapat 403.

MetodePathDeskripsi
GET/meProfil pengguna saat ini
PUT/mePerbarui profil
DELETE/meHapus akun — ditolak selama Anda satu-satunya owner sebuah organisasi atau proyek yang memiliki anggota lain
GET/me/deletion-impactApa yang akan dihapus bila akun dihapus dan apa yang menghalanginya
PUT/me/passwordUbah kata sandi
PUT/me/settingsPerbarui pengaturan (tema, preferensi notifikasi)
POST / DELETE/me/avatarUnggah (multipart) / hapus avatar Anda
POST/me/api-token/regenerateKeluarkan setiap sesi dan kembalikan token sesi baru; kunci API tidak terpengaruh
GET / POST/me/email_addresses · GET …/email_addresses/offers · PUT …/email_addresses/primaryAlamat email Anda; adopsi alamat dari penyedia yang terhubung sebagai alternatif; minta perubahan email utama (dikonfirmasi lewat email)
GET/me/oauth_identities · DELETE …/oauth_identities/{provider} · POST …/oauth_identities/{provider}/linkAkun masuk yang terhubung (GitHub, Google): daftar, putuskan, mulai penautan
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}Kelola kunci API pengguna (ea_user_)
GET/me/totp · POST /me/totp/setup · /me/totp/verify · /me/totp/disablePendaftaran dua faktor (TOTP); verify mengembalikan kode pemulihan satu kali
GET/me/passkeys · POST /me/passkeys/register/start · /me/passkeys/register/finish · DELETE /me/passkeys/{credential_id}Pendaftaran dan penghapusan passkey
GET/me/oauth_grants · DELETE /me/oauth_grants/{grant_id}Connected apps — klien MCP dan aplikasi OAuth yang telah Anda otorisasi
GET/me/activityAktivitas Anda di semua proyek
GET/me/storiesStory yang Anda miliki, minta, atau ikuti di setiap proyek yang dapat dijangkau token — role=owned|requested|following, state=, cursor= / limit= (maks 200)
GET/me/mentions · POST /me/mentions/{mention_id}/ackKotak masuk @-sebutan (unacked=true untuk memfilter) dan pengakuannya — juga dilebur ke feed notifikasi di bawah
GET/me/data-exportEkspor-mandiri GDPR atas data Anda
GET/me/consent · POST /me/consentBaca / catat persetujuan ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptDokumen clickwrap tertunda / catat penerimaan
GET / PUT/agent/meIdentitas dan profil milik kunci agen itu sendiri, dapat dibaca dan diedit oleh agen (padanan sisi-agen dari /me)
POST/api/contact · /api/v1/feedback · /api/v1/feedback/with-screenshotKontak + umpan balik dalam-aplikasi; dibatasi laju per IP

Lookup benih yang digunakan saat membuat/mengestimasi story. ID stabil.

MetodePathDeskripsi
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scalesskala estimasi yang tersedia
GET/effort_scales/{scale_id}/valuesnilai poin dalam suatu skala
GET/priority_scales · /priority_scales/{scale_id}/valuesskala prioritas dan nilainya (priority_id pada story diselesaikan di sini)

Hanya layanan yang di-host — instalasi self-hosted berjalan dalam mode organisasi-tunggal dan tidak memasang endpoint ini (kecuali daftar organisasi). Perannya adalah peran organisasi: owner, admin, member.

MetodePathDeskripsi
GET / POST/organizationsDaftar organisasi Anda / buat satu
GET / PUT / DELETE/organizations/{oid}Baca, ganti nama (nama + slug; owner atau admin), hapus
GET / POST/organizations/{oid}/memberships · PUT / DELETE …/memberships/{member_id}Anggota dan undangan; undangan membawa plafon peran (tidak pernah di atas peran pemanggil; owner tidak pernah diundang)
POST/organizations/{oid}/memberships/bulk-role · …/memberships/bulk-removeUbah peran atau keluarkan hingga 200 anggota sekaligus. Semua atau tidak sama sekali: batch yang akan mengeluarkan owner terakhir atau membuat proyek tanpa pemilik ditolak seluruhnya; dengan reassign_confirmed Anda menjadi pemilik proyek tersebut
DELETE/organizations/{oid}/invitations/{invitation_id}Cabut undangan tertunda
POST/organizations/{oid}/transfer-ownershipSerahkan peran owner ke anggota lain
GET/organization-invitations/{token} · POST …/{token}/acceptSelesaikan / terima undangan organisasi yang dikirim lewat email
GET/organizations/{oid}/export · POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/downloadEkspor organisasi khusus-owner: zip berisi dump SQL dan setiap lampiran, dijalankan sebagai job
MetodePathDeskripsi
GET/projectsDaftar proyek Anda (limit ≤ 200)
POST/projectsBuat proyek
GET/projects/{id}Dapatkan detail proyek (viewer)
PUT/projects/{id}Perbarui pengaturan proyek (manager)
DELETE/projects/{id}Hapus proyek (manager)
POST / DELETE/projects/{id}/pinSematkan / lepas sematan proyek di daftar proyek Anda
POST/projects/{id}/transfer-organizationPindahkan proyek ke organisasi lain — pemanggil harus Manajer proyek dan owner atau admin organisasi tujuan
POST/projects/{id}/slack/testKirim pesan uji ke feed Slack proyek (manager)
GET / POST/projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seedProyek showcase publik: periksa apakah Anda dapat mengklaimnya, klaim, isi datanya (pengisian data khusus admin produk; selain itu mendapat 404)
GET/projects/{id}/audit-logPembacaan audit log — riwayat proyek plus aktivitas per-story / per-epic lewat surface=; akses bervariasi menurut surface, lihat di bawah
GET/projects/{id}/eventsAliran event dengan paginasi-kursor (member) — lihat Event

Parameter query audit log: event_type= (satu tipe atau daftar dipisah koma), limit= (default 50, dibatasi hingga 1000), before= (kursor keyset <ISO-8601>|<audit_id> — kirim next_cursor dari halaman sebelumnya), surface= (project_history, story_activities, epic_activities), target_id= (id story/epic — wajib saat surface=story_activities atau epic_activities). Akses: log tanpa filter adalah (manager); surface=project_history adalah (viewer), dengan email anggota disamarkan bila proyek menyembunyikannya; story_activities / epic_activities dapat dibaca anggota proyek mana pun, dan secara anonim pada proyek publik dengan PII aktor disamarkan.

MetodePathDeskripsi
GET/projects/{id}/membershipsDaftar anggota (viewer)
POST/projects/{id}/membershipsUndang anggota lewat email (manager)
PUT/projects/{id}/memberships/{mid}Perbarui peran (manager)
DELETE/projects/{id}/memberships/{mid}Hapus anggota (manager)
POST/projects/{id}/memberships/bulk-role · …/memberships/bulk-removeUbah peran, atau keluarkan, banyak anggota sekaligus (manager)
GET/projects/{id}/addable-members · POST /projects/{id}/members/add-existingAnggota organisasi yang belum ada di proyek / tambahkan satu tanpa undangan email — (manager) dan owner atau admin organisasi
POST/projects/{id}/members/joinOwner atau admin organisasi bergabung ke proyek di organisasinya sebagai manager, atau menaikkan dirinya menjadi manager (aksi Make me owner di daftar proyek)
GET / POST/projects/{id}/agent_keysDaftar (manager) / cetak kunci agen — orang yang perannya ada dalam kebijakan creator-roles proyek; kunci agen tidak dapat mencetak
PUT / DELETE/projects/{id}/agent_keys/{kid}Ubah nama, peran, atau petunjuk respons sebuah kunci / cabut (manager)
GET/projects/{id}/agent_keys/onboardingBundel onboarding: prompt dan file konfigurasi untuk klien agen yang umum
GET/projects/{id}/agents · GET / PUT / DELETE /projects/{id}/agents/{aid}Agen-agen proyek dan profilnya (nama, inisial, deskripsi, warna); DELETE mencabut agen dan semua kuncinya — manager atau pembuat agen
POST/projects/{id}/agents/{aid}/rotate-key · /projects/{id}/agents/{aid}/avatarRotasi kunci agen (identitas dan riwayat tetap) / unggah avatarnya

Semua write story membutuhkan peran member. Membuat story dengan tanggal mundur, asal impor (import_source / import_external_id), atau owner maupun requester eksternal membutuhkan (manager).

MetodePathDeskripsi
GET/projects/{id}/storiesDaftar story (terpaginasi, dapat difilter) (viewer)
POST/projects/{id}/storiesBuat story
GET/projects/{id}/stories/{sid}Dapatkan satu story (viewer)
PUT/projects/{id}/stories/{sid}Perbarui story
DELETE/projects/{id}/stories/{sid}Hapus story
POST/projects/{id}/stories/{sid}/transitionsUbah status dengan validasi
POST/projects/{id}/stories/{sid}/reject · /projects/{id}/stories/{sid}/restartTolak story yang sudah delivered / kembalikan story yang ditolak ke started (rejected bersifat terminal bagi /transitions)
POST/projects/{id}/stories/{sid}/archive · /projects/{id}/stories/{sid}/unarchiveArsipkan / batalkan arsip satu story
POST/projects/{id}/stories/bulk-unarchiveBatalkan arsip banyak story
POST/projects/{id}/stories/bulk_transitionTransisikan banyak story (1–100) sekaligus
POST/projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-moveArsipkan, hapus, duplikat, atau pindahkan (ke panel / posisi) banyak story
POST/projects/{id}/stories/{sid}/duplicateDuplikat satu story
POST / DELETE/projects/{id}/stories/{sid}/epics · …/epics/{eid}Keanggotaan epic dari story
GET/short-links/{code} · /story-referencesSelesaikan short link /s/<code> ke story-nya / selesaikan hingga 100 referensi — codes= (kode short link dipisah koma) dan ids= (project_id:story_id dipisah koma) — ke story yang dapat dibaca pemanggil

Parameter query daftar-story: archived= (exclude default / include / only — filter arsip tri-status; menggantikan include_archived=true yang usang, yang kini menjadi alias archived=include), include_done=true (mengikutsertakan story panel-Done yang dibekukan pada iterasi lampau, dikecualikan secara default). Paginasi (cursor= / limit= / offset=) dan set field parsial (fields=) mengikuti Paginasi dan Proyeksi field.

Create (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. estimate adalah label nilai skala sebagai string ("3", "13"); angka JSON ditolak. labels menerima ["auth"] atau [{ "name": "auth" }]; label yang tidak dikenal akan dibuat. Default: story_type=feature, current_state=unstarted.

Update (PUT …/stories/{sid}): field yang sama, semua opsional, plus "position" (float), "force_state_change" (bool), dan "expected_version" (bilangan bulat, version story — penyimpanan deskripsi ditolak dengan 409 stale_write jika deskripsi berubah setelah versi tersebut). "expected_updated_at" (RFC 3339) yang lama sudah usang dan masih berfungsi satu rilis lagi: jika dikirim bersama deskripsi dan tanpa expected_version, penyimpanan ditolak dengan 409 stale_write kecuali nilainya sama dengan updated_at story. Write story juga menghormati If-Match terhadap ETag story; ketidakcocokan menghasilkan 412 precondition_failed.

Transition (POST …/transitions): { "to": "<state>" }. Field-nya adalah to. Mengembalikan { story_id, state }. Pergerakan ilegal → 422 invalid_transition dengan details: { from, to, allowed }.

Bulk transition (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>" }. Setiap story dinilai secara independen; mengembalikan { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

Semua member. List/GET pada sebagian besar adalah (viewer). Menghapus lampiran atau lampiran tautan membutuhkan pengunggahnya atau (manager).

MetodePathBody / catatan
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) } atau { comment_emoji }. GET menerima fields= (daftar yang diizinkan: comment_id, story_comment_id, story_id, comment_text, comment_emoji, member, created) plus 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}Buat: { url, link_type?, title? }; perbarui: { url, title? } — link_type ∈ relates_to, duplicates, blocks, is_blocked_by, pull_request, branch, other; URL GitHub /pull/ dan /tree/ diberi tipe otomatis
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}Buat: { reviewer_id? / reviewer_agent_id?, comment? } — hilangkan keduanya untuk menugaskan diri sendiri. Perbarui: { status, comment? }
GET / POST/projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid}{ member_id? / agent_id? } — hilangkan keduanya untuk menambahkan pemanggil
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 } — label proyek yang sudah ada; buat label dengan POST /projects/{id}/labels, atau kirim labels pada PUT story
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}unggah multipart — video ≤ 200 MB, PDF / Word / Excel ≤ 25 MB, gambar / CSV / teks ≤ 10 MB; daftar adalah (viewer)
GET / POST/projects/{id}/stories/{sid}/link-attachments · DELETE …/link-attachments/{laid}Lampiran tautan — URL eksternal yang disimpan bersama lampiran file, bukan sebagai link kode
GET/attachments/{token} · /api/v1/avatars/{token}Pembacaan lampiran atau avatar berbasis token — URL yang dibagikan API; tidak perlu X-TrackerToken

Bentuk yang sama dengan story, tanpa mesin status. member untuk write dan untuk daftar komentar, pemilik, dan pengikut; (viewer) untuk daftar epic, satu epic, dan daftar lampiran.

MetodePathDeskripsi
GET / POST/projects/{id}/epics · GET / PUT / DELETE …/epics/{eid}Epic membawa nama, deskripsi Markdown, dan label pendukung yang menghubungkan story-story-nya
GET / POST / PUT / DELETE…/epics/{eid}/comments · …/comments/{cid}Komentar epic
GET / POST / DELETE…/epics/{eid}/owners · …/followers (+ varian /agents/{aid})Pemilik dan pengikut, anggota atau agen — pemilik epic diturunkan ke story-story-nya
GET / POST / DELETE…/epics/{eid}/attachments (+ /json) · …/link-attachmentsLampiran, batas yang sama dengan story
GET/projects/{id}/analytics/epics · …/analytics/epics/{eid}Progres per-epic: burnup, throughput, kesehatan, perkiraan (viewer)

member untuk write, (viewer) untuk pembacaan.

MetodePathDeskripsi
GET / POST/projects/{id}/labelsDaftar / buat label
GET / PUT / DELETE/projects/{id}/labels/{lid}Baca / perbarui / hapus label
POST/projects/{id}/labels/{lid}/archiveArsipkan (sembunyikan-lunak) label

Pembacaan terbuka untuk peran proyek apa pun, dan anonim pada proyek publik.

MetodePathDeskripsi
GET/projects/{id}/iterationsDaftar iterasi (≤ 500 per halaman; membawa ETag dan header lanjutan X-Tracker-Pagination-* saat terpotong)
GET/projects/{id}/iterations/{itid}Satu iterasi
GET/projects/{id}/iterations/first-previewJendela waktu, velocity yang diproyeksikan, dan pengisian dari Backlog untuk iterasi yang akan dibuat oleh penulisan penyemaian, atau untuk iterasi saat ini jika sudah ada (member)
POST/projects/{id}/iterationsBuat iterasi manual (manager)
DELETE/projects/{id}/iterations/{itid}Hapus iterasi (manager)
PUT/projects/{id}/iterations/{itid}/velocityGanti velocity satu iterasi tanpa mengubah strategi proyek (manager)
GET/projects/{id}/iterations/{itid}/done-storiesStory yang diterima dari iterasi yang sudah ditutup, terpaginasi
MetodePathDeskripsi
GET/projects/{id}/search?q=…Pencarian yang kuat — teks-penuh + qualifier facet / rentang-tanggal / orang (DSL gaya GitHub); mengembalikan { results, total, limit, offset }. query adalah alias untuk q; limit= (default 50, maks 1000) / offset= untuk paginasi; sort= mengurutkan menurut relevance (default), created, created_asc, state, atau updated. (viewer) — lihat Panduan
GET/projects/{id}/metrics/{velocity,burndown,story-types,contributors}Deret data halaman Metrics (viewer); metrik epic ada di bawah /analytics/epics di atas
GET/projects/{id}/backlog/groupingGrup iterasi terproyeksi dari Backlog (viewer)
GET / PUT/projects/{id}/preferencesPreferensi papan Anda untuk proyek ini — peran proyek apa pun, hanya baris milik Anda sendiri
MetodePathDeskripsi
GET/projects/{id}/eventsAliran event dengan paginasi-kursor (member) — viewer mendapat 403

Parameter kueri: since_id=<event_id> (since adalah alias lama; since_id yang menang bila keduanya dikirim), types=story.created,story.transitioned,comment.added,…, limit= (default 100, ≤ 500), cursor=. Responsnya adalah { items, next_since_id, next_cursor }: simpan next_since_id dan kirim kembali sebagai since_id untuk melanjutkan; next_cursor bernilai null pada halaman terakhir.

Feed notifikasi terpadu di dalam aplikasi: baris notifikasi kelas satu (permintaan review, aktivitas story, undangan, …) digabung dengan kotak masuk @-sebutan menjadi satu aliran, terbaru lebih dulu. Id feed berawalan sumber (nt-… / sc-… / ec-…). Sesi anggota dan kunci ea_user_* membaca baris sisi-anggota mereka; kunci ea_agent_* baris sisi-agennya.

MetodePathDeskripsi
GET/me/notificationsFeed notifikasi Anda. Filter: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); paginasi dengan cursor= / limit=
GET/me/notifications/unread-countTotal belum dibaca — { unread_count, by_category: { mentions, reviews, stories, invitations } }
POST/me/notifications/read-allTandai semua telah dibaca; mengembalikan hitungan terbaru
POST/me/notifications/{id}/ackTandai satu item telah dibaca (idempoten)
POST/me/notifications/{id}/acceptTerima undangan proyek / organisasi langsung dari feed (khusus token anggota)
POST/me/notifications/{id}/declineTolak undangan proyek / organisasi (khusus token anggota)
GET/me/notifications/resolve-invite?token=…Petakan token undangan dari email ke id notifikasi Anda — { "id": "nt-…" } atau { "id": null }
GET/me/notifications/streamPush langsung — Server-Sent Events (text/event-stream); lihat di bawah

Endpoint stream bukan endpoint JSON sehingga tidak ada dalam spesifikasi OpenAPI: ia menjaga koneksi tetap terbuka dan mengirim frame tanpa payload ({"type":"notification","kind":…}) setiap ada yang baru, memberi tahu klien untuk mengambil ulang feed. Koneksi diputus di sisi server setelah 45 menit — sambungkan dan autentikasi ulang. Hanya sesi anggota dan kunci ea_user_*; kunci ea_agent_* menerima 403.

MetodePathDeskripsi
POST/projects/{id}/importSumber file: source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. file= multipart. Sinkron — menjawab dengan hitungan hasil.
POST/projects/{id}/import/jsonBody JSON; source=github tidak memerlukan file — owner, repo, token opsional, dan flag opt-in include_pull_requests / include_milestones / include_releases / include_dependencies, dan include_comments (bawaan true); sumber file mengirim file_base64. Asinkron: mengembalikan 202 { import_id, status }. Server mengambil lewat API GraphQL GitHub, yang menolak pemanggil anonim, jadi selalu ada token yang sampai ke GitHub — milik Anda, atau token bersama milik deployment. Lihat Panduan.
GET/projects/{id}/imports/{import_id}Poll sebuah job: status berjalan pending → fetching → writing → done | failed, dengan progress_current / progress_total selama pengambilan dan hitungan hasil saat done

Hanya satu impor JSON berjalan per proyek pada satu waktu; POST …/import/json kedua saat satu masih berjalan adalah 409 import_already_running. Dengan check_unpointed_estimates: true (sumber berkas; diabaikan untuk github), berkas yang berisi estimasi bug atau chore yang tidak diberi poin oleh proyek ditolak dengan 409 import_unpointed_estimates dan details.count sebelum job apa pun dimulai; tanpa flag, impor membuang estimasi tersebut dan melaporkan { code: "estimates_unpointed_dropped", count } di warnings hasil. dry_run: true (body JSON atau dry_run=true multipart) mempratinjau sumber apa pun: mengurai, menyelesaikan, mendeduplikasi, mengembalikan hitungan { imported, skipped, errors, unmatched } yang sama, lalu membatalkan — tanpa apa pun yang ditulis. Batas: file 10 MiB (400 import_too_large) dan 5.000 story per impor untuk sumber berbasis file (400 import_too_many_records); tanpa apa pun yang ditulis. Body request di atas 16 MiB ditolak lebih awal dengan 413 request_too_large. Sumber GitHub tanpa plafon — ia menulis per bongkahan alih-alih satu transaksi. Impor ulang idempoten per source id — baris yang sudah diimpor dilewati, bukan diduplikasi.

MetodePathDeskripsi
GET/projects/{id}/export/formatsFormat yang terdaftar: { id, name, content_type, drops, includes_archived }. Peran proyek apa pun.
GET/projects/{id}/export/{format}Unduh satu (manager). Pertukaran: eat (kesetiaan penuh), jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json; dokumen: pdf, docx.
GET/projects/{id}/export/attachmentsSetiap lampiran sebagai satu zip yang dapat dijelajahi (file mempertahankan nama asli; manifes JSON + CSV) (manager).

Ekspor dokumen (pdf, docx) menerima parameter query tambahan: page_size= (letter default / a4 / legal / folio), from= / to= (batas jendela-story — RFC 3339 atau YYYY-MM-DD polos; sebuah story masuk rentang saat created atau completed_at-nya jatuh di dalamnya), include_icebox= / include_backlog= (keduanya default false, sehingga ekspor yang dapat dibagikan hanya menampilkan pekerjaan terjadwal / sedang berjalan). Format CSV pertukaran mengabaikannya.

MetodePathDeskripsi
GET / POST/projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/healthDaftar snapshot, ambil satu sekarang, baca satu, dan ringkasan kesehatan retensi
POST/projects/{id}/restores · POST …/restores/partial · GET …/restores/{restore_id}Pulihkan seluruh snapshot, atau tabel tertentu darinya, dan poll proses pemulihannya

POST-POST tersebut berada di tingkat batas laju sensitive (di bawah).

East Agile Tracker adalah penyedia OAuth 2.1 untuk klien MCP. Sebuah klien menemukannya di /.well-known/oauth-authorization-server dan /.well-known/oauth-protected-resource/mcp, mengarahkan Anda ke /oauth/authorize (halaman persetujuan), menukar kodenya di /oauth/token, lalu berbicara MCP di /mcp dengan token ea_mcp_* yang dihasilkan. Grant didaftar dan dicabut di /me/oauth_grants. Endpoint penyedia memiliki tingkat batas lajunya sendiri.

Endpoint write (POST, PUT, DELETE) menerima header Idempotency-Key. Kunci sama + body sama memutar ulang respons yang ter-cache (jendela 24-jam); kunci sama + body berbeda mengembalikan 409 idempotency_conflict. Kunci dicakup pada kredensial yang mengirimnya. Tidak diterapkan pada GET/HEAD/OPTIONS, /openapi.json dan /docs, /api/auth/*, /mcp, path apa pun yang memuat /attachments, atau request multipart/* apa pun; request tanpa kredensial tidak pernah di-cache. Respons yang berhenti sebelum sampai pada jawaban domain tidak pernah di-cache — 401, 403, 404, 429, dan setiap 5xx — sehingga coba-ulang setelah salah satunya mencapai handler; 400, 409, 412, dan 422 adalah jawaban domain dan diputar ulang seperti keberhasilan.

Endpoint daftar menerima cursor=<opaque> dan limit=<n>. Saat diatur, responsnya adalah { "items": [...], "next_cursor": "<str|null>" }; berikan next_cursor kembali untuk halaman berikutnya. Batas limit berbeda per endpoint: 200 pada story, komentar, dan proyek; 500 pada event; 1000 pada log audit. Pencarian memakai paginasi limit (≤ 1000) dan offset alih-alih kursor dan mengembalikan { results, total, limit, offset }.

Daftar biasa (tanpa cursor/limit) yang harus memotong responsnya menyatakannya lewat header — X-Tracker-Pagination-Truncated, X-Tracker-Pagination-Limit, X-Tracker-Pagination-Offset, dan X-Tracker-Pagination-Next-Offset; kirim balik yang terakhir sebagai offset= untuk halaman berikutnya. Tidak ada header jumlah total.

Daftar story, komentar, dan proyek menerima fields= (dipisahkan koma) untuk mengembalikan hanya field tertentu. Id sumber daya selalu disertakan (story_id, story_comment_id dan comment_id, project_id); nama field yang tidak dikenal mengembalikan 400 validation_failed dengan nama yang menyalahi di details.fields.

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

Setiap error JSON memiliki code dan error; beberapa menambahkan details:

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
StatuscodeKapan
400invalid_parameterinput buruk; pesan di error. Validasi field (kosong/panjang/null-byte/email) menambahkan details.fields dan details.constraint; hanya error bad request polos yang tanpa details
400validation_failederror input terstruktur; details.fields adalah array nama field yang menyalahi
400kode domainpenolakan khusus route dengan kodenya sendiri dan tanpa details — mis. unsupported_export_format, import_too_large, import_unknown_source
401unauthenticatedtoken hilang/tidak valid
403unauthorized_operationterautentikasi tetapi peran tidak mencukupi
404unfound_resourcetidak ditemukan — juga dikembalikan ke non-member
409conflictkonflik sumber daya (mis. duplikat)
409idempotency_conflictIdempotency-Key digunakan ulang dengan body berbeda
409stale_write · import_already_running · import_unpointed_estimatesdeskripsi berubah setelah expected_version Anda (atau expected_updated_at tidak lagi cocok) · sebuah impor sedang berjalan · berkas berisi estimasi bug atau chore yang tidak diberi poin oleh proyek (details.count)
412precondition_failedIf-Match tidak cocok dengan ETag sumber daya saat ini; details membawa expected dan current
413request_too_largebody melebihi batas ukuran route
422invalid_transitionpergerakan status ilegal; details membawa { from, to, allowed }
429rate_limitedterlalu banyak request dari IP ini pada route yang dibatasi laju; header Retry-After
500internal_errorkesalahan server — pesan generik; aman untuk dicoba-ulang
502upstream_errorlayanan yang menjadi sandaran route (mis. GitHub) gagal
503not_configureddeployment tidak memiliki integrasi yang dibutuhkan route ini (SMS, penyimpanan objek, …)

details.fields adalah array JSON nama field (mis. ["to"]), kadang dengan kunci tambahan seperti max. Tidak ada peta field→pesan.

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

Per IP klien, pada segelintir route; lalu lintas API terautentikasi di tempat lain tidak dibatasi lajunya. Default (setiap pasangan adalah laju berkelanjutan dan burst, dapat disetel operator):

  • Auth — /api/auth/*: 0,5 req/d, burst 20.
  • OAuth provider — /oauth/*: 1 req/d, burst 60.
  • Public — /api/contact: 0,2 req/d, burst 10.
  • Feedback — /api/v1/feedback dan /api/v1/feedback/with-screenshot: tiga tingkat bertumpuk — satu kiriman per 15 d, 10 per jam, 36 per hari.
  • Avatars — pengalihan avatar tanpa autentikasi: 20 req/d, burst 200.
  • Sensitive — POST cadangan dan pemulihan: ~0,002 req/d, burst 5.

Batas yang terlampaui mengembalikan 429 dengan header Retry-After dan amplop error JSON standar, code: "rate_limited".