Lewati ke konten

Spesifikasi API

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 owner ditandai (owner); selebihnya hanya membutuhkan keanggotaan proyek (atau, untuk pembacaan yang ditandai (viewer), tingkat akses apa pun).

https://eastagiletracker.com/api/v1

https://api.eastagiletracker.com/api/v1 menyajikan API yang identik. Semua request dan respons berupa JSON, kecuali beberapa endpoint unggah-file yang menerima multipart.

Setiap request terautentikasi mengirim kunci API melalui salah satu dari:

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

Kunci pengguna dimulai dengan ea_user_. Kunci agen dimulai dengan ea_agent_. Lihat Panduan API → Dua jenis kunci.

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

Tiga tingkat menggerbangi endpoint yang dicakup-proyek:

TingkatSiapa yang lolosOperasi tipikal
viewerviewer, member, ownerpembacaan (daftar/dapatkan story, pencarian, analitik)
membermember, ownersemua write work-item (story, task, komentar, …)
ownerhanya ownerpengaturan proyek, manajemen keanggotaan, kunci agen, hapus, impor, log audit

Non-member menerima 404 unfound_resource (bukan 403) pada path proyek, sehingga ID proyek tidak dapat dienumerasi.

MetodePathDeskripsi
GET/openapi.jsonSpesifikasi OpenAPI 3 langsung. 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.

Ini bertindak pada pemanggil dan hanya membutuhkan kunci valid (tanpa peran proyek).

MetodePathDeskripsi
POST/auth/registerDaftarkan akun baru
POST/auth/loginMasuk, mengembalikan token sesi
POST/auth/logoutKeluar
POST/auth/forgot-passwordMinta email reset-kata-sandi
POST/auth/reset-passwordGunakan token reset untuk menetapkan kata sandi baru
GET/auth/verify-emailVerifikasi alamat email
POST/auth/accept-invite/lookupSelesaikan token undangan → email (tidak terautentikasi)
POST/auth/accept-inviteTerima undangan proyek (setelah autentikasi)
GET/meProfil pengguna saat ini
PUT/mePerbarui profil
DELETE/meHapus akun
PUT/me/passwordUbah kata sandi
PUT/me/settingsPerbarui pengaturan (tema, preferensi notifikasi)
POST/me/avatarUnggah avatar (multipart)
POST/me/api-token/regenerateRotasi token API Anda — membatalkan sesi/kunci yang ada
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}Kelola kunci API pengguna (ea_user_)
GET/me/activityAktivitas Anda di semua proyek
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
POST/contact · POST /feedback · POST /feedback/with-screenshotKontak + umpan balik dalam-aplikasi

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
MetodePathDeskripsi
GET/projectsDaftar proyek Anda
POST/projectsBuat proyek
GET/projects/{id}Dapatkan detail proyek (viewer)
PUT/projects/{id}Perbarui pengaturan proyek (owner)
DELETE/projects/{id}Hapus proyek (owner)
GET/projects/{id}/audit-logAliran aktivitas proyek (owner)
GET/projects/{id}/eventsAliran event dengan paginasi-kursor (viewer) — lihat Event
MetodePathDeskripsi
GET/projects/{id}/membershipsDaftar anggota (viewer)
POST/projects/{id}/membershipsUndang anggota lewat email (owner)
PUT/projects/{id}/memberships/{mid}Perbarui peran (owner)
DELETE/projects/{id}/memberships/{mid}Hapus anggota (owner)
GET / POST/projects/{id}/agent_keysDaftar / cetak kunci agen (owner)
DELETE/projects/{id}/agent_keys/{kid}Cabut kunci agen (owner)

Semua write story membutuhkan peran member.

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/bulk_transitionTransisikan banyak story (1–100) sekaligus
POST/projects/{id}/stories/bulk-deleteHapus banyak story
POST/projects/{id}/stories/bulk-duplicateDuplikat banyak story
POST/projects/{id}/stories/{sid}/duplicateDuplikat satu story

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

Transition (POST …/transitions): { "to": "<state>", "reason"? }. 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>", "reason"? }. Setiap story dinilai secara independen; mengembalikan { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

