Bỏ qua để đến nội dung

Đặc tả API

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).

https://eastagiletracker.com/api/v1

https://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.

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, …). /metacầ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ó).

Ba cấp độ kiểm soát các endpoint có phạm vi theo dự án:

Cấp độAi vượt quaCác thao tác điển hình
viewerviewer, member, ownerđọc (liệt kê/lấy story, tìm kiếm, phân tích)
membermember, ownermọi thao tác ghi với hạng mục công việc (story, task, comment, …)
ownerchỉ ownercà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ê.

Phương thứcPathMô tả
GET/openapi.jsonĐặc tả OpenAPI 3 trực tiếp. Không cần xác thực.
GET/docsSwagger UI. Không cần xác thực.
GET/metaDanh 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.

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ứcPathMô 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-passwordYêu cầu một email đặt lại mật khẩu
POST/auth/reset-passwordDùng một token đặt lại để đặt mật khẩu mới
GET/auth/verify-emailXác minh một địa chỉ email
POST/auth/accept-invite/lookupPhân giải một token lời mời → email (không cần xác thực)
POST/auth/accept-inviteChấp nhận một lời mời dự án (sau khi đã xác thực)
GET/meHồ sơ người dùng hiện tại
PUT/meCập nhật hồ sơ
DELETE/meXóa tài khoản
PUT/me/passwordĐổi mật khẩu
PUT/me/settingsCập nhật cài đặt (theme, tùy chọn thông báo)
POST/me/avatarTải lên avatar (multipart)
POST/me/api-token/regenerateXoay 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/activityHoạt động của bạn trên tất cả các dự án
GET/me/data-exportTự 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/acceptCác tài liệu clickwrap đang chờ / ghi nhận sự chấp nhận
POST/contact · POST /feedback · POST /feedback/with-screenshotLiê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ứcPathMô tả
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scalescác thang ước lượng khả dụng
GET/effort_scales/{scale_id}/valuescác giá trị điểm trong một thang đo
Phương thứcPathMô tả
GET/projectsLiệt kê các dự án của bạn
POST/projectsTạ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-logLuồng hoạt động dự án (owner)
GET/projects/{id}/eventsLuồng sự kiện phân trang theo cursor (viewer) — xem Events
Phương thứcPathMô tả
GET/projects/{id}/membershipsLiệt kê thành viên (viewer)
POST/projects/{id}/membershipsMờ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_keysLiệt kê / phát hành agent key (owner)
DELETE/projects/{id}/agent_keys/{kid}Thu hồi một agent key (owner)

Mọi thao tác ghi story cần vai trò member.

Phương thứcPathMô tả
GET/projects/{id}/storiesLiệt kê story (phân trang, lọc được) (viewer)
POST/projects/{id}/storiesTạ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}/transitionsThay đổi trạng thái có xác thực
POST/projects/{id}/stories/bulk_transitionChuyển đổi nhiều story (1–100) cùng lúc
POST/projects/{id}/stories/bulk-deleteXóa nhiều story
POST/projects/{id}/stories/bulk-duplicateNhân bản nhiều story
POST/projects/{id}/stories/{sid}/duplicateNhâ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ất cả đều là member. Thao tác List/GET trên hầu hết là (viewer).

Phương thứcPathBody / 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)

member cho thao tác ghi, (viewer) cho thao tác đọc.

Phương thứcPathMô tả
GET / POST/projects/{id}/labelsLiệ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}/archiveLưu trữ (ẩn mềm) một nhãn
Phương thứcPathMô tả
GET/projects/{id}/iterationsLiệt kê iteration (member)
POST/projects/{id}/iterationsTạ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ứcPathMô 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}/preferencesTùy chọn board của bạn cho dự án này (member)
Phương thứcPathMô tả
GET/projects/{id}/eventsLuồ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.

Phương thứcPathMô tả
POST/projects/{id}/import (+ /json)Tải lên multipart. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
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.

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.

Các endpoint danh sách chấp nhận cursor=<opaque>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.

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

Mọi lỗi JSON đều có codeerror; 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áicodeKhi nào
400invalid_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)
400validation_failedlỗ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
401unauthenticatedthiếu/token không hợp lệ
403unauthorized_operationđã xác thực nhưng vai trò không đủ
404unfound_resourcekhông tìm thấy — cũng được trả về cho người không phải thành viên
409conflictxung đột tài nguyên (ví dụ trùng lặp)
409idempotency_conflictIdempotency-Key được dùng lại với một body khác
422invalid_transitionbước di chuyển trạng thái không hợp lệ; details mang { from, to, allowed }
500internal_errorlỗ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"] } }

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).