API của East Agile Tracker được thiết kế cho agent ngang bằng với cho con người. Mọi thứ bạn có thể làm trong giao diện, bạn đều có thể làm qua API — và một vài thứ mà giao diện không phơi bày cũng có ở đó.
Hướng dẫn này đưa bạn từ con số không đến “viết script cho backlog của bạn” trong chưa đầy mười phút. Để có tham chiếu endpoint đầy đủ, xem Đặc tả API.
Ba loại thông tin xác thực
Phần tiêu đề “Ba loại thông tin xác thực”Bạn xác thực bằng một key trong header X-TrackerToken. Có hai loại key bạn tự phát hành, và một loại thứ ba mà một client MCP lấy thay cho bạn:
- User key (
ea_user_…) — Hành động với tư cách bạn. Tạo chúng trong Account Settings → API Keys. Dùng những key này cho các script cá nhân, công cụ CLI, tích hợp. - Agent key (
ea_agent_…) — Hành động với tư cách một agent có tên trong một dự án. Tạo chúng trong Project Settings → Agents. Dùng những key này cho các AI agent — Claude Code, Codex, của riêng bạn — vốn nên tham gia vào dự án như những đồng đội có tên. - MCP token (
ea_mcp_…) — Access token OAuth 2.1 được cấp cho một client MCP (Claude, một IDE) sau khi bạn phê duyệt nó trên trang đồng ý. Chúng hành động với tư cách bạn, và bạn có thể thu hồi chúng dưới Account Settings → Connected apps.


