דלגו לתוכן

מפרט API

מדריך עיון מלא לנקודות הקצה של ה-REST API של East Agile Tracker: אימות ותפקידים, פרויקטים, סיפורים, אפיקים, איטרציות, אירועים, ייבוא וייצוא.

סימוכין מלא לנקודות הקצה של REST. למדריכים ולדוגמאות, ראו את מדריך API.

כל מה שחבר בפרויקט יכול לעשות בממשק האינטרנט זמין כאן — ה-SPA צורך את אותו ה-API הזה. פעולות הדורשות את תפקיד ה-manager מסומנות ב-(manager); כל השאר דורש רק חברוּת בפרויקט (או, עבור קריאות המסומנות ב-(viewer), כל רמת גישה). הטבלאות להלן מציינות כל קבוצת נתיבים שהשרת מתקין; אלה שמסוכמות בשורה אחת מתוארות במלואן ב-openapi.json החי.

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

ל-API יש מארח משלו: eastagiletracker.com מגיש את אפליקציית האינטרנט ועונה על /api/v1/… עם 404. כל הבקשות והתגובות הן JSON, מלבד כמה נקודות קצה של העלאת-קבצים שמקבלות multipart.

שתי קבוצות יושבות רמה אחת למעלה, תחת /api ולא תחת /api/v1: משטח האימות (/api/auth/*) וטופס יצירת הקשר הציבורי (/api/contact). הכתיבים שלהם בצורת /api/v1/… מחזירים 404.

כל בקשה מאומתת שולחת אישור גישה באמצעות אחד מ:

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

מפתחות משתמש מתחילים ב-ea_user_, מפתחות סוכן ב-ea_agent_, ואסימוני גישה של MCP ב-ea_mcp_. ראו מדריך API ← שלושה סוגי אישורי גישה.

נקודות קצה ללא אימות: /openapi.json, /docs, נקודות הקצה /api/auth/*, וחיפושי נתוני-הסימוכין (/story_types, /story_states, /effort_scales, /priority_scales). /meta הוא מאומת — כל מפתח תקף עובד, אך הוא אינו בהיקף פרויקט (מפתח סוכן הקשור לפרויקט מגיע אליו גם הוא).

ארבע רמות מהוות שער לנקודות קצה בהיקף פרויקט:

רמהמי עוברפעולות טיפוסיות
public viewerכל אחד, בפרויקט שהנראות שלו ציבוריתקריאות של הלוח: סיפורים, איטרציות, חיפוש, פעילות סיפורים ואפיקים (עם השחרת פרטי המבצע)
viewerviewer, member, managerקריאות (רשימה/קבלת סיפורים, חיפוש, מדדים, רשימת פורמטי הייצוא)
membermember, managerכל כתיבות פריטי-העבודה (סיפורים, מטלות, תגובות, …), זרם האירועים
managermanager בלבדהגדרות פרויקט, ניהול חברוּת, מפתחות סוכן, מחיקה, ייבוא, הורדות ייצוא, גיבויים, יומן ביקורת

לסוכנים יש אותם תפקידים כמו לחברים — viewer, member, או manager — עם תקרה בגובה התפקיד של החבר שטבע את המפתח. לא-חבר מקבל 404 unfound_resource (לא 403) בנתיבי פרויקט פרטיים, כך שמזהי פרויקט אינם ניתנים למניין.

שיטהנתיבתיאור
GET/openapi.jsonמפרט OpenAPI 3 החי, כולל גופי הבקשה. ללא אימות.
GET/docsSwagger UI. ללא אימות.
GET/metaזהות הקורא (auth.kind/key_id/agent_id/project_id) + גרף המעברים לכל-סוג-סיפור. מאומת (כל מפתח תקף; לא בהיקף פרויקט). קראו לזה תחילה.
GET/api/health · /api/configבדיקת חיוּת, והתצורה הציבורית של הפריסה (מצב ארגון יחיד, אילו תכונות אופציונליות פעילות, שם המופע). ללא אימות, מחוץ ל-/v1.

נתיבי אימות (/api/auth/*, מחוץ ל-/v1)

Section titled “נתיבי אימות (/api/auth/*, מחוץ ל-/v1)”

נקודות קצה של מפגש, ללא אימות אלא אם צוין אחרת. ה-SPA מפעיל אותן; סקריפטים משתמשים בדרך כלל במפתח API במקומן.

שיטהנתיבתיאור
POST/auth/registerרישום חשבון חדש — מוגן ב-reCAPTCHA; לאחר מכן החשבון עובר את אתגר ה-SMS
POST/auth/sms/challenge · /auth/sms/status · /auth/sms/bypassשליחה / בדיקה של קוד ה-SMS של ההרשמה (העקיפה מוגבלת למפעיל)
GET/auth/configאילו שיטות התחברות הפריסה מציעה
POST/auth/loginהתחברות עם דוא”ל + סיסמה; מחזיר JWT של מפגש, או אתגר TOTP
POST/auth/login/totpהשלמת התחברות עם קוד מאפליקציית מאמת או קוד שחזור
POST/auth/passkey/login/start · /auth/passkey/login/finishהתחברות WebAuthn ללא סיסמה
GET/auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchangeהתחברות OAuth עם GitHub או Google
POST/auth/refresh · /auth/refresh/revokeסבב של ה-refresh token / ביטולו
POST/auth/logoutהתנתקות (מאומת; מבטלת את ה-refresh token של המפגש הזה)
POST/auth/forgot-password · /auth/reset-passwordבקשת דוא”ל לאיפוס / שימוש באסימון האיפוס
POST/auth/accept-invite/lookup · /auth/accept-inviteפתרון אסימון הזמנה → דוא”ל / קבלת ההזמנה לפרויקט (לאחר אימות)
POST/auth/oauth/link/preview · …/link/confirm · /auth/oauth/merge/preview · …/merge/confirmחיבור חשבון GitHub או Google לחשבון קיים, או מיזוג שני חשבונות
POST/auth/email_addresses/primary/preview · …/primary/confirmהשלמת שינוי של כתובת הדוא”ל הראשית מקישור האישור שנשלח בדוא”ל

אלה פועלים על הקורא ואינם דורשים תפקיד פרויקט. הם דורשים זהות של חבר — מפתח סוכן מקבל 401 (סוכנים משתמשים ב-/agent/me). קריאות שמשנות אישורי גישה — סיסמה, TOTP, מפתחות גישה, מחיקת חשבון, שינוי דוא”ל, יצירה מחדש של אסימון — דורשות מפגש דפדפן; מפתח API מקבל 403.

שיטהנתיבתיאור
GET/meפרופיל המשתמש הנוכחי
PUT/meעדכון פרופיל
DELETE/meמחיקת חשבון — נדחית כל עוד אתם הבעלים היחידים של ארגון או של פרויקט עם חברים אחרים
GET/me/deletion-impactמה מחיקת החשבון תסיר ומה חוסם אותה
PUT/me/passwordשינוי סיסמה
PUT/me/settingsעדכון הגדרות (ערכת נושא, העדפות התראות)
POST / DELETE/me/avatarהעלאה (multipart) / הסרה של האווטר שלכם
POST/me/api-token/regenerateניתוק כל המפגשים והחזרת אסימון מפגש חדש; מפתחות API אינם מושפעים
GET / POST/me/email_addresses · GET …/email_addresses/offers · PUT …/email_addresses/primaryכתובות הדוא”ל שלכם; אימוץ הכתובת של ספק מחובר ככתובת חלופית; בקשה לשינוי הכתובת הראשית (מאושרת בדוא”ל)
GET/me/oauth_identities · DELETE …/oauth_identities/{provider} · POST …/oauth_identities/{provider}/linkחשבונות התחברות מחוברים (GitHub, Google): רשימה, ניתוק, התחלת קישור
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}ניהול מפתחות API של משתמש (ea_user_)
GET/me/totp · POST /me/totp/setup · /me/totp/verify · /me/totp/disableהרשמה לאימות דו-שלבי (TOTP); verify מחזיר את קודי השחזור פעם אחת
GET/me/passkeys · POST /me/passkeys/register/start · /me/passkeys/register/finish · DELETE /me/passkeys/{credential_id}רישום והסרה של מפתחות גישה
GET/me/oauth_grants · DELETE /me/oauth_grants/{grant_id}אפליקציות מחוברות — לקוחות ה-MCP ואפליקציות ה-OAuth שאישרתם
GET/me/activityהפעילות שלכם בכל הפרויקטים
GET/me/storiesסיפורים שבבעלותכם, שביקשתם, או שאתם עוקבים אחריהם בכל פרויקט שהאסימון מגיע אליו — role=owned|requested|following, state=, cursor= / limit= (מקסימום 200)
GET/me/mentions · POST /me/mentions/{mention_id}/ackתיבת ה-@-אזכורים (unacked=true לסינון) ואישור קבלה — מוזגה גם לפיד ההתראות להלן
GET/me/data-exportייצוא-עצמי של הנתונים שלכם לפי GDPR
GET/me/consent · POST /me/consentקריאה / רישום הסכמה ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptמסמכי clickwrap ממתינים / רישום קבלה
GET / PUT/agent/meהזהות והפרופיל של מפתח סוכן, שהסוכן יכול לקרוא ולערוך (המקבילה בצד הסוכן ל-/me)
POST/api/contact · /api/v1/feedback · /api/v1/feedback/with-screenshotיצירת קשר + משוב בתוך האפליקציה; מוגבל קצב לכל IP

נתוני סימוכין (ללא אימות)

Section titled “נתוני סימוכין (ללא אימות)”

חיפושי seed המשמשים ביצירת/הערכת סיפורים. מזהים יציבים.

שיטהנתיבתיאור
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scalesסולמות הערכה זמינים
GET/effort_scales/{scale_id}/valuesערכי הנקודות בסולם
GET/priority_scales · /priority_scales/{scale_id}/valuesסולמות העדיפות והערכים שלהם (priority_id על סיפור נפתר כאן)

שירות מתארח בלבד — התקנה באירוח עצמי רצה במצב ארגון יחיד ואינה מתקינה את אלה (מלבד רשימת הארגונים). התפקידים הם תפקידי ארגון: owner, admin, member.

שיטהנתיבתיאור
GET / POST/organizationsרשימת הארגונים שלכם / יצירת ארגון
GET / PUT / DELETE/organizations/{oid}קריאה, שינוי שם (שם + slug; בעלים או אדמין), מחיקה
GET / POST/organizations/{oid}/memberships · PUT / DELETE …/memberships/{member_id}חברים והזמנות; להזמנות יש תקרת תפקיד (לעולם לא מעל זה של הקורא; לתפקיד הבעלים אין מזמינים לעולם)
POST/organizations/{oid}/memberships/bulk-role · …/memberships/bulk-removeשינוי התפקיד של עד 200 חברים בבת אחת או הסרתם. הכול או כלום: אצווה שתסיר את ה-owner האחרון או תשאיר פרויקט ללא בעלים נדחית כולה; עם reassign_confirmed אתם הופכים לבעלים של הפרויקטים האלה במקום זאת
DELETE/organizations/{oid}/invitations/{invitation_id}ביטול הזמנה ממתינה
POST/organizations/{oid}/transfer-ownershipהעברת תפקיד הבעלים לחבר אחר
GET/organization-invitations/{token} · POST …/{token}/acceptפתרון / קבלה של הזמנה לארגון שנשלחה בדוא”ל
GET/organizations/{oid}/export · POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/downloadייצוא ארגון לבעלים בלבד: zip עם dump של SQL וכל קובץ מצורף, שרץ כמשימה
שיטהנתיבתיאור
GET/projectsרשימת הפרויקטים שלכם (limit ≤ 200)
POST/projectsיצירת פרויקט
GET/projects/{id}קבלת פרטי פרויקט (viewer)
PUT/projects/{id}עדכון הגדרות פרויקט (manager)
DELETE/projects/{id}מחיקת פרויקט (manager)
POST / DELETE/projects/{id}/pinהצמדה / ביטול הצמדה של הפרויקט ברשימת הפרויקטים שלכם
POST/projects/{id}/transfer-organizationהעברת הפרויקט לארגון אחר — הקורא חייב להיות מנהל (Manager) של הפרויקט ובעלים או אדמין של ארגון היעד
POST/projects/{id}/slack/testשליחת הודעת בדיקה להזנת ה-Slack של הפרויקט (manager)
GET / POST/projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seedפרויקטי תצוגה ציבוריים: בדיקה אם אפשר לתבוע אחד, תביעתו, אכלוסו (האכלוס מיועד למנהלי המוצר; כל אחד אחר מקבל 404)
GET/projects/{id}/audit-logקריאת יומן הביקורת — היסטוריית הפרויקט וכן פעילות לפי סיפור / לפי epic דרך surface=; הגישה משתנה לפי ה-surface, ראו למטה
GET/projects/{id}/eventsזרם אירועים מדופדף-cursor (member) — ראו אירועים

פרמטרי שאילתה של יומן הביקורת: event_type= (סוג יחיד או רשימה מופרדת בפסיקים), limit= (ברירת מחדל 50, מוגבל ל-1000), before= (סמן keyset <ISO-8601>|<audit_id> — העבירו את ה-next_cursor של העמוד הקודם), surface= (project_history, story_activities, epic_activities), target_id= (מזהה הסיפור/ה-epic — נדרש כאשר surface=story_activities או epic_activities). גישה: היומן הלא מסונן הוא (manager); surface=project_history הוא (viewer), עם השחרת כתובות הדוא”ל של החברים כשהפרויקט מסתיר אותן; את story_activities / epic_activities יכול לקרוא כל חבר בפרויקט, ובפרויקטים ציבוריים גם באופן אנונימי עם השחרת פרטים מזהים של המבצע.

חברים, סוכנים ומפתחות סוכן

Section titled “חברים, סוכנים ומפתחות סוכן”
שיטהנתיבתיאור
GET/projects/{id}/membershipsרשימת חברים (viewer)
POST/projects/{id}/membershipsהזמנת חבר בדוא”ל (manager)
PUT/projects/{id}/memberships/{mid}עדכון תפקיד (manager)
DELETE/projects/{id}/memberships/{mid}הסרת חבר (manager)
POST/projects/{id}/memberships/bulk-role · …/memberships/bulk-removeשינוי התפקיד של חברים רבים בבת אחת או הסרתם (manager)
GET/projects/{id}/addable-members · POST /projects/{id}/members/add-existingחברי ארגון שעדיין אינם בפרויקט / הוספת אחד מהם ללא הזמנה בדוא”ל — (manager) וגם בעלים או אדמין של הארגון
POST/projects/{id}/members/joinבעלים או אדמין של ארגון מצטרפים לפרויקט בארגון שלהם כ-manager, או מקדמים את עצמם לתפקיד זה (הפעולה Make me owner ברשימת הפרויקטים)
GET / POST/projects/{id}/agent_keysרשימה (manager) / טביעת מפתחות סוכן — אנשים שהתפקיד שלהם נכלל במדיניות תפקידי היוצרים של הפרויקט; מפתחות סוכן אינם יכולים לטבוע
PUT / DELETE/projects/{id}/agent_keys/{kid}עריכת השם, התפקיד או רמזי התגובה של מפתח / ביטולו (manager)
GET/projects/{id}/agent_keys/onboardingחבילת ה-onboarding: פרומפטים וקובצי תצורה עבור לקוחות הסוכנים הנפוצים
GET/projects/{id}/agents · GET / PUT / DELETE /projects/{id}/agents/{aid}הסוכנים של הפרויקט והפרופילים שלהם (שם, ראשי תיבות, תיאור, צבע); DELETE מבטל את הסוכן ואת כל המפתחות שלו — manager או היוצר של הסוכן
POST/projects/{id}/agents/{aid}/rotate-key · /projects/{id}/agents/{aid}/avatarסבב של מפתח סוכן (הזהות וההיסטוריה נשמרות) / העלאת האווטר שלו

כל כתיבות הסיפור דורשות את תפקיד ה-member. יצירת סיפור עם תאריכים לאחור, מקור ייבוא (import_source / import_external_id), או בעלים או מבקש חיצוניים דורשת (manager).

שיטהנתיבתיאור
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/{sid}/reject · /projects/{id}/stories/{sid}/restartדחיית סיפור שסופק / החזרת סיפור שנדחה ל-started (rejected הוא מצב סופי עבור /transitions)
POST/projects/{id}/stories/{sid}/archive · /projects/{id}/stories/{sid}/unarchiveארכוב / ביטול ארכוב של סיפור אחד
POST/projects/{id}/stories/bulk-unarchiveביטול ארכוב של סיפורים רבים
POST/projects/{id}/stories/bulk_transitionמעבר של סיפורים רבים (1–100) בבת אחת
POST/projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-moveארכוב, מחיקה, שכפול, או העברה (לפאנל / מיקום) של סיפורים רבים
POST/projects/{id}/stories/{sid}/duplicateשכפול סיפור אחד
POST / DELETE/projects/{id}/stories/{sid}/epics · …/epics/{eid}השתייכות הסיפור לאפיקים
GET/short-links/{code} · /story-referencesפתרון קישור מקוצר /s/<code> לסיפור שלו / פתרון של עד 100 הפניות — codes= (קודי קישורים מקוצרים מופרדים בפסיקים) ו-ids= (project_id:story_id מופרדים בפסיקים) — לסיפורים שהקורא יכול לקרוא

פרמטרי שאילתה של רשימת הסיפורים: archived= (exclude ברירת מחדל / include / only — מסנן הארכוב התלת-מצבי; מחליף את include_archived=true שהוצא משימוש, המשמש כעת ככינוי ל-archived=include), include_done=true (מכניס סיפורים מפאנל Done הקפואים על איטרציות עבר, המוחרגים כברירת מחדל). דפדוף (cursor= / limit= / offset=) וקבוצות שדות חלקיות (fields=) פועלים לפי דפדוף והקרנת שדות.

יצירה (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. estimate הוא התווית של ערך הסולם כמחרוזת ("3", "13"); מספר JSON נדחה. labels מקבל ["auth"] או [{ "name": "auth" }]; תוויות לא-מוכרות נוצרות. ברירות מחדל: story_type=feature, current_state=unstarted.

עדכון (PUT …/stories/{sid}): אותם שדות, כולם אופציונליים, בתוספת "position" (float), "force_state_change" (bool), ו-"expected_version" (מספר שלם, ה-version של הסיפור — שמירת תיאור נדחית עם 409 stale_write אם התיאור השתנה אחרי גרסה זו). השדה הישן "expected_updated_at" (RFC 3339) הוצא משימוש ועובד לגרסה אחת נוספת: אם הוא נשלח עם תיאור וללא expected_version, השמירה נדחית עם 409 stale_write אלא אם הוא שווה ל-updated_at של הסיפור. כתיבות סיפור מכבדות גם If-Match מול ה-ETag של הסיפור; אי-התאמה היא 412 precondition_failed.

מעבר (POST …/transitions): { "to": "<state>" }. השדה הוא to. מחזיר { story_id, state }. תנועה לא-חוקית → 422 invalid_transition עם details: { from, to, allowed }.

מעבר קבוצתי (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>" }. כל סיפור נשפט באופן עצמאי; מחזיר { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

כולם member. רשימה/GET על רובם הוא (viewer). מחיקת קובץ מצורף או קובץ מצורף מסוג קישור דורשת את המעלה שלו או (manager).

שיטהנתיבגוף / הערות
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) } או { comment_emoji }. GET מקבל fields= (רשימת ההיתר: comment_id, story_comment_id, story_id, comment_text, comment_emoji, member, created) בתוספת 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}יצירה: { url, link_type?, title? }; עדכון: { url, title? } — link_type ∈ relates_to, duplicates, blocks, is_blocked_by, pull_request, branch, other; כתובות GitHub מסוג /pull/ ו-/tree/ מסווגות אוטומטית
GET / POST/projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid}יצירה: { reviewer_id? / reviewer_agent_id?, comment? } — השמיטו את שניהם כדי להקצות את עצמכם. עדכון: { 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}{ label_id } — תווית פרויקט קיימת; צרו תוויות עם POST /projects/{id}/labels, או שלחו labels ב-PUT של הסיפור
GET / POST/projects/{id}/stories/{sid}/attachments (+ /json) · DELETE …/attachments/{aid}העלאת multipart — וידאו ≤ 200 MB, PDF / Word / Excel ≤ 25 MB, תמונות / CSV / טקסט ≤ 10 MB; רשימה היא (viewer)
GET / POST/projects/{id}/stories/{sid}/link-attachments · DELETE …/link-attachments/{laid}קבצים מצורפים מסוג קישור — URL חיצוני שנשמר לצד הקבצים המצורפים ולא כקישור קוד
GET/attachments/{token} · /api/v1/avatars/{token}קריאות של קובץ מצורף או אווטר לפי אסימון — הכתובות שה-API מחלק; אין צורך ב-X-TrackerToken

אותו מבנה כמו סיפורים, בלי מכונת המצבים. member לכתיבות ולרשימות התגובות, הבעלים והעוקבים; (viewer) לרשימת האפיקים, לאפיק בודד ולרשימות הקבצים המצורפים.

שיטהנתיבתיאור
GET / POST/projects/{id}/epics · GET / PUT / DELETE …/epics/{eid}לאפיקים יש שם, תיאור ב-Markdown, ותווית תומכת שמחברת את הסיפורים שלהם
GET / POST / PUT / DELETE…/epics/{eid}/comments · …/comments/{cid}תגובות על אפיקים
GET / POST / DELETE…/epics/{eid}/owners · …/followers (+ גרסאות /agents/{aid})בעלים ועוקבים, חברים או סוכנים — הבעלים של אפיק מתפשטים לסיפורים שלו
GET / POST / DELETE…/epics/{eid}/attachments (+ /json) · …/link-attachmentsקבצים מצורפים, באותן מגבלות כמו לסיפורים
GET/projects/{id}/analytics/epics · …/analytics/epics/{eid}התקדמות לכל אפיק: burnup, תפוקה, בריאות, תחזית (viewer)

member לכתיבות, (viewer) לקריאות.

שיטהנתיבתיאור
GET / POST/projects/{id}/labelsרשימה / יצירת תווית
GET / PUT / DELETE/projects/{id}/labels/{lid}קריאה / עדכון / מחיקת תווית
POST/projects/{id}/labels/{lid}/archiveארכוב (הסתרה רכה) של תווית

הקריאות פתוחות לכל תפקיד בפרויקט, וגם באופן אנונימי בפרויקט ציבורי.

שיטהנתיבתיאור
GET/projects/{id}/iterationsרשימת איטרציות (≤ 500 לעמוד; נושאת ETag ואת כותרות ההמשך X-Tracker-Pagination-* כשהיא מקוצצת)
GET/projects/{id}/iterations/{itid}איטרציה אחת
GET/projects/{id}/iterations/first-previewהחלון, המהירות החזויה ומילוי ה-Backlog של האיטרציה שכתיבה מאתחלת תיצור, או של האיטרציה הנוכחית כשהיא קיימת (member)
POST/projects/{id}/iterationsיצירת איטרציה ידנית (manager)
DELETE/projects/{id}/iterations/{itid}מחיקת איטרציה (manager)
PUT/projects/{id}/iterations/{itid}/velocityעקיפת המהירות של איטרציה אחת בלי לשנות את האסטרטגיה של הפרויקט (manager)
GET/projects/{id}/iterations/{itid}/done-storiesהסיפורים שהתקבלו באיטרציה סגורה, מדופדפים
שיטהנתיבתיאור
GET/projects/{id}/search?q=…חיפוש רב-עוצמה — טקסט מלא + מגדירי היבט / טווח תאריכים / אנשים (DSL בסגנון GitHub); מחזיר { results, total, limit, offset }. query הוא כינוי ל-q; limit= (ברירת מחדל 50, מקסימום 1000) / offset= מדפדפים; sort= ממיין לפי relevance (ברירת מחדל), created, created_asc, state, או updated. (viewer) — ראו את המדריך
GET/projects/{id}/metrics/{velocity,burndown,story-types,contributors}הסדרות של עמוד ה-Metrics (viewer); מדדי האפיקים נמצאים תחת /analytics/epics לעיל
GET/projects/{id}/backlog/groupingקבוצות האיטרציות המוקרנות של ה-Backlog (viewer)
GET / PUT/projects/{id}/preferencesהעדפות הלוח שלכם לפרויקט זה — כל תפקיד בפרויקט, השורה שלכם בלבד
שיטהנתיבתיאור
GET/projects/{id}/eventsזרם אירועים מדופדף-cursor (member) — viewers מקבלים 403

פרמטרי שאילתה: since_id=<event_id> (since הוא הכינוי הישן; since_id גובר כששניהם נשלחים), types=story.created,story.transitioned,comment.added,…, limit= (ברירת מחדל 100, ≤ 500), cursor=. התגובה היא { items, next_since_id, next_cursor }: שמרו את next_since_id והעבירו אותו בחזרה כ-since_id כדי להמשיך; next_cursor הוא null בעמוד האחרון.

פיד ההתראות המאוחד בתוך האפליקציה: שורות התראה מן המניין (בקשות סקירה, פעילות בסיפורים, הזמנות ועוד) ממוזגות עם תיבת ה-@-אזכורים לזרם אחד, מהחדש לישן. מזהי הפיד נושאים קידומת מקור (nt-… / sc-… / ec-…). מפגשים של חברים ומפתחות ea_user_* קוראים את שורות צד-החבר שלהם; מפתחות ea_agent_* את שורות צד-הסוכן.

שיטהנתיבתיאור
GET/me/notificationsפיד ההתראות שלכם. מסננים: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); דפדוף באמצעות cursor= / limit=
GET/me/notifications/unread-countסיכומי לא-נקראו — { unread_count, by_category: { mentions, reviews, stories, invitations } }
POST/me/notifications/read-allסימון הכול כנקרא; מחזיר את המונים המעודכנים
POST/me/notifications/{id}/ackסימון פריט אחד כנקרא (אידמפוטנטי)
POST/me/notifications/{id}/acceptקבלת הזמנה לפרויקט / ארגון ישירות מהפיד (אסימוני חבר בלבד)
POST/me/notifications/{id}/declineדחיית הזמנה לפרויקט / ארגון (אסימוני חבר בלבד)
GET/me/notifications/resolve-invite?token=…המרת אסימון הזמנה שנשלח בדוא”ל למזהה ההתראה שלכם — { "id": "nt-…" } או { "id": null }
GET/me/notifications/streamדחיפה חיה — Server-Sent Events (text/event-stream); ראו בהמשך

נקודת הקצה של הזרם אינה נקודת קצה JSON ולכן אינה במפרט ה-OpenAPI: היא משאירה את החיבור פתוח ופולטת מסגרת ללא payload ({"type":"notification","kind":…}) בכל פעם שמשהו חדש מגיע, כאות ללקוח לרענן את הפיד. חיבורים נסגרים בצד השרת אחרי 45 דקות — התחברו ואמתו מחדש. מפגשים של חברים ומפתחות ea_user_* בלבד; מפתחות ea_agent_* מקבלים 403.

שיטהנתיבתיאור
POST/projects/{id}/importמקורות-קבצים: source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. file= multipart. סינכרוני — עונה עם ספירות התוצאה.
POST/projects/{id}/import/jsonגוף JSON; source=github אינו צריך קובץ — owner, repo, token אופציונלי, ודגלי ההצטרפות מרצון include_pull_requests / include_milestones / include_releases / include_dependencies, ו-include_comments (ברירת מחדל true); מקורות הקבצים שולחים file_base64. אסינכרוני: מחזיר 202 { import_id, status }. השרת שולף דרך ה-GraphQL API של GitHub, שדוחה קוראים אנונימיים, ולכן תמיד מגיע אסימון ל-GitHub — שלכם, או המשותף של הפריסה. ראו את המדריך.
GET/projects/{id}/imports/{import_id}poll למשימה: status עובר pending → fetching → writing → done | failed, עם progress_current / progress_total בזמן השליפה וספירות התוצאה ב-done

רק ייבוא JSON אחד רץ לכל פרויקט בכל רגע; POST …/import/json שני בזמן שאחד בעיצומו הוא 409 import_already_running. עם check_unpointed_estimates: true (מקורות קובץ; מתעלמים ממנו ב-github), קובץ שמכיל הערכות של באגים או משימות תחזוקה שהפרויקט אינו מנקד נדחה ב-409 import_unpointed_estimates עם details.count לפני שמתחילה כל משימה; בלי הדגל הייבוא משמיט את ההערכות האלה ומדווח { code: "estimates_unpointed_dropped", count } ב-warnings של התוצאה. dry_run: true (גוף JSON או dry_run=true multipart) מציג תצוגה מקדימה של כל מקור: מפרסר, פותר, מסיר כפילויות, מחזיר את אותן הספירות { imported, skipped, errors, unmatched }, ואז מגלגל לאחור — דבר אינו נכתב. תקרות: קובץ של 10 MiB (400 import_too_large) ו-5,000 סיפורים לכל ייבוא עבור מקורות הקבצים (400 import_too_many_records); דבר אינו נכתב. גוף בקשה מעל 16 MiB נדחה מוקדם יותר עם 413 request_too_large. למקור GitHub אין תקרה — הוא כותב במנות ולא בטרנזקציה אחת. ייבוא חוזר אידמפוטנטי לכל מזהה מקור — שורות שכבר יובאו מדולגות, לא משוכפלות.

שיטהנתיבתיאור
GET/projects/{id}/export/formatsפורמטים רשומים: { id, name, content_type, drops, includes_archived }. כל תפקיד בפרויקט.
GET/projects/{id}/export/{format}הורדת אחד (manager). חילופין: eat (נאמנות מלאה), jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json; מסמכים: pdf, docx.
GET/projects/{id}/export/attachmentsכל קובץ מצורף כ-zip יחיד הניתן לעיון (קבצים שומרים על שמותיהם המקוריים; מניפסט JSON + CSV) (manager).

ייצוא מסמכים (pdf, docx) מקבל פרמטרי שאילתה נוספים: page_size= (letter ברירת מחדל / a4 / legal / folio), from= / to= (גבולות חלון-הסיפורים — RFC 3339 או YYYY-MM-DD פשוט; סיפור נמצא בטווח כאשר ה-created או ה-completed_at שלו נופל בתוכו), include_icebox= / include_backlog= (שניהם false כברירת מחדל, כך שייצוא הניתן לשיתוף מציג רק עבודה מתוזמנת / בעיצומה). פורמטי ה-CSV לחילופין מתעלמים מהם.

שיטהנתיבתיאור
GET / POST/projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/healthרשימת תמונות מצב, צילום אחת עכשיו, קריאת אחת, וסיכום בריאות השמירה
POST/projects/{id}/restores · POST …/restores/partial · GET …/restores/{restore_id}שחזור תמונת מצב שלמה, או טבלאות נבחרות ממנה, ו-poll לשחזור

בקשות ה-POST יושבות בשכבת מגבלות הקצב הרגישה (להלן).

East Agile Tracker הוא ספק OAuth 2.1 עבור לקוחות MCP. לקוח מגלה אותו ב-/.well-known/oauth-authorization-server וב-/.well-known/oauth-protected-resource/mcp, שולח אתכם ל-/oauth/authorize (דף ההסכמה), מחליף את הקוד ב-/oauth/token, ואז מדבר MCP ב-/mcp עם אסימון ה-ea_mcp_* שהתקבל. ההרשאות מופיעות ומבוטלות ב-/me/oauth_grants. לנקודות הקצה של הספק יש שכבת מגבלות קצב משלהן.

נקודות קצה של כתיבה (POST, PUT, DELETE) מקבלות כותרת Idempotency-Key. אותו מפתח + אותו גוף משמיע מחדש את התגובה השמורה (חלון של 24 שעות); אותו מפתח + גוף שונה מחזיר 409 idempotency_conflict. המפתח תחום לאישור הגישה ששלח אותו. אינו חל על GET/HEAD/OPTIONS, על /openapi.json ו-/docs, על /api/auth/*, על /mcp, על כל נתיב שמכיל /attachments, או על כל בקשת multipart/*; בקשה ללא אישור גישה לעולם אינה נשמרת. תגובות שנעצרו לפני תשובה של התחום לעולם אינן נשמרות — 401, 403, 404, 429, וכל 5xx — כך שניסיון חוזר אחרי כל אחת מהן מגיע ל-handler; 400, 409, 412, ו-422 הן התשובה של התחום ומושמעות מחדש כמו הצלחה.

נקודות קצה של רשימה מקבלות cursor=<opaque> ו-limit=<n>. כשהוגדרו, התגובה היא { "items": [...], "next_cursor": "<str|null>" }; העבירו את next_cursor בחזרה כדי לדפדף. תקרת ה-limit נקבעת לכל נקודת קצה: 200 בסיפורים, בתגובות ובפרויקטים; 500 באירועים; 1000 ביומן הביקורת. החיפוש מדפדף עם limit (≤ 1000) ו-offset במקום cursor ומחזיר { results, total, limit, offset }.

רשימה רגילה (ללא cursor/limit) שנאלצה לקצץ את התגובה שלה מציינת זאת בכותרות — X-Tracker-Pagination-Truncated, X-Tracker-Pagination-Limit, X-Tracker-Pagination-Offset, ו-X-Tracker-Pagination-Next-Offset; העבירו את האחרונה בחזרה כ-offset= לעמוד הבא. אין כותרת של ספירה כוללת.

רשימות הסיפורים, התגובות והפרויקטים מקבלות fields= (מופרד בפסיקים) כדי להחזיר רק שדות מסוימים. המזהה של המשאב תמיד נכלל (story_id, story_comment_id ו-comment_id, project_id); שם שדה לא-מוכר מחזיר 400 validation_failed עם השמות הפוגעים ב-details.fields.

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

לכל שגיאת JSON יש code ו-error; חלק מוסיפות details:

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
סטטוסcodeמתי
400invalid_parameterקלט שגוי; הודעה ב-error. אימות שדות (ריק/אורך/null-byte/דוא”ל) מוסיף details.fields ו-details.constraint; רק שגיאת בקשה שגויה פשוטה משמיטה את details
400validation_failedשגיאת קלט מובְנית; details.fields הוא מערך של שמות שדות פוגעים
400קודי תחוםדחייה ייחודית לנתיב עם קוד משלה וללא details — למשל unsupported_export_format, import_too_large, import_unknown_source
401unauthenticatedאסימון חסר/לא-תקף
403unauthorized_operationמאומת אך תפקיד לא-מספיק
404unfound_resourceלא נמצא — מוחזר גם ללא-חברים
409conflictהתנגשות משאב (למשל כפילות)
409idempotency_conflictIdempotency-Key נעשה בו שימוש חוזר עם גוף שונה
409stale_write · import_already_running · import_unpointed_estimatesהתיאור השתנה אחרי ה-expected_version שלכם (או ש-expected_updated_at כבר אינו תואם) · ייבוא כבר בעיצומו · הקובץ מכיל הערכות של באגים או משימות תחזוקה שהפרויקט אינו מנקד (details.count)
412precondition_failedIf-Match לא תאם את ה-ETag הנוכחי של המשאב; details נושא את expected ואת current
413request_too_largeהגוף חורג ממגבלת הגודל של הנתיב
422invalid_transitionתנועת מצב לא-חוקית; details נושא { from, to, allowed }
429rate_limitedיותר מדי בקשות מה-IP הזה בנתיב מוגבל קצב; כותרת Retry-After
500internal_errorתקלת שרת — הודעה כללית; בטוח לנסות שוב
502upstream_errorשירות שהנתיב תלוי בו (למשל GitHub) נכשל
503not_configuredלפריסה חסרה האינטגרציה שהנתיב הזה צריך (SMS, אחסון אובייקטים, …)

details.fields הוא מערך JSON של שמות שדות (למשל ["to"]), לעיתים עם מפתחות נוספים כמו max. אין מפת שדה→הודעה.

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

לכל IP של לקוח, בקומץ נתיבים; תעבורת API מאומתת בשאר המקומות אינה מוגבלת קצב. ברירות מחדל (כל זוג הוא קצב מתמשך ופרץ, ניתנים לכוונון על ידי המפעיל):

  • Auth — /api/auth/*: 0.5 בקשות/שנייה, פרץ 20.
  • ספק OAuth — /oauth/*: 1 בקשה/שנייה, פרץ 60.
  • Public — /api/contact: 0.2 בקשות/שנייה, פרץ 10.
  • משוב — /api/v1/feedback ו-/api/v1/feedback/with-screenshot: שלוש שכבות מוערמות — שליחה אחת כל 15 שניות, 10 בשעה, 36 ביום.
  • אווטרים — ההפניה הלא מאומתת של אווטרים: 20 בקשות/שנייה, פרץ 200.
  • רגיש — בקשות ה-POST של גיבוי ושחזור: ~0.002 בקשות/שנייה, פרץ 5.

מגבלה שנחרגה מחזירה 429 עם כותרת Retry-After ומעטפת שגיאת ה-JSON הסטנדרטית, code: "rate_limited".