콘텐츠로 이동

API 명세

완전한 REST 엔드포인트 레퍼런스. 튜토리얼과 예제는 API 가이드를 참고하세요.

프로젝트 멤버가 웹 UI에서 할 수 있는 모든 것을 여기서 사용할 수 있습니다 — SPA는 이 동일한 API를 사용합니다. owner 역할을 요구하는 작업은 (owner)로 표시됩니다. 그 외 모든 것은 프로젝트 멤버십만 필요합니다(또는 (viewer)로 표시된 읽기의 경우 모든 접근 수준).

https://eastagiletracker.com/api/v1

https://api.eastagiletracker.com/api/v1도 동일한 API를 제공합니다. multipart를 받는 몇몇 파일 업로드 엔드포인트를 제외하고, 모든 요청과 응답은 JSON입니다.

모든 인증된 요청은 다음 중 하나로 API 키를 보냅니다:

  • X-TrackerToken: <key>
  • Authorization: Bearer <key>

User key는 ea_user_로 시작합니다. Agent key는 ea_agent_로 시작합니다. API 가이드 → 두 종류의 키를 참고하세요.

인증되지 않은 엔드포인트: /openapi.json, /docs, /auth/* 엔드포인트, 그리고 참조 데이터 조회(/story_types, /story_states, /effort_scales, …). /meta인증됨입니다 — 유효한 키라면 작동하지만 프로젝트 범위가 아닙니다(프로젝트에 묶인 에이전트 키도 도달합니다).

세 수준이 프로젝트 범위 엔드포인트를 통제합니다:

LevelWho passesTypical operations
viewerviewer, member, owner읽기(스토리 목록/조회, 검색, 분석)
membermember, owner모든 작업 항목 쓰기(스토리, 작업, 댓글, …)
ownerowner only프로젝트 설정, 멤버십 관리, 에이전트 키, 삭제, 임포트, 감사 로그

비멤버는 프로젝트 경로에서 403이 아니라 404 unfound_resource를 받으므로, 프로젝트 ID를 열거할 수 없습니다.

MethodPathDescription
GET/openapi.json실시간 OpenAPI 3 스펙. 인증되지 않음.
GET/docsSwagger UI. 인증되지 않음.
GET/meta호출자 정체성(auth.kind/key_id/agent_id/project_id) + 스토리 유형 전환 그래프. 인증됨(유효한 키라면; 프로젝트 범위 아님). 이것을 먼저 호출하세요.

이것들은 호출자에 대해 작동하며 유효한 키만 필요합니다(프로젝트 역할 없음).

MethodPathDescription
POST/auth/register새 계정 등록
POST/auth/login로그인, 세션 토큰 반환
POST/auth/logout로그아웃
POST/auth/forgot-password비밀번호 재설정 이메일 요청
POST/auth/reset-password재설정 토큰으로 새 비밀번호 설정
GET/auth/verify-email이메일 주소 인증
POST/auth/accept-invite/lookup초대 토큰 → 이메일 해석(인증되지 않음)
POST/auth/accept-invite프로젝트 초대 수락(인증 후)
GET/me현재 사용자 프로필
PUT/me프로필 업데이트
DELETE/me계정 삭제
PUT/me/password비밀번호 변경
PUT/me/settings설정 업데이트(테마, 알림 환경 설정)
POST/me/avatar아바타 업로드(multipart)
POST/me/api-token/regenerateAPI 토큰 회전 — 기존 세션/키 무효화
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}사용자(ea_user_) API 키 관리
GET/me/activity모든 프로젝트에 걸친 여러분의 활동
GET/me/data-export여러분 데이터의 GDPR 자체 익스포트
GET/me/consent · POST /me/consent동의 읽기 / 기록({ consent_type, granted })
GET/legal/pending · POST /legal/accept대기 중인 클릭랩 문서 / 수락 기록
POST/contact · POST /feedback · POST /feedback/with-screenshot문의 + 앱 내 피드백

스토리를 생성/추정할 때 사용되는 시드 조회. 안정적인 ID.

MethodPathDescription
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scales사용 가능한 추정 척도
GET/effort_scales/{scale_id}/values척도의 포인트 값
MethodPathDescription
GET/projects여러분의 프로젝트 목록
POST/projects프로젝트 생성
GET/projects/{id}프로젝트 상세 조회 (viewer)
PUT/projects/{id}프로젝트 설정 업데이트 (owner)
DELETE/projects/{id}프로젝트 삭제 (owner)
GET/projects/{id}/audit-log프로젝트 활동 스트림 (owner)
GET/projects/{id}/events커서 페이지네이션 이벤트 스트림 (viewer)Events 참고
MethodPathDescription
GET/projects/{id}/memberships멤버 목록 (viewer)
POST/projects/{id}/memberships이메일로 멤버 초대 (owner)
PUT/projects/{id}/memberships/{mid}역할 업데이트 (owner)
DELETE/projects/{id}/memberships/{mid}멤버 제거 (owner)
GET / POST/projects/{id}/agent_keys에이전트 키 목록 / 발급 (owner)
DELETE/projects/{id}/agent_keys/{kid}에이전트 키 취소 (owner)

모든 스토리 쓰기는 member 역할이 필요합니다.

MethodPathDescription
GET/projects/{id}/stories스토리 목록(페이지네이션, 필터 가능) (viewer)
POST/projects/{id}/stories스토리 생성
GET/projects/{id}/stories/{sid}스토리 하나 조회 (viewer)
PUT/projects/{id}/stories/{sid}스토리 업데이트
DELETE/projects/{id}/stories/{sid}스토리 삭제
POST/projects/{id}/stories/{sid}/transitions검증과 함께 상태 변경
POST/projects/{id}/stories/bulk_transition한 번에 많은 스토리(1–100) 전환
POST/projects/{id}/stories/bulk-delete많은 스토리 삭제
POST/projects/{id}/stories/bulk-duplicate많은 스토리 복제
POST/projects/{id}/stories/{sid}/duplicate스토리 하나 복제

Create (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. labels["auth"] 또는 [{ "name": "auth" }]를 받으며, 알려지지 않은 라벨은 생성됩니다. 기본값: story_type=feature, current_state=unstarted.

Update (PUT …/stories/{sid}): 동일한 필드, 모두 선택적, 그리고 "position"(float)과 "force_state_change"(bool).

Transition (POST …/transitions): { "to": "<state>", "reason"? }. 필드는 **to**입니다. { story_id, state }를 반환합니다. 불법 이동 → details: { from, to, allowed }와 함께 422 invalid_transition.

Bulk transition (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>", "reason"? }. 각 스토리는 독립적으로 판단됩니다. { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }를 반환합니다.

모두 member. 대부분의 List/GET은 (viewer)입니다.

MethodPathBody / notes
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) } or { 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? } — 둘 다 생략하면 호출자를 추가
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}multipart 업로드(각 ≤ 2 GB); 목록은 (viewer)

쓰기는 member, 읽기는 (viewer).

MethodPathDescription
GET / POST/projects/{id}/labels라벨 목록 / 생성
PUT / DELETE/projects/{id}/labels/{lid}라벨 업데이트 / 삭제
POST/projects/{id}/labels/{lid}/archive라벨 보관(소프트 숨김)
MethodPathDescription
GET/projects/{id}/iterations이터레이션 목록 (member)
POST/projects/{id}/iterations수동 이터레이션 생성 (owner)
DELETE/projects/{id}/iterations/{itid}이터레이션 삭제 (owner)
MethodPathDescription
GET/projects/{id}/search?query=…필터 구문 검색 (viewer) — 가이드 참고
GET/projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections}분석 (viewer). 이터레이션 드릴다운은 ?iteration_id=를 받음
GET/projects/{id}/metrics/{velocity,burndown,story-types}지표 (viewer)
GET / PUT/projects/{id}/preferences이 프로젝트에 대한 여러분의 보드 환경 설정 (member)
MethodPathDescription
GET/projects/{id}/events커서 페이지네이션 이벤트 스트림 (viewer)

쿼리 파라미터: since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. 응답은 next_cursor를 포함합니다. 본 마지막 event_idsince로 전달해 재개하세요.

MethodPathDescription
POST/projects/{id}/import (+ /json)Multipart 업로드. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
wss://eastagiletracker.com/ws/control?token=<key>

상호작용 UI 원격 제어용({ "action": "get_state", "id": "req-1" }). 데이터 채널이 아닙니다 — 모든 읽기/쓰기는 REST를 통합니다. 단일 인스턴스 전용. 복제본 간에 팬아웃되지 않습니다.

쓰기 엔드포인트(POST, PUT, DELETE)는 Idempotency-Key 헤더를 받습니다. 같은 키 + 같은 본문은 캐시된 응답을 재생합니다(24시간 창). 같은 키 + 다른 본문은 409 idempotency_conflict를 반환합니다. GET/HEAD/OPTIONS, /auth/*, /attachments 경로에는 적용되지 않습니다. 5xx 응답은 결코 캐시되지 않습니다 — 재시도는 핸들러에 도달합니다.

목록 엔드포인트는 cursor=<opaque>limit=<n≤200>을 받습니다. 설정되면 응답은 { "items": [...], "next_cursor": "<str|null>" }입니다. 페이징하려면 next_cursor를 다시 전달하세요. 일부 목록은 X-Tracker-Pagination-Total 헤더도 반환합니다.

목록 엔드포인트는 특정 필드만 반환하도록 fields=(쉼표로 구분)를 받습니다. story_id는 항상 포함됩니다. 알려지지 않은 필드 이름은 details.fields에 위반한 이름과 함께 400 validation_failed를 반환합니다.

GET /projects/123/stories?fields=story_id,name,current_state,owners

모든 JSON 오류는 codeerror를 가집니다. 일부는 details를 더합니다:

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
StatuscodeWhen
400invalid_parameter잘못된 입력; error에 메시지, details 없음(대부분의 검증: 공백/길이/널 바이트/이메일)
400validation_failed구조화된 입력 오류; details.fields는 위반한 필드 이름의 배열
401unauthenticated토큰 누락/유효하지 않음
403unauthorized_operation인증되었으나 역할 부족
404unfound_resource찾을 수 없음 — 비멤버에게도 반환됨
409conflict리소스 충돌(예: 중복)
409idempotency_conflictIdempotency-Key가 다른 본문으로 재사용됨
422invalid_transition불법 상태 이동; details{ from, to, allowed }를 담음
500internal_error서버 결함 — 일반 메시지; 재시도 안전

details.fields는 필드 이름의 JSON 배열(예: ["to"])이며, 때로 max 같은 추가 키를 포함합니다. 필드→메시지 맵은 없습니다.

{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }

키당(인증되지 않은 엔드포인트는 IP당), GCRA 토큰 버킷:

  • Auth/auth/*: 0.5 req/s, burst 20.
  • Public/contact, /feedback: 0.2 req/s, burst 10.
  • Sensitive — 비밀번호 재설정: ~0.002 req/s, burst 5.

초과된 제한은 Retry-After 헤더와 평문 본문(JSON 오류 봉투가 아님)과 함께 429 Too Many Requests를 반환합니다.