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

Đặc tả API

Tài liệu tham chiếu đầy đủ các endpoint REST của East Agile Tracker API: xác thực và vai trò, dự án, story, epic, iteration, sự kiện, nhập và xuất dữ liệu.

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ò manager được đánh dấu (manager); 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ác bảng dưới đây nêu tên mọi nhóm route mà máy chủ gắn vào; những nhóm được tóm tắt trong một dòng được mô tả đầy đủ trong openapi.json trực tiếp.

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

API có host riêng: eastagiletracker.com phục vụ ứng dụng web và trả lời /api/v1/… bằng 404. 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.

Hai nhóm nằm cao hơn một cấp, dưới /api thay vì /api/v1: bề mặt xác thực (/api/auth/*) và biểu mẫu liên hệ công khai (/api/contact). Các cách viết /api/v1/… của chúng trả về 404.

Mọi request đã xác thực gửi một thông tin xác thực 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ằng ea_agent_, và access token MCP bằng ea_mcp_. Xem Hướng dẫn API → Ba loại thông tin xác thực.

Các endpoint không cần xác thực: /openapi.json, /docs, các endpoint /api/auth/*, và các lượt tra cứu dữ liệu tham chiếu (/story_types, /story_states, /effort_scales, /priority_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ó).

Bốn 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
public viewerbất kỳ ai, trên một dự án có chế độ hiển thị công khaiđọc board: story, iteration, tìm kiếm, hoạt động của story và epic (với chi tiết tác nhân bị che)
viewerviewer, member, managerđọc (liệt kê/lấy story, tìm kiếm, số liệu, danh sách định dạng xuất)
membermember, managermọi thao tác ghi với hạng mục công việc (story, task, comment, …), luồng sự kiện
managerchỉ managercài đặt dự án, quản lý thành viên, agent key, xóa, nhập, tải bản xuất, sao lưu, audit log

Agent giữ cùng các vai trò như thành viên — viewer, member, hoặc manager — bị giới hạn ở vai trò của thành viên đã phát hành key. 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 riêng tư, 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, bao gồm cả request body. 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.
GET/api/health · /api/configKiểm tra hoạt động, và cấu hình công khai của bản triển khai (chế độ một tổ chức, các tính năng tùy chọn đang bật, tên phiên bản). Không cần xác thực, nằm ngoài /v1.

Các endpoint phiên, không cần xác thực trừ khi có ghi chú. SPA điều khiển chúng; script thường dùng một API key thay vào đó.

Phương thứcPathMô tả
POST/auth/registerĐăng ký một tài khoản mới — được bảo vệ bằng reCAPTCHA; sau đó tài khoản phải qua thử thách SMS
POST/auth/sms/challenge · /auth/sms/status · /auth/sms/bypassGửi / kiểm tra mã SMS đăng ký (bypass do nhà vận hành kiểm soát)
GET/auth/configNhững phương thức đăng nhập mà bản triển khai cung cấp
POST/auth/loginĐăng nhập bằng email + mật khẩu; trả về một JWT phiên, hoặc một thử thách TOTP
POST/auth/login/totpHoàn tất đăng nhập bằng mã từ ứng dụng xác thực hoặc một mã khôi phục
POST/auth/passkey/login/start · /auth/passkey/login/finishĐăng nhập WebAuthn không cần mật khẩu
GET/auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchangeĐăng nhập OAuth bằng GitHub hoặc Google
POST/auth/refresh · /auth/refresh/revokeXoay vòng refresh token / thu hồi nó
POST/auth/logoutĐăng xuất (đã xác thực; thu hồi refresh token của phiên này)
POST/auth/forgot-password · /auth/reset-passwordYêu cầu email đặt lại / dùng token đặt lại
POST/auth/accept-invite/lookup · /auth/accept-invitePhân giải một token lời mời → email / chấp nhận lời mời dự án (sau khi đã xác thực)
POST/auth/oauth/link/preview · …/link/confirm · /auth/oauth/merge/preview · …/merge/confirmKết nối một tài khoản GitHub hoặc Google với một tài khoản hiện có, hoặc hợp nhất hai tài khoản
POST/auth/email_addresses/primary/preview · …/primary/confirmHoàn tất việc đổi email chính từ liên kết xác nhận được gửi qua email

Những endpoint này hành động trên người gọi và không cần vai trò dự án. Chúng cần một danh tính thành viên — một agent key nhận 401 (agent dùng /agent/me). Các lời gọi thay đổi thông tin xác thực — mật khẩu, TOTP, passkey, xóa tài khoản, đổi email, tạo lại token — cần một phiên trình duyệt; một API key nhận 403.

Phương thứcPathMô tả
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 — bị từ chối khi bạn là owner duy nhất của một tổ chức hoặc của một dự án có thành viên khác
GET/me/deletion-impactViệc xóa tài khoản sẽ gỡ bỏ những gì và điều gì đang chặn 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 / DELETE/me/avatarTải lên (multipart) / gỡ avatar của bạn
POST/me/api-token/regenerateĐăng xuất mọi phiên và trả về một token phiên mới; API key không bị ảnh hưởng
GET / POST/me/email_addresses · GET …/email_addresses/offers · PUT …/email_addresses/primaryCác địa chỉ email của bạn; dùng địa chỉ của một nhà cung cấp đã kết nối làm email phụ; yêu cầu đổi email chính (xác nhận qua email)
GET/me/oauth_identities · DELETE …/oauth_identities/{provider} · POST …/oauth_identities/{provider}/linkCác tài khoản đăng nhập đã kết nối (GitHub, Google): liệt kê, ngắt kết nối, bắt đầu liên kết
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/totp · POST /me/totp/setup · /me/totp/verify · /me/totp/disableĐăng ký xác thực hai yếu tố (TOTP); verify trả về các mã khôi phục một lần duy nhất
GET/me/passkeys · POST /me/passkeys/register/start · /me/passkeys/register/finish · DELETE /me/passkeys/{credential_id}Đăng ký và gỡ passkey
GET/me/oauth_grants · DELETE /me/oauth_grants/{grant_id}Connected apps — các client MCP và ứng dụng OAuth bạn đã cấp quyền
GET/me/activityHoạt động của bạn trên tất cả các dự án
GET/me/storiesCác story bạn sở hữu, đã yêu cầu, hoặc theo dõi trên mọi dự án mà token truy cập được — role=owned|requested|following, state=, cursor= / limit= (tối đa 200)
GET/me/mentions · POST /me/mentions/{mention_id}/ackHộp thư @-nhắc đến (unacked=true để lọc) và xác nhận đã đọc — cũng được gộp vào luồng thông báo bên dưới
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
GET / PUT/agent/meDanh tính và hồ sơ của chính một agent key, agent có thể đọc và sửa (phần tương ứng phía agent của /me)
POST/api/contact · /api/v1/feedback · /api/v1/feedback/with-screenshotLiên hệ + phản hồi trong ứng dụng; giới hạn tốc độ theo IP

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
GET/priority_scales · /priority_scales/{scale_id}/valuescác thang độ ưu tiên và giá trị của chúng (priority_id trên một story được phân giải tại đây)

Chỉ dành cho dịch vụ được lưu trữ — một bản cài đặt tự lưu trữ chạy ở chế độ một tổ chức và không gắn các endpoint này (ngoại trừ danh sách tổ chức). Vai trò là vai trò tổ chức: owner, admin, member.

Phương thứcPathMô tả
GET / POST/organizationsLiệt kê các tổ chức của bạn / tạo một tổ chức
GET / PUT / DELETE/organizations/{oid}Đọc, đổi tên (tên + slug; owner hoặc admin), xóa
GET / POST/organizations/{oid}/memberships · PUT / DELETE …/memberships/{member_id}Thành viên và lời mời; lời mời mang một trần vai trò (không bao giờ cao hơn vai trò người gọi; owner không bao giờ được mời)
POST/organizations/{oid}/memberships/bulk-role · …/memberships/bulk-removeĐổi vai trò hoặc xóa tối đa 200 thành viên cùng lúc. Tất cả hoặc không: một lô sẽ xóa owner cuối cùng hoặc để một dự án không có chủ sở hữu sẽ bị từ chối toàn bộ; với reassign_confirmed, bạn trở thành chủ sở hữu các dự án đó
DELETE/organizations/{oid}/invitations/{invitation_id}Thu hồi một lời mời đang chờ
POST/organizations/{oid}/transfer-ownershipChuyển vai trò owner cho một thành viên khác
GET/organization-invitations/{token} · POST …/{token}/acceptPhân giải / chấp nhận một lời mời tổ chức gửi qua email
GET/organizations/{oid}/export · POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/downloadXuất tổ chức, chỉ owner: một zip gồm bản dump SQL và mọi tệp đính kèm, chạy dưới dạng job
Phương thứcPathMô tả
GET/projectsLiệt kê các dự án của bạn (limit ≤ 200)
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 (manager)
DELETE/projects/{id}Xóa một dự án (manager)
POST / DELETE/projects/{id}/pinGhim / bỏ ghim dự án trên danh sách dự án của bạn
POST/projects/{id}/transfer-organizationChuyển dự án sang một tổ chức khác — người gọi phải là Quản lý của dự án và là owner hoặc admin của tổ chức đích
POST/projects/{id}/slack/testGửi một tin nhắn thử đến luồng Slack của dự án (manager)
GET / POST/projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seedCác dự án trưng bày công khai: kiểm tra xem bạn có thể nhận một dự án không, nhận nó, khởi tạo dữ liệu cho nó (việc khởi tạo dữ liệu dành cho quản trị viên sản phẩm; người khác nhận 404)
GET/projects/{id}/audit-logĐọc audit log — lịch sử dự án cùng hoạt động theo từng story / từng epic qua surface=; quyền truy cập khác nhau theo surface, xem bên dưới
GET/projects/{id}/eventsLuồng sự kiện phân trang theo cursor (member) — xem Events

Tham số query của audit log: event_type= (một loại hoặc danh sách phân tách bằng dấu phẩy), limit= (mặc định 50, bị giới hạn ở 1000), before= (con trỏ keyset <ISO-8601>|<audit_id> — truyền next_cursor của trang trước), surface= (project_history, story_activities, epic_activities), target_id= (id của story/epic — bắt buộc khi surface=story_activities hoặc epic_activities). Quyền truy cập: log không lọc là (manager); surface=project_history là (viewer), với email thành viên bị che khi dự án ẩn chúng; story_activities / epic_activities mọi thành viên dự án đều đọc được, và đọc ẩn danh được trên dự án công khai với PII của tác nhân bị che.

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 (manager)
PUT/projects/{id}/memberships/{mid}Cập nhật vai trò (manager)
DELETE/projects/{id}/memberships/{mid}Loại bỏ một thành viên (manager)
POST/projects/{id}/memberships/bulk-role · …/memberships/bulk-removeĐổi vai trò hoặc loại bỏ nhiều thành viên cùng lúc (manager)
GET/projects/{id}/addable-members · POST /projects/{id}/members/add-existingCác thành viên tổ chức chưa có trong dự án / thêm một người mà không cần lời mời qua email — (manager) và là owner hoặc admin của tổ chức
POST/projects/{id}/members/joinMột owner hoặc admin của tổ chức tham gia một dự án trong tổ chức của mình với vai trò manager, hoặc tự thăng cấp lên manager (hành động Make me owner trên danh sách dự án)
GET / POST/projects/{id}/agent_keysLiệt kê (manager) / phát hành agent key — những người có vai trò nằm trong chính sách creator-roles của dự án; agent key không thể phát hành
PUT / DELETE/projects/{id}/agent_keys/{kid}Sửa tên, vai trò, hoặc gợi ý phản hồi của một key / thu hồi nó (manager)
GET/projects/{id}/agent_keys/onboardingGói onboarding: các prompt và tệp cấu hình cho các client agent phổ biến
GET/projects/{id}/agents · GET / PUT / DELETE /projects/{id}/agents/{aid}Các agent của dự án và hồ sơ của chúng (tên, chữ viết tắt, mô tả, màu); DELETE thu hồi agent cùng mọi key của nó — một manager hoặc người đã tạo agent
POST/projects/{id}/agents/{aid}/rotate-key · /projects/{id}/agents/{aid}/avatarXoay vòng key của một agent (giữ nguyên danh tính và lịch sử) / tải lên avatar của nó

Mọi thao tác ghi story cần vai trò member. Tạo một story với ngày lùi về quá khứ, nguồn gốc nhập (import_source / import_external_id), hoặc owner hay requester bên ngoài cần (manager).

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/{sid}/reject · /projects/{id}/stories/{sid}/restartTừ chối một story đã giao / đưa một story bị từ chối trở lại started (rejected là trạng thái cuối đối với /transitions)
POST/projects/{id}/stories/{sid}/archive · /projects/{id}/stories/{sid}/unarchiveLưu trữ / bỏ lưu trữ một story
POST/projects/{id}/stories/bulk_transitionChuyển đổi nhiều story (1–100) cùng lúc
POST/projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-moveLưu trữ, xóa, nhân bản, hoặc di chuyển (đến một bảng / vị trí) nhiều story
POST/projects/{id}/stories/bulk-unarchiveBỏ lưu trữ nhiều story
POST/projects/{id}/stories/{sid}/duplicateNhân bản một story
POST / DELETE/projects/{id}/stories/{sid}/epics · …/epics/{eid}Tư cách thành viên epic của story
GET/short-links/{code} · /story-referencesPhân giải một liên kết rút gọn /s/<code> thành story của nó / phân giải tối đa 100 tham chiếu — codes= (các mã liên kết rút gọn, phân tách bằng dấu phẩy) và ids= (các project_id:story_id, phân tách bằng dấu phẩy) — thành các story mà người gọi có thể đọc

Tham số truy vấn danh sách story: archived= (exclude mặc định / include / only — bộ lọc lưu trữ ba trạng thái; thay thế include_archived=true đã lỗi thời, nay là bí danh của archived=include), include_done=true (cho phép các story ở bảng Done bị đóng băng trên các iteration đã qua, mặc định bị loại trừ). Phân trang (cursor= / limit= / offset=) và tập trường rút gọn (fields=) tuân theo Phân trang và Phép chiếu trường.

Create (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. estimate là nhãn của giá trị trên thang đo, dưới dạng chuỗi ("3", "13"); một số JSON sẽ bị từ chối. 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), "force_state_change" (bool), và "expected_version" (số nguyên, version của story — việc lưu mô tả bị từ chối với 409 stale_write nếu mô tả đã thay đổi sau phiên bản đó). Trường cũ "expected_updated_at" (RFC 3339) đã lỗi thời và vẫn hoạt động thêm một bản phát hành: nếu gửi kèm mô tả và không có expected_version, việc lưu bị từ chối với 409 stale_write trừ khi giá trị bằng updated_at của story. Các thao tác ghi story cũng tôn trọng If-Match so với ETag của story; không khớp sẽ là 412 precondition_failed.

Transition (POST …/transitions): { "to": "<state>" }. 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>" }. 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). Xóa một tệp đính kèm hoặc tệp đính kèm dạng liên kết cần người đã tải lên hoặc (manager).

Phương thứcPathBody / ghi chú
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) } hoặc { comment_emoji }. GET nhận fields= (danh sách cho phép: comment_id, story_comment_id, story_id, comment_text, comment_emoji, member, created) cùng với 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}Tạo: { url, link_type?, title? }; cập nhật: { url, title? } — link_type ∈ relates_to, duplicates, blocks, is_blocked_by, pull_request, branch, other; các URL GitHub /pull/ và /tree/ được tự động gán loại
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}Tạo: { reviewer_id? / reviewer_agent_id?, comment? } — bỏ qua cả hai để tự gán cho mình. Cập nhật: { 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}{ label_id } — một nhãn dự án đã có; tạo nhãn bằng POST /projects/{id}/labels, hoặc gửi labels trong PUT của story
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}tải lên multipart — video ≤ 200 MB, PDF / Word / Excel ≤ 25 MB, hình ảnh / CSV / văn bản ≤ 10 MB; thao tác list là (viewer)
GET / POST/projects/{id}/stories/{sid}/link-attachments · DELETE …/link-attachments/{laid}Tệp đính kèm dạng liên kết — một URL bên ngoài được giữ cùng với các tệp đính kèm thay vì là một liên kết mã
GET/attachments/{token} · /api/v1/avatars/{token}Đọc một tệp đính kèm hoặc một avatar theo token — các URL mà API trả ra; không cần X-TrackerToken

Cùng cấu trúc như story, trừ máy trạng thái. member cho thao tác ghi và cho danh sách bình luận, owner, và follower; (viewer) cho danh sách epic, một epic đơn lẻ, và danh sách tệp đính kèm.

Phương thứcPathMô tả
GET / POST/projects/{id}/epics · GET / PUT / DELETE …/epics/{eid}Epic mang một tên, một mô tả Markdown, và một nhãn nền kết nối các story của nó
GET / POST / PUT / DELETE…/epics/{eid}/comments · …/comments/{cid}Bình luận trên epic
GET / POST / DELETE…/epics/{eid}/owners · …/followers (+ các biến thể /agents/{aid})Owner và follower, thành viên hoặc agent — owner của một epic được lan truyền xuống các story của nó
GET / POST / DELETE…/epics/{eid}/attachments (+ /json) · …/link-attachmentsTệp đính kèm, cùng giới hạn như story
GET/projects/{id}/analytics/epics · …/analytics/epics/{eid}Tiến độ theo từng epic: burnup, năng suất, sức khỏe, dự báo (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
GET / PUT / DELETE/projects/{id}/labels/{lid}Đọc / 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

Thao tác đọc mở cho mọi vai trò dự án, và cho người ẩn danh trên một dự án công khai.

Phương thứcPathMô tả
GET/projects/{id}/iterationsLiệt kê iteration (≤ 500 mỗi trang; mang một ETag và các header tiếp nối X-Tracker-Pagination-* khi bị cắt bớt)
GET/projects/{id}/iterations/{itid}Một iteration
GET/projects/{id}/iterations/first-previewKhung thời gian, velocity dự kiến và số story lấp từ Backlog của iteration mà một thao tác ghi khởi tạo sẽ tạo ra, hoặc của iteration hiện tại khi đã có (member)
POST/projects/{id}/iterationsTạo một iteration thủ công (manager)
DELETE/projects/{id}/iterations/{itid}Xóa một iteration (manager)
PUT/projects/{id}/iterations/{itid}/velocityGhi đè velocity của một iteration mà không thay đổi chiến lược của dự án (manager)
GET/projects/{id}/iterations/{itid}/done-storiesCác story đã được chấp nhận của một iteration đã đóng, có phân trang
Phương thứcPathMô tả
GET/projects/{id}/search?q=…Tìm kiếm mạnh mẽ — toàn văn + các qualifier facet / khoảng ngày / người (DSL kiểu GitHub); trả về { results, total, limit, offset }. query là bí danh của q; limit= (mặc định 50, tối đa 1000) / offset= để phân trang; sort= sắp xếp theo relevance (mặc định), created, created_asc, state, hoặc updated. (viewer) — xem Hướng dẫn
GET/projects/{id}/metrics/{velocity,burndown,story-types,contributors}Các chuỗi dữ liệu của trang Metrics (viewer); số liệu epic nằm dưới /analytics/epics ở trên
GET/projects/{id}/backlog/groupingCác nhóm iteration được dự báo của Backlog (viewer)
GET / PUT/projects/{id}/preferencesTùy chọn board của bạn cho dự án này — mọi vai trò dự án, chỉ hàng dữ liệu của chính bạn
Phương thứcPathMô tả
GET/projects/{id}/eventsLuồng sự kiện phân trang theo cursor (member) — viewer nhận 403

Các tham số truy vấn: since_id=<event_id> (since là bí danh cũ hơn; since_id được ưu tiên khi gửi cả hai), types=story.created,story.transitioned,comment.added,…, limit= (mặc định 100, ≤ 500), cursor=. Phản hồi là { items, next_since_id, next_cursor }: lưu next_since_id và truyền lại nó làm since_id để tiếp tục; next_cursor là null ở trang cuối.

Luồng thông báo hợp nhất trong ứng dụng: các dòng thông báo hạng nhất (yêu cầu review, hoạt động của story, lời mời, …) được gộp với hộp thư @-nhắc đến thành một luồng duy nhất, mới nhất trước. Id trong luồng mang tiền tố nguồn (nt-… / sc-… / ec-…). Phiên thành viên và khóa ea_user_* đọc các dòng phía thành viên; khóa ea_agent_* đọc các dòng phía agent.

Phương thứcPathMô tả
GET/me/notificationsLuồng thông báo của bạn. Bộ lọc: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); phân trang bằng cursor= / limit=
GET/me/notifications/unread-countTổng chưa đọc — { unread_count, by_category: { mentions, reviews, stories, invitations } }
POST/me/notifications/read-allĐánh dấu tất cả là đã đọc; trả về bộ đếm mới
POST/me/notifications/{id}/ackĐánh dấu một mục là đã đọc (idempotent)
POST/me/notifications/{id}/acceptChấp nhận lời mời vào dự án / tổ chức ngay từ luồng (chỉ token thành viên)
POST/me/notifications/{id}/declineTừ chối lời mời vào dự án / tổ chức (chỉ token thành viên)
GET/me/notifications/resolve-invite?token=…Đối chiếu token lời mời gửi qua email với id thông báo của bạn — { "id": "nt-…" } hoặc { "id": null }
GET/me/notifications/streamPush trực tiếp — Server-Sent Events (text/event-stream); xem bên dưới

Endpoint stream không phải endpoint JSON nên không có trong đặc tả OpenAPI: nó giữ kết nối mở và phát một frame không có payload ({"type":"notification","kind":…}) mỗi khi có nội dung mới, báo cho client tải lại luồng. Kết nối bị ngắt phía máy chủ sau 45 phút — hãy kết nối lại và xác thực lại. Chỉ dành cho phiên thành viên và khóa ea_user_*; khóa ea_agent_* nhận 403.

Phương thứcPathMô tả
POST/projects/{id}/importCác nguồn từ tệp: source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. Multipart file=. Đồng bộ — trả lời bằng các bộ đếm kết quả.
POST/projects/{id}/import/jsonThân JSON; source=github không cần tệp — owner, repo, token tùy chọn, và các cờ opt-in include_pull_requests / include_milestones / include_releases / include_dependencies, và include_comments (mặc định true); các nguồn từ tệp gửi file_base64. Bất đồng bộ: trả về 202 { import_id, status }. Máy chủ lấy dữ liệu qua API GraphQL của GitHub, vốn từ chối lời gọi ẩn danh, nên luôn có một token đến được GitHub — token của bạn, hoặc token dùng chung của bản triển khai. Xem Hướng dẫn.
GET/projects/{id}/imports/{import_id}Poll một job: status chạy theo pending → fetching → writing → done | failed, với progress_current / progress_total trong lúc lấy dữ liệu và các bộ đếm kết quả khi done

Mỗi dự án chỉ chạy một lần nhập JSON tại một thời điểm; một POST …/import/json thứ hai trong khi một lần nhập đang chạy sẽ nhận 409 import_already_running. Với check_unpointed_estimates: true (nguồn tệp; bị bỏ qua với github), một tệp chứa ước lượng của bug hoặc chore mà dự án không chấm điểm sẽ bị từ chối bằng 409 import_unpointed_estimates kèm details.count trước khi bất kỳ job nào bắt đầu; không có cờ này, lần nhập sẽ bỏ các ước lượng đó và báo { code: "estimates_unpointed_dropped", count } trong warnings của kết quả. dry_run: true (trong thân JSON hoặc dry_run=true multipart) xem trước bất kỳ nguồn nào: phân tích, đối chiếu, khử trùng lặp, trả về cùng các bộ đếm { imported, skipped, errors, unmatched }, rồi hoàn tác — không có gì được ghi. Giới hạn: một tệp 10 MiB (400 import_too_large) và 5.000 story mỗi lần nhập với các nguồn theo tệp (400 import_too_many_records); không có gì được ghi. Một request body vượt quá 16 MiB bị từ chối sớm hơn với 413 request_too_large. Nguồn GitHub không có trần — nó ghi theo từng khối thay vì một giao dịch duy nhất. Nhập lại là idempotent theo id nguồn — các hàng đã được nhập bị bỏ qua, không nhân đôi.

Phương thứcPathMô tả
GET/projects/{id}/export/formatsCác định dạng đã đăng ký: { id, name, content_type, drops, includes_archived }. Mọi vai trò dự án.
GET/projects/{id}/export/{format}Tải xuống một định dạng (manager). Trao đổi: eat (đầy đủ độ trung thực), jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json; tài liệu: pdf, docx.
GET/projects/{id}/export/attachmentsMọi tệp đính kèm dưới dạng một zip có thể duyệt (tệp giữ tên gốc; manifest JSON + CSV) (manager).

Xuất tài liệu (pdf, docx) nhận thêm các tham số truy vấn: page_size= (letter mặc định / a4 / legal / folio), from= / to= (giới hạn cửa sổ story — RFC 3339 hoặc chỉ YYYY-MM-DD; một story nằm trong khoảng khi created hoặc completed_at của nó rơi vào đó), include_icebox= / include_backlog= (cả hai mặc định là false, nên bản xuất để chia sẻ chỉ hiển thị công việc đã lên lịch / đang thực hiện). Các định dạng CSV trao đổi bỏ qua chúng.

Phương thứcPathMô tả
GET / POST/projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/healthLiệt kê các snapshot, chụp một snapshot ngay, đọc một snapshot, và bản tóm tắt sức khỏe lưu giữ
POST/projects/{id}/restores · POST …/restores/partial · GET …/restores/{restore_id}Khôi phục toàn bộ một snapshot, hoặc các bảng được chọn từ đó, và poll quá trình khôi phục

Các POST nằm ở bậc giới hạn tốc độ sensitive (bên dưới).

East Agile Tracker là một nhà cung cấp OAuth 2.1 cho các client MCP. Một client khám phá nó tại /.well-known/oauth-authorization-server và /.well-known/oauth-protected-resource/mcp, đưa bạn đến /oauth/authorize (trang đồng ý), đổi mã tại /oauth/token, rồi giao tiếp MCP tại /mcp bằng token ea_mcp_* nhận được. Các quyền cấp được liệt kê và thu hồi tại /me/oauth_grants. Các endpoint của nhà cung cấp có bậc giới hạn tốc độ riêng.

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. Key có phạm vi theo thông tin xác thực đã gửi nó. Không áp dụng cho GET/HEAD/OPTIONS, /openapi.json và /docs, /api/auth/*, /mcp, mọi path chứa /attachments, hoặc mọi request multipart/*; một request không có thông tin xác thực không bao giờ được cache. Các phản hồi dừng lại trước khi có câu trả lời nghiệp vụ không bao giờ được cache — 401, 403, 404, 429, và mọi 5xx — nên một lần thử lại sau bất kỳ phản hồi nào trong số đó sẽ đến được handler; 400, 409, 412, và 422 là câu trả lời của nghiệp vụ và được phát lại như một thành công.

Các endpoint danh sách chấp nhận cursor=<opaque> và limit=<n>. Khi được đặt, phản hồi là { "items": [...], "next_cursor": "<str|null>" }; truyền next_cursor trở lại để sang trang. Trần của limit tùy theo endpoint: 200 cho story, bình luận, và dự án; 500 cho sự kiện; 1000 cho audit log. Tìm kiếm phân trang bằng limit (≤ 1000) và offset thay vì cursor và trả về { results, total, limit, offset }.

Một danh sách thường (không có cursor/limit) phải cắt bớt phản hồi sẽ báo điều đó qua các header — X-Tracker-Pagination-Truncated, X-Tracker-Pagination-Limit, X-Tracker-Pagination-Offset, và X-Tracker-Pagination-Next-Offset; truyền giá trị cuối cùng trở lại làm offset= cho trang tiếp theo. Không có header tổng số đếm.

Các danh sách story, bình luận, và dự án chấp nhận fields= (cách nhau bằng dấu phẩy) để chỉ trả về các trường cụ thể. Id của tài nguyên luôn được bao gồm (story_id, story_comment_id và comment_id, project_id); 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ó 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áicodeKhi nào
400invalid_parameterđầu vào sai; thông điệp trong error. Kiểm tra trường (trống/độ dài/null-byte/email) thêm details.fields và details.constraint; chỉ lỗi bad request đơn thuần mới không có details
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
400mã nghiệp vụmột lời từ chối riêng của route với mã riêng và không có details — ví dụ unsupported_export_format, import_too_large, import_unknown_source
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
409stale_write · import_already_running · import_unpointed_estimatesmô tả đã thay đổi sau expected_version của bạn (hoặc expected_updated_at không còn khớp) · một lần nhập đang chạy · tệp có ước lượng của bug hoặc chore mà dự án không chấm điểm (details.count)
412precondition_failedIf-Match không khớp với ETag hiện tại của tài nguyên; details mang expected và current
413request_too_largebody vượt quá giới hạn kích thước của route
422invalid_transitionbước di chuyển trạng thái không hợp lệ; details mang { from, to, allowed }
429rate_limitedquá nhiều request từ IP này trên một route có giới hạn tốc độ; header Retry-After
500internal_errorlỗi máy chủ — thông điệp chung; an toàn để thử lại
502upstream_errormột dịch vụ mà route phụ thuộc vào (ví dụ GitHub) bị lỗi
503not_configuredbản triển khai thiếu tích hợp mà route này cần (SMS, lưu trữ đối tượng, …)

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 IP của client, trên một số ít route; lưu lượng API đã xác thực ở những nơi khác không bị giới hạn tốc độ. Giá trị mặc định (mỗi cặp là tốc độ duy trì và burst, nhà vận hành có thể điều chỉnh):

  • Auth — /api/auth/*: 0.5 req/s, burst 20.
  • OAuth provider — /oauth/*: 1 req/s, burst 60.
  • Public — /api/contact: 0.2 req/s, burst 10.
  • Feedback — /api/v1/feedback và /api/v1/feedback/with-screenshot: ba bậc chồng lên nhau — một lần gửi mỗi 15 giây, 10 lần mỗi giờ, 36 lần mỗi ngày.
  • Avatars — chuyển hướng avatar không cần xác thực: 20 req/s, burst 200.
  • Sensitive — các POST sao lưu và khôi phục: ~0.002 req/s, burst 5.

Một giới hạn bị vượt quá sẽ trả về 429 với một header Retry-After và phong bì lỗi JSON tiêu chuẩn, code: "rate_limited".