Semua member. List/GET pada sebagian besar adalah (viewer).

MetodePathBody / catatan
GET / POST/projects/{id}/stories/{sid}/tasks · PUT/DELETE …/tasks/{tid}{ description (atau task_desc), complete?, task_order? }
GET / POST/projects/{id}/stories/{sid}/comments · PUT/DELETE …/comments/{cid}{ text (atau comment_text) } atau { comment_emoji }
GET / POST/projects/{id}/stories/{sid}/blockers · PUT/DELETE …/blockers/{bid}{ blocker_desc, resolved? }
GET / POST/projects/{id}/stories/{sid}/links · DELETE …/links/{lid}{ url, link_type?, title? }
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}{ reviewer_id? / reviewer_agent_id?, status, comment? }
GET / POST/projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid}{ member_id? / agent_id? } — 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}{ name }
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}unggah multipart (≤ 2 GB masing-masing); daftar adalah (viewer)

member untuk write, (viewer) untuk pembacaan.

MetodePathDeskripsi
GET / POST/projects/{id}/labelsDaftar / buat label
PUT / DELETE/projects/{id}/labels/{lid}Perbarui / hapus label
POST/projects/{id}/labels/{lid}/archiveArsipkan (sembunyikan-lunak) label
MetodePathDeskripsi
GET/projects/{id}/iterationsDaftar iterasi (member)
POST/projects/{id}/iterationsBuat iterasi manual (owner)
DELETE/projects/{id}/iterations/{itid}Hapus iterasi (owner)
MetodePathDeskripsi
GET/projects/{id}/search?query=…Pencarian sintaks filter (viewer) — lihat Panduan
GET/projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections}Analitik (viewer). Penelusuran iterasi menerima ?iteration_id=
GET/projects/{id}/metrics/{velocity,burndown,story-types}Metrik (viewer)
GET / PUT/projects/{id}/preferencesPreferensi papan Anda untuk proyek ini (member)
MetodePathDeskripsi
GET/projects/{id}/eventsAliran event dengan paginasi-kursor (viewer)

Parameter kueri: since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. Respons menyertakan next_cursor. Berikan event_id terakhir yang Anda lihat sebagai since untuk melanjutkan.

MetodePathDeskripsi
POST/projects/{id}/import (+ /json)Unggah multipart. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
wss://eastagiletracker.com/ws/control?token=<key>

Untuk kontrol-jarak-jauh UI interaktif ({ "action": "get_state", "id": "req-1" }). Bukan kanal data — semua pembacaan/write melalui REST. Hanya instans-tunggal; tidak disebarkan lintas replika.

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. Tidak diterapkan pada GET/HEAD/OPTIONS, /auth/*, atau path /attachments. Respons 5xx tidak pernah di-cache — sebuah coba-ulang mencapai handler.

Endpoint daftar menerima cursor=<opaque> dan limit=<n≤200>. Saat diatur, responsnya adalah { "items": [...], "next_cursor": "<str|null>" }; berikan next_cursor kembali untuk halaman berikutnya. Beberapa daftar juga mengembalikan header X-Tracker-Pagination-Total.

Endpoint daftar menerima fields= (dipisahkan koma) untuk mengembalikan hanya field tertentu. story_id selalu disertakan; 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, tanpa details (sebagian besar validasi: kosong/panjang/null-byte/email)
400validation_failederror input terstruktur; details.fields adalah array nama field yang menyalahi
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
422invalid_transitionpergerakan status ilegal; details membawa { from, to, allowed }
500internal_errorkesalahan server — pesan generik; aman untuk dicoba-ulang

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-kunci (per-IP untuk endpoint tidak terautentikasi), token bucket GCRA:

  • Auth/auth/*: 0,5 req/d, burst 20.
  • Public/contact, /feedback: 0,2 req/d, burst 10.
  • Sensitive — reset-kata-sandi: ~0,002 req/d, burst 5.

Batas yang terlampaui mengembalikan 429 Too Many Requests dengan header Retry-After dan body teks-biasa (bukan amplop error JSON).