Tham chiếu endpoint REST đầy đủ. Để có hướng dẫn và ví dụ, xem Hướng dẫn API.
Mọi thứ một thành viên dự án có thể làm trong giao diện web đều có sẵn ở đây — SPA tiêu thụ chính API này. Các thao tác yêu cầu vai trò owner được đánh dấu (owner); mọi thứ khác chỉ cần là thành viên dự án (hoặc, đối với các thao tác đọc được đánh dấu (viewer), bất kỳ cấp quyền truy cập nào).
Cơ sở (Base)
Phần tiêu đề “Cơ sở (Base)”https://eastagiletracker.com/api/v1https://api.eastagiletracker.com/api/v1 phục vụ API y hệt. Mọi request và response đều là JSON, ngoại trừ một vài endpoint tải lên tệp chấp nhận multipart.
Xác thực
Phần tiêu đề “Xác thực”Mọi request đã xác thực gửi một API key qua một trong các cách:
X-TrackerToken: <key>Authorization: Bearer <key>
User key bắt đầu bằng ea_user_. Agent key bắt đầu bằng ea_agent_. Xem Hướng dẫn API → Hai loại key.
Các endpoint không cần xác thực: /openapi.json, /docs, các endpoint /auth/*, và các lượt tra cứu dữ liệu tham chiếu (/story_types, /story_states, /effort_scales, …). /meta là cần xác thực — bất kỳ key hợp lệ nào cũng dùng được, nhưng nó không có phạm vi theo dự án (một agent key gắn với dự án cũng truy cập được nó).
Vai trò
Phần tiêu đề “Vai trò”Ba cấp độ kiểm soát các endpoint có phạm vi theo dự án:
| Cấp độ | Ai vượt qua | Các thao tác điển hình |
|---|---|---|
| viewer | viewer, member, owner | đọc (liệt kê/lấy story, tìm kiếm, phân tích) |
| member | member, owner | mọi thao tác ghi với hạng mục công việc (story, task, comment, …) |
| owner | chỉ owner | cài đặt dự án, quản lý thành viên, agent key, xóa, nhập, audit log |
Một người không phải thành viên nhận 404 unfound_resource (không phải 403) trên các path dự án, nên các project ID không thể bị liệt kê.
Các endpoint tự mô tả
Phần tiêu đề “Các endpoint tự mô tả”| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /openapi.json | Đặc tả OpenAPI 3 trực tiếp. Không cần xác thực. |
| GET | /docs | Swagger UI. Không cần xác thực. |
| GET | /meta | Danh tính người gọi (auth.kind/key_id/agent_id/project_id) + đồ thị chuyển đổi theo loại story. Cần xác thực (bất kỳ key hợp lệ nào; không có phạm vi theo dự án). Gọi cái này trước tiên. |
Tài khoản / danh tính
Phần tiêu đề “Tài khoản / danh tính”Những endpoint này hành động trên người gọi và chỉ cần một key hợp lệ (không cần vai trò dự án).
| Phương thức | Path | Mô tả |
|---|---|---|
| POST | /auth/register | Đăng ký một tài khoản mới |
| POST | /auth/login | Đăng nhập, trả về một token phiên |
| POST | /auth/logout | Đăng xuất |
| POST | /auth/forgot-password | Yêu cầu một email đặt lại mật khẩu |
| POST | /auth/reset-password | Dùng một token đặt lại để đặt mật khẩu mới |
| GET | /auth/verify-email | Xác minh một địa chỉ email |
| POST | /auth/accept-invite/lookup | Phân giải một token lời mời → email (không cần xác thực) |
| POST | /auth/accept-invite | Chấp nhận một lời mời dự án (sau khi đã xác thực) |
| GET | /me | Hồ sơ người dùng hiện tại |
| PUT | /me | Cập nhật hồ sơ |
| DELETE | /me | Xóa tài khoản |
| PUT | /me/password | Đổi mật khẩu |
| PUT | /me/settings | Cập nhật cài đặt (theme, tùy chọn thông báo) |
| POST | /me/avatar | Tải lên avatar (multipart) |
| POST | /me/api-token/regenerate | Xoay vòng API token của bạn — vô hiệu hóa các phiên/key hiện có |
| GET | /me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id} | Quản lý các API key người dùng (ea_user_) |
| GET | /me/activity | Hoạt động của bạn trên tất cả các dự án |
| GET | /me/data-export | Tự xuất dữ liệu của bạn theo GDPR |
| GET | /me/consent · POST /me/consent | Đọc / ghi nhận sự đồng ý ({ consent_type, granted }) |
| GET | /legal/pending · POST /legal/accept | Các tài liệu clickwrap đang chờ / ghi nhận sự chấp nhận |
| POST | /contact · POST /feedback · POST /feedback/with-screenshot | Liên hệ + phản hồi trong ứng dụng |
Dữ liệu tham chiếu (không cần xác thực)
Phần tiêu đề “Dữ liệu tham chiếu (không cần xác thực)”Các lượt tra cứu dữ liệu mầm (seed) được dùng khi tạo/ước lượng story. ID ổn định.
| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /story_types | feature, bug, chore, release (+ allow_points) |
| GET | /story_states | unstarted … accepted, rejected |
| GET | /effort_scales | các thang ước lượng khả dụng |
| GET | /effort_scales/{scale_id}/values | các giá trị điểm trong một thang đo |
Dự án
Phần tiêu đề “Dự án”| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /projects | Liệt kê các dự án của bạn |
| POST | /projects | Tạo một dự án |
| GET | /projects/{id} | Lấy chi tiết dự án (viewer) |
| PUT | /projects/{id} | Cập nhật cài đặt dự án (owner) |
| DELETE | /projects/{id} | Xóa một dự án (owner) |
| GET | /projects/{id}/audit-log | Luồng hoạt động dự án (owner) |
| GET | /projects/{id}/events | Luồng sự kiện phân trang theo cursor (viewer) — xem Events |
Thành viên và agent key
Phần tiêu đề “Thành viên và agent key”| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /projects/{id}/memberships | Liệt kê thành viên (viewer) |
| POST | /projects/{id}/memberships | Mời một thành viên bằng email (owner) |
| PUT | /projects/{id}/memberships/{mid} | Cập nhật vai trò (owner) |
| DELETE | /projects/{id}/memberships/{mid} | Loại bỏ một thành viên (owner) |
| GET / POST | /projects/{id}/agent_keys | Liệt kê / phát hành agent key (owner) |
| DELETE | /projects/{id}/agent_keys/{kid} | Thu hồi một agent key (owner) |
Story
Phần tiêu đề “Story”Mọi thao tác ghi story cần vai trò member.
| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /projects/{id}/stories | Liệt kê story (phân trang, lọc được) (viewer) |
| POST | /projects/{id}/stories | Tạo một story |
| GET | /projects/{id}/stories/{sid} | Lấy một story (viewer) |
| PUT | /projects/{id}/stories/{sid} | Cập nhật một story |
| DELETE | /projects/{id}/stories/{sid} | Xóa một story |
| POST | /projects/{id}/stories/{sid}/transitions | Thay đổi trạng thái có xác thực |
| POST | /projects/{id}/stories/bulk_transition | Chuyển đổi nhiều story (1–100) cùng lúc |
| POST | /projects/{id}/stories/bulk-delete | Xóa nhiều story |
| POST | /projects/{id}/stories/bulk-duplicate | Nhân bản nhiều story |
| POST | /projects/{id}/stories/{sid}/duplicate | Nhân bản một story |
Create (POST …/stories): { "name" (bắt buộc), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. labels chấp nhận ["auth"] hoặc [{ "name": "auth" }]; các nhãn chưa biết sẽ được tạo. Giá trị mặc định: story_type=feature, current_state=unstarted.
Update (PUT …/stories/{sid}): cùng các trường, tất cả đều tùy chọn, cộng thêm "position" (float) và "force_state_change" (bool).
Transition (POST …/transitions): { "to": "<state>", "reason"? }. Trường là to. Trả về { story_id, state }. Bước di chuyển không hợp lệ → 422 invalid_transition với details: { from, to, allowed }.
Bulk transition (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>", "reason"? }. Mỗi story được đánh giá độc lập; trả về { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.
Tài nguyên con của story
Phần tiêu đề “Tài nguyên con của story”Tất cả đều là member. Thao tác List/GET trên hầu hết là (viewer).
| Phương thức | Path | Body / ghi chú |
|---|---|---|
| GET / POST | /projects/{id}/stories/{sid}/tasks · PUT/DELETE …/tasks/{tid} | { description (hoặc task_desc), complete?, task_order? } |
| GET / POST | /projects/{id}/stories/{sid}/comments · PUT/DELETE …/comments/{cid} | { text (hoặc comment_text) } hoặc { 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? } — bỏ qua cả hai để thêm người gọi |
| 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} | tải lên multipart (≤ 2 GB mỗi tệp); thao tác list là (viewer) |
Nhãn (Label)
Phần tiêu đề “Nhãn (Label)”member cho thao tác ghi, (viewer) cho thao tác đọc.
| Phương thức | Path | Mô tả |
|---|---|---|
| GET / POST | /projects/{id}/labels | Liệt kê / tạo một nhãn |
| PUT / DELETE | /projects/{id}/labels/{lid} | Cập nhật / xóa một nhãn |
| POST | /projects/{id}/labels/{lid}/archive | Lưu trữ (ẩn mềm) một nhãn |
Iteration
Phần tiêu đề “Iteration”| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /projects/{id}/iterations | Liệt kê iteration (member) |
| POST | /projects/{id}/iterations | Tạo một iteration thủ công (owner) |
| DELETE | /projects/{id}/iterations/{itid} | Xóa một iteration (owner) |
Tìm kiếm, phân tích, số liệu, tùy chọn
Phần tiêu đề “Tìm kiếm, phân tích, số liệu, tùy chọn”| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /projects/{id}/search?query=… | Tìm kiếm bằng cú pháp lọc (viewer) — xem Hướng dẫn |
| GET | /projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections} | Phân tích (viewer). Phân tích chi tiết iteration nhận ?iteration_id= |
| GET | /projects/{id}/metrics/{velocity,burndown,story-types} | Số liệu (viewer) |
| GET / PUT | /projects/{id}/preferences | Tùy chọn board của bạn cho dự án này (member) |
Events
Phần tiêu đề “Events”| Phương thức | Path | Mô tả |
|---|---|---|
| GET | /projects/{id}/events | Luồng sự kiện phân trang theo cursor (viewer) |
Các tham số truy vấn: since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. Phản hồi bao gồm next_cursor. Truyền event_id cuối cùng bạn đã thấy làm since để tiếp tục.
Nhập (Import) (owner)
Phần tiêu đề “Nhập (Import) (owner)”| Phương thức | Path | Mô tả |
|---|---|---|
| POST | /projects/{id}/import (+ /json) | Tải lên multipart. source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json. |
WebSocket
Phần tiêu đề “WebSocket”wss://eastagiletracker.com/ws/control?token=<key>Dành cho điều khiển từ xa giao diện một cách tương tác ({ "action": "get_state", "id": "req-1" }). Không phải một kênh dữ liệu — mọi thao tác đọc/ghi đều đi qua REST. Chỉ một phiên bản (single-instance); không được phân phối (fan-out) qua các bản sao.
Idempotency
Phần tiêu đề “Idempotency”Các endpoint ghi (POST, PUT, DELETE) chấp nhận một header Idempotency-Key. Cùng key + cùng body sẽ phát lại phản hồi được lưu cache (cửa sổ 24 giờ); cùng key + một body khác sẽ trả về 409 idempotency_conflict. Không áp dụng cho GET/HEAD/OPTIONS, /auth/*, hoặc các path /attachments. Các phản hồi 5xx không bao giờ được cache — một lần thử lại sẽ đến được handler.
Phân trang
Phần tiêu đề “Phân trang”Các endpoint danh sách chấp nhận cursor=<opaque> và limit=<n≤200>. Khi được đặt, phản hồi là { "items": [...], "next_cursor": "<str|null>" }; truyền next_cursor trở lại để sang trang. Một số danh sách cũng trả về một header X-Tracker-Pagination-Total.
Phép chiếu trường (Field projection)
Phần tiêu đề “Phép chiếu trường (Field projection)”Các endpoint danh sách chấp nhận fields= (cách nhau bằng dấu phẩy) để chỉ trả về các trường cụ thể. story_id luôn được bao gồm; một tên trường chưa biết sẽ trả về 400 validation_failed với các tên vi phạm trong details.fields.
GET /projects/123/stories?fields=story_id,name,current_state,ownersĐịnh dạng lỗi
Phần tiêu đề “Định dạng lỗi”Mọi lỗi JSON đều có code và error; một số thêm details:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`", "details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }| Trạng thái | code | Khi nào |
|---|---|---|
| 400 | invalid_parameter | đầu vào sai; thông điệp trong error, không có details (hầu hết kiểm tra: trống/độ dài/null-byte/email) |
| 400 | validation_failed | lỗi đầu vào có cấu trúc; details.fields là một mảng tên các trường vi phạm |
| 401 | unauthenticated | thiếu/token không hợp lệ |
| 403 | unauthorized_operation | đã xác thực nhưng vai trò không đủ |
| 404 | unfound_resource | không tìm thấy — cũng được trả về cho người không phải thành viên |
| 409 | conflict | xung đột tài nguyên (ví dụ trùng lặp) |
| 409 | idempotency_conflict | Idempotency-Key được dùng lại với một body khác |
| 422 | invalid_transition | bước di chuyển trạng thái không hợp lệ; details mang { from, to, allowed } |
| 500 | internal_error | lỗi máy chủ — thông điệp chung; an toàn để thử lại |
details.fields là một mảng JSON tên các trường (ví dụ ["to"]), đôi khi kèm các khóa bổ sung như max. Không có ánh xạ trường→thông điệp.
{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }Giới hạn tốc độ (Rate limit)
Phần tiêu đề “Giới hạn tốc độ (Rate limit)”Theo từng key (theo từng IP đối với các endpoint không cần xác thực), token bucket GCRA:
- Auth —
/auth/*: 0.5 req/s, burst 20. - Public —
/contact,/feedback: 0.2 req/s, burst 10. - Sensitive — đặt lại mật khẩu: ~0.002 req/s, burst 5.
Một giới hạn bị vượt quá sẽ trả về 429 Too Many Requests với một header Retry-After và một body văn bản thuần (plain-text) (không phải bao bì lỗi JSON).