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/v1API 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.
Autentikasi
Section titled “Autentikasi”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:
| Tingkat | Siapa yang lolos | Operasi tipikal |
|---|---|---|
| public viewer | siapa pun, pada proyek yang visibilitasnya publik | pembacaan papan: story, iterasi, pencarian, aktivitas story dan epic (dengan detail aktor disamarkan) |
| viewer | viewer, member, manager | pembacaan (daftar/dapatkan story, pencarian, metrik, daftar format ekspor) |
| member | member, manager | semua write work-item (story, task, komentar, …), aliran event |
| manager | hanya manager | pengaturan 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.
Endpoint yang mendeskripsikan diri
Section titled “Endpoint yang mendeskripsikan diri”| Metode | Path | Deskripsi |
|---|---|---|
| GET | /openapi.json | Spesifikasi OpenAPI 3 langsung, termasuk request body. Tidak terautentikasi. |
| GET | /docs | Swagger UI. Tidak terautentikasi. |
| GET | /meta | Identitas 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/config | Liveness, dan konfigurasi publik deployment (mode organisasi-tunggal, fitur opsional yang aktif, nama instans). Tidak terautentikasi, di luar /v1. |
Auth (/api/auth/*, di luar /v1)
Section titled “Auth (/api/auth/*, di luar /v1)”Endpoint sesi, tidak terautentikasi kecuali dinyatakan lain. SPA yang menggerakkannya; skrip biasanya memakai kunci API sebagai gantinya.
| Metode | Path | Deskripsi |
|---|---|---|
| POST | /auth/register | Daftarkan akun baru — dijaga reCAPTCHA; akun kemudian melewati tantangan SMS |
| POST | /auth/sms/challenge · /auth/sms/status · /auth/sms/bypass | Kirim / periksa kode SMS pendaftaran (bypass digerbangi operator) |
| GET | /auth/config | Metode masuk mana yang ditawarkan deployment |
| POST | /auth/login | Masuk dengan email + kata sandi; mengembalikan JWT sesi, atau tantangan TOTP |
| POST | /auth/login/totp | Selesaikan proses masuk dengan kode autentikator atau kode pemulihan |
| POST | /auth/passkey/login/start · /auth/passkey/login/finish | Masuk WebAuthn tanpa kata sandi |
| GET | /auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchange | Masuk OAuth dengan GitHub atau Google |
| POST | /auth/refresh · /auth/refresh/revoke | Rotasi refresh token / cabut |
| POST | /auth/logout | Keluar (terautentikasi; mencabut refresh token sesi ini) |
| POST | /auth/forgot-password · /auth/reset-password | Minta email reset / gunakan token reset |
| POST | /auth/accept-invite/lookup · /auth/accept-invite | Selesaikan token undangan → email / terima undangan proyek (setelah autentikasi) |
| POST | /auth/oauth/link/preview · …/link/confirm · /auth/oauth/merge/preview · …/merge/confirm | Hubungkan akun GitHub atau Google ke akun yang sudah ada, atau gabungkan dua akun |
| POST | /auth/email_addresses/primary/preview · …/primary/confirm | Selesaikan perubahan email utama dari tautan konfirmasi yang dikirim lewat email |
Akun / identitas
Section titled “Akun / identitas”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.
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /me | Profil pengguna saat ini |
| PUT | /me | Perbarui profil |
| DELETE | /me | Hapus akun — ditolak selama Anda satu-satunya owner sebuah organisasi atau proyek yang memiliki anggota lain |
| GET | /me/deletion-impact | Apa yang akan dihapus bila akun dihapus dan apa yang menghalanginya |
| PUT | /me/password | Ubah kata sandi |
| PUT | /me/settings | Perbarui pengaturan (tema, preferensi notifikasi) |
| POST / DELETE | /me/avatar | Unggah (multipart) / hapus avatar Anda |
| POST | /me/api-token/regenerate | Keluarkan setiap sesi dan kembalikan token sesi baru; kunci API tidak terpengaruh |
| GET / POST | /me/email_addresses · GET …/email_addresses/offers · PUT …/email_addresses/primary | Alamat 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}/link | Akun 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/disable | Pendaftaran 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/activity | Aktivitas Anda di semua proyek |
| GET | /me/stories | Story 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}/ack | Kotak masuk @-sebutan (unacked=true untuk memfilter) dan pengakuannya — juga dilebur ke feed notifikasi di bawah |
| GET | /me/data-export | Ekspor-mandiri GDPR atas data Anda |
| GET | /me/consent · POST /me/consent | Baca / catat persetujuan ({ consent_type, granted }) |
| GET | /legal/pending · POST /legal/accept | Dokumen clickwrap tertunda / catat penerimaan |
| GET / PUT | /agent/me | Identitas 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-screenshot | Kontak + umpan balik dalam-aplikasi; dibatasi laju per IP |
Data referensi (tidak terautentikasi)
Section titled “Data referensi (tidak terautentikasi)”Lookup benih yang digunakan saat membuat/mengestimasi story. ID stabil.
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /story_types | feature, bug, chore, release (+ allow_points) |
| GET | /story_states | unstarted … accepted, rejected |
| GET | /effort_scales | skala estimasi yang tersedia |
| GET | /effort_scales/{scale_id}/values | nilai poin dalam suatu skala |
| GET | /priority_scales · /priority_scales/{scale_id}/values | skala prioritas dan nilainya (priority_id pada story diselesaikan di sini) |
Organisasi
Section titled “Organisasi”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.
| Metode | Path | Deskripsi |
|---|---|---|
| GET / POST | /organizations | Daftar 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-remove | Ubah 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-ownership | Serahkan peran owner ke anggota lain |
| GET | /organization-invitations/{token} · POST …/{token}/accept | Selesaikan / terima undangan organisasi yang dikirim lewat email |
| GET | /organizations/{oid}/export · POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/download | Ekspor organisasi khusus-owner: zip berisi dump SQL dan setiap lampiran, dijalankan sebagai job |
Proyek
Section titled “Proyek”| Metode | Path | Deskripsi |
|---|---|---|
| GET | /projects | Daftar proyek Anda (limit ≤ 200) |
| POST | /projects | Buat 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}/pin | Sematkan / lepas sematan proyek di daftar proyek Anda |
| POST | /projects/{id}/transfer-organization | Pindahkan proyek ke organisasi lain — pemanggil harus Manajer proyek dan owner atau admin organisasi tujuan |
| POST | /projects/{id}/slack/test | Kirim pesan uji ke feed Slack proyek (manager) |
| GET / POST | /projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seed | Proyek showcase publik: periksa apakah Anda dapat mengklaimnya, klaim, isi datanya (pengisian data khusus admin produk; selain itu mendapat 404) |
| GET | /projects/{id}/audit-log | Pembacaan audit log — riwayat proyek plus aktivitas per-story / per-epic lewat surface=; akses bervariasi menurut surface, lihat di bawah |
| GET | /projects/{id}/events | Aliran 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.
Anggota, agen, dan kunci agen
Section titled “Anggota, agen, dan kunci agen”| Metode | Path | Deskripsi |
|---|---|---|
| GET | /projects/{id}/memberships | Daftar anggota (viewer) |
| POST | /projects/{id}/memberships | Undang 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-remove | Ubah peran, atau keluarkan, banyak anggota sekaligus (manager) |
| GET | /projects/{id}/addable-members · POST /projects/{id}/members/add-existing | Anggota organisasi yang belum ada di proyek / tambahkan satu tanpa undangan email — (manager) dan owner atau admin organisasi |
| POST | /projects/{id}/members/join | Owner 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_keys | Daftar (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/onboarding | Bundel 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}/avatar | Rotasi 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).
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /projects/{id}/stories | Daftar story (terpaginasi, dapat difilter) (viewer) |
| POST | /projects/{id}/stories | Buat 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}/transitions | Ubah status dengan validasi |
| POST | /projects/{id}/stories/{sid}/reject · /projects/{id}/stories/{sid}/restart | Tolak 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}/unarchive | Arsipkan / batalkan arsip satu story |
| POST | /projects/{id}/stories/bulk-unarchive | Batalkan arsip banyak story |
| POST | /projects/{id}/stories/bulk_transition | Transisikan banyak story (1–100) sekaligus |
| POST | /projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-move | Arsipkan, hapus, duplikat, atau pindahkan (ke panel / posisi) banyak story |
| POST | /projects/{id}/stories/{sid}/duplicate | Duplikat satu story |
| POST / DELETE | /projects/{id}/stories/{sid}/epics · …/epics/{eid} | Keanggotaan epic dari story |
| GET | /short-links/{code} · /story-references | Selesaikan 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 } ] }.
Sub-sumber daya story
Section titled “Sub-sumber daya story”Semua member. List/GET pada sebagian besar adalah (viewer). Menghapus lampiran atau lampiran tautan membutuhkan pengunggahnya atau (manager).
| Metode | Path | Body / 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.
| Metode | Path | Deskripsi |
|---|---|---|
| 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-attachments | Lampiran, 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.
| Metode | Path | Deskripsi |
|---|---|---|
| GET / POST | /projects/{id}/labels | Daftar / buat label |
| GET / PUT / DELETE | /projects/{id}/labels/{lid} | Baca / perbarui / hapus label |
| POST | /projects/{id}/labels/{lid}/archive | Arsipkan (sembunyikan-lunak) label |
Iterasi
Section titled “Iterasi”Pembacaan terbuka untuk peran proyek apa pun, dan anonim pada proyek publik.
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /projects/{id}/iterations | Daftar 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-preview | Jendela 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}/iterations | Buat iterasi manual (manager) |
| DELETE | /projects/{id}/iterations/{itid} | Hapus iterasi (manager) |
| PUT | /projects/{id}/iterations/{itid}/velocity | Ganti velocity satu iterasi tanpa mengubah strategi proyek (manager) |
| GET | /projects/{id}/iterations/{itid}/done-stories | Story yang diterima dari iterasi yang sudah ditutup, terpaginasi |
Pencarian, metrik, preferensi
Section titled “Pencarian, metrik, preferensi”| Metode | Path | Deskripsi |
|---|---|---|
| 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/grouping | Grup iterasi terproyeksi dari Backlog (viewer) |
| GET / PUT | /projects/{id}/preferences | Preferensi papan Anda untuk proyek ini — peran proyek apa pun, hanya baris milik Anda sendiri |
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /projects/{id}/events | Aliran 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.
Notifikasi
Section titled “Notifikasi”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.
| Metode | Path | Deskripsi |
|---|---|---|
| GET | /me/notifications | Feed notifikasi Anda. Filter: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); paginasi dengan cursor= / limit= |
| GET | /me/notifications/unread-count | Total belum dibaca — { unread_count, by_category: { mentions, reviews, stories, invitations } } |
| POST | /me/notifications/read-all | Tandai semua telah dibaca; mengembalikan hitungan terbaru |
| POST | /me/notifications/{id}/ack | Tandai satu item telah dibaca (idempoten) |
| POST | /me/notifications/{id}/accept | Terima undangan proyek / organisasi langsung dari feed (khusus token anggota) |
| POST | /me/notifications/{id}/decline | Tolak 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/stream | Push 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.
Impor (manager)
Section titled “Impor (manager)”| Metode | Path | Deskripsi |
|---|---|---|
| POST | /projects/{id}/import | Sumber file: source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. file= multipart. Sinkron — menjawab dengan hitungan hasil. |
| POST | /projects/{id}/import/json | Body 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.
Ekspor
Section titled “Ekspor”| Metode | Path | Deskripsi |
|---|---|---|
| GET | /projects/{id}/export/formats | Format 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/attachments | Setiap 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.
Cadangan dan pemulihan (manager)
Section titled “Cadangan dan pemulihan (manager)”| Metode | Path | Deskripsi |
|---|---|---|
| GET / POST | /projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/health | Daftar 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).
MCP dan penyedia OAuth
Section titled “MCP dan penyedia OAuth”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.
Idempotensi
Section titled “Idempotensi”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.
Paginasi
Section titled “Paginasi”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.
Proyeksi field
Section titled “Proyeksi field”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,ownersFormat error
Section titled “Format error”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"] } }| Status | code | Kapan |
|---|---|---|
| 400 | invalid_parameter | input 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 |
| 400 | validation_failed | error input terstruktur; details.fields adalah array nama field yang menyalahi |
| 400 | kode domain | penolakan khusus route dengan kodenya sendiri dan tanpa details — mis. unsupported_export_format, import_too_large, import_unknown_source |
| 401 | unauthenticated | token hilang/tidak valid |
| 403 | unauthorized_operation | terautentikasi tetapi peran tidak mencukupi |
| 404 | unfound_resource | tidak ditemukan — juga dikembalikan ke non-member |
| 409 | conflict | konflik sumber daya (mis. duplikat) |
| 409 | idempotency_conflict | Idempotency-Key digunakan ulang dengan body berbeda |
| 409 | stale_write · import_already_running · import_unpointed_estimates | deskripsi 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) |
| 412 | precondition_failed | If-Match tidak cocok dengan ETag sumber daya saat ini; details membawa expected dan current |
| 413 | request_too_large | body melebihi batas ukuran route |
| 422 | invalid_transition | pergerakan status ilegal; details membawa { from, to, allowed } |
| 429 | rate_limited | terlalu banyak request dari IP ini pada route yang dibatasi laju; header Retry-After |
| 500 | internal_error | kesalahan server — pesan generik; aman untuk dicoba-ulang |
| 502 | upstream_error | layanan yang menjadi sandaran route (mis. GitHub) gagal |
| 503 | not_configured | deployment 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"] } }Batas laju
Section titled “Batas laju”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/feedbackdan/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 —
POSTcadangan 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".