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

Hướng dẫn API

Bắt đầu với REST API của East Agile Tracker: khóa người dùng và khóa agent, tạo và chuyển story, ghi idempotent, tìm kiếm, sự kiện và phân trang.

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.

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 → Agent. 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 → API Keys → Connected apps.

Hộp thoại chỉ hiện một lần sau khi tạo khóa API cá nhân trong Cài đặt tài khoản, khóa được che trong ảnh chụp này

Biểu mẫu tạo khóa trong tab Agent với tên và vai trò member đã chọn, bên dưới hướng dẫn thiết lập

Sự khác biệt giữa hai loại bạn tự phát hành:

User keyAgent key
Phạm viTất cả các dự án của bạnMột dự án cụ thể
Danh tính trong audit logTên của bạnTê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ồiThu hồi một key; bạn vẫn giữ quyền truy cập qua các key/phiên khácThu 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 choTự động hóa cá nhân, scriptCá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.

Lấy các dự án của bạn:

Terminal window
curl https://api.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:

Terminal window
curl https://api.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.

Terminal window
curl -X POST https://api.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à các giá trị mặc định của iteration mà máy chủ đã áp dụng (iteration_start_day, initial_velocity, iteration_length_weeks); GET /projects/{id} trả về toàn bộ cài đặt.

Terminal window
curl -X POST https://api.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.

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:

Terminal window
curl -X POST https://api.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, và endpoint này cũng từ chối to: "rejected". Từ chối một story đã được giao bằng POST …/stories/{sid}/reject; đưa một story bị từ chối trở lại làm việc bằng POST …/stories/{sid}/restart, thao tác này hoạt động khi story còn nằm trong iteration hiện tại.

Terminal window
curl -X POST https://api.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.

Các endpoint ghi chấp nhận một header Idempotency-Key (trừ các bản tải lên tệp đính kèm). Thử lại cùng một key với cùng một body trong vòng 24 giờ, 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:

Terminal window
curl -X POST https://api.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. Một phản hồi 5xx, 401, 403, 404, hoặc 429 không bao giờ được cache, nên thử lại sau một phản hồi như vậy sẽ chạy lại request.

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.

Terminal window
curl -X POST https://api.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"
}'

Đố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:

Terminal window
curl "https://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/events?since_id=$LAST_EVENT_ID&types=story.created,story.transitioned,comment.added" \
-H "X-TrackerToken: $TRACKER_TOKEN"

Phản hồi là { items, next_since_id, next_cursor }: mỗi sự kiện mang tác nhân, tài nguyên, và sự thay đổi. Lưu next_since_id và truyền lại nó làm since_id ở lần poll tiếp theo để tiếp tục từ nơi bạn dừng lại (since vẫn được chấp nhận như một bí danh cũ hơn). 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.

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.

Terminal window
curl -G "https://api.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 khi truy vấn có văn bản tự do, và theo thứ tự board trong trường hợp còn lại:

{ "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.

  • 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.
QualifierVí 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:>3giá trị hoặc khoảng ước lượng
iteration:iteration:42id của iteration
created: updated: started: completed: release:created:2026-05-01..2026-06-01 · updated:>2026-06-01mộ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:@memột người theo tên hoặc email — thành viên và agent, kể cả mention:; @me là bạn (với một agent key, là thành viên đã tạo key đó)
has:blockerhas:blockercó một blocker đang mở
is:is:unestimated · is:icebox · is:backlog · is:blockedmộ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ị.

payment crash full text "payment" AND "crash"
"exact phrase" a phrase
type:bug,chore state:started bugs or chores that are started
owner:@me -label:wontfix mine, excluding the wontfix label
points:3..8 created:2026-05-01..2026-05-31 estimated 3-8, created in May
follower:tomas has:blocker tomas follows it and it's blocked
is:backlog updated:>2026-06-01 backlog items touched since Jun 1

Cù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.

Đặc tả OpenAPI 3 trực tiếp nằm tại:

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

Swagger 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 đó.

Nếu bạn đang viết script cho một cuộc di chuyển hàng loạt:

Terminal window
curl -X POST https://api.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:

Terminal window
curl -X POST https://api.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. Một tệp nhập bị giới hạn ở 10 MiB và 5.000 story (400 import_too_large / import_too_many_records, không ghi gì); một lần nhập từ GitHub không có trần số story. 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.

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 cần vai trò manager:

Terminal window
# Các định dạng xuất đã đăng ký: { id, name, content_type, drops, includes_archived }
curl https://api.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://api.eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/eat \
-H "X-TrackerToken: $TRACKER_TOKEN" -o project-export.csv

Cá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.

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 đó.

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 audit log; tìm kiếm phân trang bằng limit (≤ 1000) và offset. 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.