Sự khác biệt giữa hai loại bạn tự phát hành:
| User key | Agent key | |
|---|---|---|
| Phạm vi | Tất cả các dự án của bạn | Một dự án cụ thể |
| Danh tính trong audit log | Tên của bạn | Tên của agent |
| Vai trò | Vai trò của bạn trong mỗi dự án | Được đặt khi tạo key (viewer, member, hoặc manager — không bao giờ cao hơn vai trò của chính thành viên phát hành) |
| Thu hồi | Thu hồi một key; bạn vẫn giữ quyền truy cập qua các key/phiên khác | Thu hồi hoặc xoay vòng một key; agent mất quyền truy cập ngay lập tức |
| Phù hợp nhất cho | Tự động hóa cá nhân, script | Các AI agent cần được phân biệt với bạn trong lịch sử |
Authorization: Bearer … cũng hoạt động nếu bạn thích kiểu header đó hơn.
Chào, API
Phần tiêu đề “Chào, API”Lấy các dự án của bạn:
curl https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: $TRACKER_TOKEN"Hoặc với một agent key, liệt kê dự án mà nó được giới hạn phạm vi vào:
curl https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: ea_agent_xxxxx"API là JSON, kiểu REST, được phiên bản hóa tại /api/v1/. Cùng cấu trúc cho con người và agent.
Tạo một dự án
Phần tiêu đề “Tạo một dự án”curl -X POST https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Onboarding redesign", "description": "Q3 redesign of new-user onboarding", "iteration_length_weeks": 1 }'Phản hồi bao gồm project_id và bất kỳ giá trị mặc định nào mà máy chủ đã áp dụng (thang ước lượng, done state, v.v.).
Tạo một story
Phần tiêu đề “Tạo một story”curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Add OAuth login for Google", "description": "## Acceptance\n- Google button on /login\n- Redirect back to original URL", "story_type": "feature", "estimate": "3", "labels": ["auth"] }'estimate là nhãn của giá trị trên thang đo, dưới dạng chuỗi — "3", hoặc "13" trên thang Fibonacci — vì nó phải khớp với một điểm trên thang đo của dự án. Một số JSON sẽ bị từ chối.
Di chuyển một story qua vòng đời
Phần tiêu đề “Di chuyển một story qua vòng đời”Endpoint chuyển đổi xác thực bước di chuyển được yêu cầu và trả về các trạng thái tiếp theo được phép khi xảy ra lỗi:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/transitions \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "to": "started" }'Trường là to (không phải to_state). Nếu bước di chuyển không hợp lệ — chẳng hạn bạn cố nhảy từ unstarted thẳng đến accepted — phản hồi là 422 invalid_transition với chi tiết lỗi có cấu trúc:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`", "details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] }}Đây là một trong những điều nhỏ khiến API thân thiện với agent: một agent có thể đọc details.allowed và chọn bước di chuyển tiếp theo đúng đắn mà không cần phải trích xuất từ văn xuôi.
rejected là trạng thái cuối đối với endpoint chuyển đổi. Để đưa một story bị từ chối trở lại làm việc, dùng POST …/stories/{sid}/restart; POST …/stories/{sid}/reject là dạng động từ để từ chối một story đã được giao.
Bình luận trên một story
Phần tiêu đề “Bình luận trên một story”curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/comments \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "Investigation done. Picking this up." }'Bình luận được quy cho bất kỳ ai sở hữu API key — nếu là một agent key, tác giả của bình luận là agent.
Ghi bất biến (Idempotent)
Phần tiêu đề “Ghi bất biến (Idempotent)”Mọi endpoint ghi đều chấp nhận một header Idempotency-Key. Thử lại cùng một key với cùng một body, nhận lại cùng một phản hồi. Thử lại cùng một key với một body khác, nhận một 409 idempotency_conflict:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "name": "Refactor auth middleware", "story_type": "chore" }'Điều này rất quan trọng đối với các agent trong vòng lặp thử lại — gặp sự cố giữa chừng một thao tác ghi, thử lại với cùng key, không có story trùng lặp.
Chuyển đổi hàng loạt
Phần tiêu đề “Chuyển đổi hàng loạt”Di chuyển nhiều story cùng lúc. Mỗi story được đánh giá độc lập; một bước di chuyển không hợp lệ không làm hỏng các bước còn lại.
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/bulk_transition \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "story_ids": [101, 102, 103], "to": "delivered" }'Theo dõi luồng sự kiện
Phần tiêu đề “Theo dõi luồng sự kiện”Đối với các agent muốn phản ứng với những gì con người làm, hãy poll endpoint events:
curl "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/events?since=$LAST_CURSOR&types=story.created,story.transitioned,comment.added" \ -H "X-TrackerToken: $TRACKER_TOKEN"Phản hồi là một luồng sự kiện được phân trang theo cursor với tác nhân, tài nguyên, và sự thay đổi. Mỗi sự kiện có một ID; truyền ID cuối cùng bạn đã thấy làm since để tiếp tục từ nơi bạn dừng lại. Không webhook, không trích xuất, không bỏ lỡ sự kiện. Luồng này cần vai trò member — một viewer nhận 403.
Tìm kiếm
Phần tiêu đề “Tìm kiếm”GET /projects/{id}/search?q=<query> chạy một phép tìm kiếm toàn văn + có cấu trúc mạnh mẽ trên các story của dự án. Ngôn ngữ truy vấn được mô phỏng theo các qualifier tìm kiếm issue của GitHub — nên cú pháp mà bạn (hoặc một AI agent) đã biết từ GitHub phần lớn đều dùng được ở đây.
curl -G "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/search" \ -H "X-TrackerToken: $TRACKER_TOKEN" \ --data-urlencode 'q=payment crash type:bug,chore owner:@me created:>2026-05-01'Phản hồi là một phong bì JSON, các story được xếp hạng theo mức độ liên quan:
{ "results": [ /* canonical story objects */ ], "total": 42, "limit": 50, "offset": 0 }total là tổng số kết quả khớp, không phải kích thước trang. Phân trang bằng limit (mặc định 50, tối đa 1000) và offset; sắp xếp bằng sort=relevance (mặc định), created, created_asc, updated, hoặc state.
Ngữ pháp
Phần tiêu đề “Ngữ pháp”- Văn bản tự do khớp với tiêu đề, mã tham chiếu, và mô tả của story (toàn văn, có tách gốc từ và xếp hạng). Bọc một cụm từ chính xác trong
"dấu ngoặc kép". - Qualifier có dạng
field:value. Phân tách các lựa chọn thay thế bằng dấu phẩy (OR trong một trường):type:bug,chore. Phân tách các qualifier bằng khoảng trắng (AND giữa chúng). - Phủ định bất kỳ thuật ngữ hay qualifier nào bằng dấu
-ở đầu:-label:wontfix. - Khoảng cho ngày và điểm: bao gồm hai đầu
a..b, hoặc mở một đầu>x/<x.
Qualifier
Phần tiêu đề “Qualifier”| Qualifier | Ví dụ | Khớp với |
|---|---|---|
type: | type:bug,chore | (các) loại story |
state: | state:started,finished | (các) trạng thái quy trình |
label: | label:"my label" | một nhãn |
epic: | epic:"Checkout" | các story trong một epic |
priority: | priority:p1 | độ ưu tiên |
points: | points:3 · points:1..5 · points:>3 | giá trị hoặc khoảng ước lượng |
iteration: | iteration:42 | id của iteration |
created: updated: started: completed: release: | created:2026-05-01..2026-06-01 · updated:>2026-06-01 | một ngày hoặc một khoảng (độ chi tiết theo ngày); release: là ngày phát hành của story |
owner: requester: follower: reviewer: commenter: mention: | owner:claire · owner:@me | một người theo tên hoặc email — thành viên và agent, kể cả mention:; @me là bạn |
has:blocker | has:blocker | có một blocker đang mở |
is: | is:unestimated · is:icebox · is:backlog · is:blocked | một cờ |
mywork: là bí danh của owner: — mywork:me là owner:@me. Qualifier scheduled: cũ đã bị loại bỏ và bị bỏ qua âm thầm; hãy dùng release:.
OR bằng dấu phẩy (type:bug,chore) áp dụng cho các qualifier facet; các qualifier về người (owner: requester: follower: reviewer: commenter: mention:) chỉ nhận một giá trị.
Ví dụ
Phần tiêu đề “Ví dụ”payment crash full text "payment" AND "crash""exact phrase" a phrasetype:bug,chore state:started bugs or chores that are startedowner:@me -label:wontfix mine, excluding the wontfix labelpoints:3..8 created:2026-05-01..2026-06-01 estimated 3-8, created in Mayfollower:tomas has:blocker tomas follows it and it's blockedis:backlog updated:>2026-06-01 backlog items touched since Jun 1Cùng một chuỗi truy vấn điều khiển ô tìm kiếm của board (nơi mở một cột kết quả trực tiếp) và API này — một ngữ pháp chung cho cả con người lẫn agent. Tìm kiếm trong nội dung bình luận, task, và blocker đang nằm trong lộ trình; hiện tại văn bản tự do bao gồm tiêu đề, mã tham chiếu, và mô tả của chính story.
Khám phá API
Phần tiêu đề “Khám phá API”Đặc tả OpenAPI 3 trực tiếp nằm tại:
https://api.eastagiletracker.com/api/v1/openapi.jsonSwagger UI nằm tại:
https://api.eastagiletracker.com/api/v1/docs//openapi.json và /docs không cần xác thực — một agent có thể đọc hợp đồng trước khi nó có key. Khi đã giữ một key, /api/v1/meta (vốn yêu cầu một key hợp lệ) trả về danh tính của nó và đồ thị chuyển đổi theo từng loại story; các lượt tra cứu dữ liệu tham chiếu (/story_types, /story_states, /effort_scales, /priority_scales) cũng không cần xác thực. Cùng nhau, chúng cho phép agent trả lời “tôi có thể làm gì ở đây?” mà không cần thử-và-sai với các lỗi 403.
File openapi.json được phục vụ mang theo schema request body cho các endpoint ghi, bao gồm maxLength của từng trường, để client có thể kiểm tra hợp lệ trước khi gửi. Đặc tả tóm tắt cùng các cấu trúc đó.
Điều khiển WebSocket
Phần tiêu đề “Điều khiển WebSocket”Đối với tự động hóa tương tác — điều khiển một phiên trình duyệt đã đăng nhập từ một script, hoặc điều khiển từ xa giao diện cho các bài hướng dẫn — có một kênh WebSocket:
const ws = new WebSocket('wss://eastagiletracker.com/ws/control?token=SESSION_JWT')ws.send(JSON.stringify({ action: 'get_state', id: 'req-1' }))token là JWT của phiên trình duyệt, không phải một API key — một key ea_user_* hoặc ea_agent_* bị từ chối trước khi nâng cấp kết nối. Hầu hết người dùng không bao giờ cần đến nó; nó ở đó cho các trường hợp mà REST chưa đủ.
Nhập từ một tracker khác
Phần tiêu đề “Nhập từ một tracker khác”Nếu bạn đang viết script cho một cuộc di chuyển hàng loạt:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/import \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -F "source=pivotal" \ -F "file=@pivotal_export.csv"Các nguồn từ tệp được hỗ trợ: pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat (bản xuất của chính East Agile Tracker — định dạng khứ hồi). Endpoint multipart chạy đồng bộ và trả lời bằng các bộ đếm kết quả.
GitHub nhập từ API thay vì từ một tệp, qua endpoint JSON — không có file, chỉ cần tọa độ của repository:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/import/json \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "source": "github", "owner": "octocat", "repo": "hello-world", "token": "ghp_…", "include_pull_requests": false, "include_milestones": false, "include_releases": false, "include_dependencies": false }'Endpoint JSON là bất đồng bộ: nó trả lời 202 với { "import_id", "status" } và bạn poll GET /projects/{id}/imports/{import_id} cho đến khi job đạt done hoặc failed. Mỗi dự án chỉ chạy một lần nhập tại một thời điểm — một lời gọi thứ hai trong khi một lần nhập đang chạy sẽ nhận 409 import_already_running. Toàn bộ vòng lặp, cùng các trường tiến độ của job, nằm ở Tạo dự án từ một repo GitHub.
token là tùy chọn trên đường truyền, nhưng bản thân việc lấy dữ liệu luôn xác thực — nó chạy trên API GraphQL của GitHub, nơi không có bậc ẩn danh. Bỏ token đi và máy chủ sẽ thay bằng token nền tảng: chỉ repo công khai, dùng chung cho mọi lời gọi, và bị từ chối với import_github_shared_quota_low khi ngân sách GraphQL của nó rơi xuống dưới 500 điểm. Repo riêng tư, hoặc một bản triển khai không cấu hình token nền tảng (import_github_no_token), đòi hỏi token của bạn. Dù token nào chạy đi nữa, nó chỉ được dùng cho các lời gọi lên GitHub và không bao giờ được lưu trữ hay trả lại. Chi tiết đầy đủ, gồm cả trần REST 60 yêu cầu khi không xác thực của GitHub, nằm ở Tạo dự án từ một repo GitHub.
Xem trước dry-run. Thêm "dry_run": true (JSON) hoặc -F "dry_run=true" (multipart) cho bất kỳ nguồn nào. Việc nhập sẽ phân tích, đối chiếu, và khử trùng lặp y hệt một lần chạy thật, trả về cùng các bộ đếm kết quả (imported, skipped, errors, unmatched), rồi hoàn tác tất cả — không có gì được ghi. Trên endpoint JSON, các bộ đếm đến trên job được poll, dù là dry run hay không.
Giới hạn. Thân của bản tải lên bị giới hạn ở 10 MiB, và một lần nhập ở 5.000 story; vượt quá một trong hai sẽ là 400 mà không ghi gì. Nhập lại một tệp là an toàn — các hàng đã được nhập (đối chiếu theo id nguồn) sẽ bị bỏ qua, không nhân đôi.
Xuất một dự án
Phần tiêu đề “Xuất một dự án”Mọi vai trò dự án đều có thể liệt kê các định dạng; tải xuống một định dạng chỉ dành cho owner:
# Các định dạng xuất đã đăng ký: { id, name, content_type, drops, includes_archived }curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/formats \ -H "X-TrackerToken: $TRACKER_TOKEN"
# Tải xuống một định dạng (eat là CSV khứ hồi đầy đủ độ trung thực)curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/eat \ -H "X-TrackerToken: $TRACKER_TOKEN" -o project-export.csvCác id định dạng trao đổi: eat, jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json, cùng các định dạng tài liệu pdf và docx. Mọi tệp đính kèm có thể tải xuống dưới dạng một zip từ GET /projects/{id}/export/attachments.
Định dạng lỗi
Phần tiêu đề “Định dạng lỗi”Mọi lỗi đều là JSON với tối thiểu:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`"}Nhiều phản hồi lỗi cũng bao gồm một đối tượng details — details.fields (một mảng tên các trường vi phạm) trên validation_failed, và details.allowed (cùng với from/to) trên 422 invalid_transition. Hãy dùng chúng. Một 429 rate_limited mang header Retry-After trong cùng phong bì JSON đó.
Phân trang
Phần tiêu đề “Phân trang”Các endpoint danh sách chấp nhận limit và cursor. Cursor là không trong suốt (opaque); truyền next_cursor từ phản hồi trước. 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 tìm kiếm và audit log. Một danh sách thường (không dùng cursor) phải cắt bớt phản hồi sẽ báo điều đó qua các header: X-Tracker-Pagination-Truncated, -Limit, -Offset, và -Next-Offset, giá trị cuối bạn truyền lại làm offset= cho trang tiếp theo. Không có header tổng số đếm.
Tiếp theo là gì
Phần tiêu đề “Tiếp theo là gì”- Đặc tả API — Mọi endpoint, mọi verb, mọi cấu trúc.
- Hướng dẫn vận hành → Agent — Phía giao diện: phát hành agent key, đặt tên agent, thu hồi.
- Giới thiệu — Các khái niệm đằng sau API: story, trạng thái, iteration, velocity, agent.