Zum Inhalt springen

API-Leitfaden

Die East Agile Tracker API ist für Agenten ebenso wie für Menschen konzipiert. Alles, was Sie in der Benutzeroberfläche tun können, können Sie über die API tun — und ein paar Dinge, die die Benutzeroberfläche nicht offenlegt, sind ebenfalls dabei.

Dieser Leitfaden bringt Sie in unter zehn Minuten von null auf „Ihr Backlog skripten”. Für die vollständige Endpunktreferenz siehe API-Spezifikation.

Sie authentifizieren sich mit einem Schlüssel im X-TrackerToken-Header. Es gibt zwei Arten von Schlüsseln, die Sie selbst ausstellen, und eine dritte, die ein MCP-Client für Sie beschafft:

  • Benutzerschlüssel (ea_user_…) — Handeln als Sie. Erstellen Sie sie in Account-Einstellungen → API-Schlüssel. Verwenden Sie diese für persönliche Skripte, CLI-Tools, Integrationen.
  • Agenten-Schlüssel (ea_agent_…) — Handeln als benannter Agent in einem Projekt. Erstellen Sie sie in Project Settings → Agents. Verwenden Sie diese für KI-Agenten — Claude Code, Codex, Ihren eigenen — die als benannte Teammitglieder am Projekt teilnehmen sollen.
  • MCP-Tokens (ea_mcp_…) — OAuth-2.1-Zugriffstokens, die einem MCP-Client (Claude, einer IDE) ausgestellt werden, nachdem Sie ihn auf der Einwilligungsseite freigegeben haben. Sie handeln als Sie, und Sie können sie unter Account-Einstellungen → Verbundene Apps widerrufen.

Der einmalige Dialog nach dem Anlegen eines persönlichen API-Schlüssels in den Kontoeinstellungen; der Schlüssel ist maskiert

Das Formular zum Anlegen eines Schlüssels im Tab Agent mit Namen und gewählter Rolle member, unter der Einrichtungsanleitung

Die Unterschiede zwischen den beiden, die Sie selbst ausstellen:

BenutzerschlüsselAgenten-Schlüssel
GeltungsbereichAlle Ihre ProjekteEin bestimmtes Projekt
Identität im Audit-LogIhr NameDer Name des Agenten
RolleIhre Rolle in jedem ProjektBei Schlüsselerstellung festgelegt (viewer, member oder manager — nie über der Rolle des ausstellenden Mitglieds)
WiderrufSchlüssel widerrufen; Zugang über andere Schlüssel/Sitzungen bleibtSchlüssel widerrufen oder rotieren; der Agent verliert sofort den Zugriff
Am besten fürPersönliche Automatisierung, SkripteKI-Agenten, die sich in der Historie von Ihnen unterscheiden lassen sollen

Authorization: Bearer … funktioniert ebenfalls, wenn Sie diesen Header-Stil bevorzugen.

Rufen Sie Ihre Projekte ab:

Terminal-Fenster
curl https://eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: $TRACKER_TOKEN"

Oder für einen Agenten-Schlüssel listen Sie das Projekt auf, auf das er beschränkt ist:

Terminal-Fenster
curl https://eastagiletracker.com/api/v1/projects \
-H "X-TrackerToken: ea_agent_xxxxx"

Die API ist JSON, REST-artig, versioniert unter /api/v1/. Dieselben Formen für Menschen und Agenten.

Terminal-Fenster
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
}'

Die Antwort enthält die project_id und alle Voreinstellungen, die der Server angewendet hat (Schätzskala, Done-State usw.).

Terminal-Fenster
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 ist die Bezeichnung des Skalenwerts als String — "3" oder "13" auf der Fibonacci-Skala — denn sie muss zu einem Punkt der Projektskala passen. Eine JSON-Zahl wird abgelehnt.

Der Transition-Endpunkt validiert die angeforderte Bewegung und gibt bei einem Fehler die erlaubten nächsten Zustände zurück:

Terminal-Fenster
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" }'

Das Feld ist to (nicht to_state). Wenn die Bewegung unzulässig ist — sagen wir, Sie haben versucht, von unstarted direkt zu accepted zu springen — ist die Antwort 422 invalid_transition mit strukturierten Fehlerdetails:

{
"code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] }
}

Das ist eines der kleinen Dinge, die die API agentenfreundlich machen: Ein Agent kann details.allowed lesen und die richtige nächste Bewegung wählen, ohne Prosa zu scrapen.

rejected ist für den Transition-Endpunkt ein Endzustand. Um eine abgelehnte Story wieder in Arbeit zu bringen, POST …/stories/{sid}/restart; POST …/stories/{sid}/reject ist die Verbform, eine delivered Story abzulehnen.

Terminal-Fenster
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." }'

Der Kommentar wird demjenigen zugeschrieben, dem der API-Schlüssel gehört — wenn es ein Agenten-Schlüssel ist, ist der Autor des Kommentars der Agent.

Jeder Schreib-Endpunkt akzeptiert einen Idempotency-Key-Header. Wiederholen Sie denselben Schlüssel mit demselben Body, erhalten Sie dieselbe Antwort zurück. Wiederholen Sie denselben Schlüssel mit einem anderen Body, erhalten Sie einen 409 idempotency_conflict:

Terminal-Fenster
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" }'

Das ist kritisch für Agenten in Retry-Schleifen — mitten im Schreibvorgang abstürzen, mit demselben Schlüssel erneut versuchen, keine doppelten Stories.

Bewegen Sie viele Stories auf einmal. Jede Story wird unabhängig beurteilt; eine unzulässige Bewegung lässt die anderen nicht fehlschlagen.

Terminal-Fenster
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"
}'

Für Agenten, die auf das reagieren möchten, was Menschen tun, pollen Sie den Events-Endpunkt:

Terminal-Fenster
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"

Die Antwort ist ein cursor-paginierter Stream von Events mit dem Akteur, der Ressource und der Änderung. Jedes Event hat eine ID; übergeben Sie die letzte ID, die Sie gesehen haben, als since, um dort fortzufahren, wo Sie aufgehört haben. Keine Webhooks, kein Scraping, keine verpassten Events. Der Stream verlangt die Rolle member — ein Viewer bekommt 403.

GET /projects/{id}/search?q=<query> führt eine mächtige Volltext- und strukturierte Suche über die Stories des Projekts aus. Die Abfragesprache ist den Issue-Such-Qualifiern von GitHub nachempfunden — Syntax, die Sie (oder ein KI-Agent) von GitHub kennen, trägt also größtenteils hierher.

Terminal-Fenster
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'

Die Antwort ist ein JSON-Umschlag, die Stories nach Relevanz sortiert:

{ "results": [ /* canonical story objects */ ], "total": 42, "limit": 50, "offset": 0 }

total ist die vollständige Trefferzahl, nicht die Seitengröße. Blättern Sie mit limit (Voreinstellung 50, maximal 1000) und offset; sortieren Sie mit sort=relevance (Voreinstellung), created, created_asc, updated oder state.

  • Freitext trifft Titel, Referenz und Beschreibung einer Story (Volltext, gestemmt und gewichtet). Setzen Sie eine exakte Phrase in "Anführungszeichen".
  • Qualifier haben die Form field:value. Trennen Sie Alternativen per Komma (ODER innerhalb eines Felds): type:bug,chore. Trennen Sie Qualifier per Leerzeichen (UND über sie hinweg).
  • Negieren Sie einen beliebigen Term oder Qualifier mit vorangestelltem -: -label:wontfix.
  • Bereiche für Daten und Punkte: einschließend a..b oder offen >x / <x.
QualifierBeispielTrifft
type:type:bug,choreStory-Typ(en)
state:state:started,finishedWorkflow-Zustand/-Zustände
label:label:"my label"ein Label
epic:epic:"Checkout"Stories in einem Epic
priority:priority:p1Priorität
points:points:3 · points:1..5 · points:>3Schätzwert oder -bereich
iteration:iteration:42Iterations-Id
created: updated: started: completed: release:created:2026-05-01..2026-06-01 · updated:>2026-06-01ein Datum oder ein Bereich (taggenau); release: ist das Release-Datum der Story
owner: requester: follower: reviewer: commenter: mention:owner:claire · owner:@meeine Person nach Name oder E-Mail — Mitglieder und Agenten, mention: eingeschlossen; @me sind Sie
has:blockerhas:blockerhat einen offenen Blocker
is:is:unestimated · is:icebox · is:backlog · is:blockedein Flag

mywork: ist ein Alias für owner:mywork:me entspricht owner:@me. Der ältere Qualifier scheduled: ist ausgemustert und wird stillschweigend ignoriert; verwenden Sie release:.

Komma-ODER (type:bug,chore) gilt für die Facet-Qualifier; die Personen-Qualifier (owner: requester: follower: reviewer: commenter: mention:) nehmen einen einzelnen Wert.

payment crash Volltext "payment" UND "crash"
"exact phrase" eine Phrase
type:bug,chore state:started Bugs oder Chores, die gestartet sind
owner:@me -label:wontfix meine, ohne das Label wontfix
points:3..8 created:2026-05-01..2026-06-01 auf 3-8 geschätzt, im Mai erstellt
follower:tomas has:blocker tomas folgt ihr und sie ist blockiert
is:backlog updated:>2026-06-01 Backlog-Einträge, seit 1. Juni berührt

Dieselbe Abfragezeichenkette treibt das Suchfeld des Boards an (das eine Live-Ergebnisspalte öffnet) und diese API — eine Grammatik für Menschen wie für Agenten. Die Suche in den Inhalten von Kommentaren, Tasks und Blockern steht auf der Roadmap; heute deckt Freitext den Titel, die Referenz und die Beschreibung der Story selbst ab.

Die Live-OpenAPI-3-Spezifikation befindet sich unter:

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

Swagger UI befindet sich unter:

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

/openapi.json und /docs sind nicht authentifiziert — ein Agent kann den Vertrag lesen, bevor er einen Schlüssel hat. Sobald er einen Schlüssel besitzt, gibt /api/v1/meta (was einen gültigen Schlüssel erfordert) seine Identität und den Transition-Graphen pro Story-Typ zurück; die Referenzdaten-Lookups (/story_types, /story_states, /effort_scales, /priority_scales) sind ebenfalls nicht authentifiziert. Zusammen lassen sie Agenten „Was kann ich hier tun?” beantworten, ohne Trial-and-Error-403s.

Die ausgelieferte openapi.json trägt Request-Body-Schemata für die Schreib-Endpunkte, einschließlich der maxLength jedes Felds, sodass ein Client vor dem Senden validieren kann. Die Spezifikation fasst dieselben Formen zusammen.

Für interaktive Automatisierung — das Steuern einer angemeldeten Browser-Sitzung aus einem Skript oder das Fernsteuern der Benutzeroberfläche für Tutorials — gibt es einen WebSocket-Kanal:

const ws = new WebSocket('wss://eastagiletracker.com/ws/control?token=SESSION_JWT')
ws.send(JSON.stringify({ action: 'get_state', id: 'req-1' }))

Das token ist das JWT der Browser-Sitzung, kein API-Schlüssel — ein ea_user_*- oder ea_agent_*-Schlüssel wird noch vor dem Upgrade abgewiesen. Die meisten Benutzer brauchen dies nie; es ist für die Fälle da, in denen REST nicht ausreicht.

Wenn Sie eine Massenmigration skripten:

Terminal-Fenster
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"

Unterstützte Datei-Quellen: pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat (das eigene Exportformat von East Agile Tracker — das Roundtrip-Format). Der Multipart-Endpunkt läuft synchron und antwortet mit den Ergebniszahlen.

GitHub importiert aus der API statt aus einer Datei, über den JSON-Endpunkt — keine file, nur die Repository-Koordinaten:

Terminal-Fenster
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
}'

Der JSON-Endpunkt ist asynchron: Er antwortet mit 202 und { "import_id", "status" }, und Sie pollen GET /projects/{id}/imports/{import_id}, bis der Job done oder failed erreicht. Pro Projekt läuft immer nur ein Import — ein zweiter Aufruf, während einer unterwegs ist, ergibt 409 import_already_running. Die ganze Schleife, samt der Fortschrittsfelder des Jobs, steht in Ein Projekt aus einem GitHub-Repo befüllen.

Das token ist auf der Leitung optional, doch der Abruf selbst authentifiziert sich immer — er läuft über GitHubs GraphQL-API, die keine anonyme Stufe kennt. Lassen Sie token weg, setzt der Server sein Plattform-Token ein: nur öffentliche Repositories, von jedem Aufrufer geteilt, und mit import_github_shared_quota_low abgelehnt, sobald sein GraphQL-Budget unter 500 Punkte fällt. Ein privates Repository oder ein Deployment, das kein Plattform-Token konfiguriert hat (import_github_no_token), verlangt Ihres. Welches Token auch läuft, es wird nur für die vorgelagerten GitHub-Aufrufe verwendet und niemals gespeichert oder zurückgegeben. Alle Einzelheiten, einschließlich GitHubs nicht authentifizierter REST-Obergrenze von 60 Anfragen, stehen in Ein Projekt aus einem GitHub-Repo befüllen.

Dry-Run-Vorschau. Fügen Sie "dry_run": true (JSON) oder -F "dry_run=true" (Multipart) zu einer beliebigen Quelle hinzu. Der Import analysiert, löst auf und dedupliziert genau wie ein echter Lauf, erzeugt dieselben Ergebniszahlen (imported, skipped, errors, unmatched) und macht dann alles rückgängig — nichts wird geschrieben. Beim JSON-Endpunkt treffen die Zahlen am gepollten Job ein, ob Dry-Run oder nicht.

Limits. Ein Upload-Body ist auf 10 MiB begrenzt und ein einzelner Import auf 5.000 Storys; das Überschreiten des einen oder anderen ist ein 400, ohne dass etwas geschrieben wird. Eine Datei erneut zu importieren ist sicher — bereits importierte Zeilen (anhand der Quell-ID abgeglichen) werden übersprungen, nicht dupliziert.

Jede Projektrolle darf die Formate auflisten; eines herunterzuladen ist nur Eigentümern vorbehalten:

Terminal-Fenster
# Die registrierten Exportformate: { id, name, content_type, drops, includes_archived }
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/formats \
-H "X-TrackerToken: $TRACKER_TOKEN"
# Ein Format herunterladen (eat ist das CSV mit voller Roundtrip-Wiedergabetreue)
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/eat \
-H "X-TrackerToken: $TRACKER_TOKEN" -o project-export.csv

Austauschformat-Ids: eat, jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json, dazu die Dokumentformate pdf und docx. Jeder Anhang ist als ein einziges zip von GET /projects/{id}/export/attachments herunterladbar.

Alle Fehler sind JSON mit mindestens:

{
"code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`"
}

Viele Fehlerantworten enthalten auch ein details-Objekt — details.fields (ein Array von beanstandeten Feldnamen) bei validation_failed und details.allowed (neben from/to) bei 422 invalid_transition. Nutzen Sie sie. Ein 429 rate_limited trägt im selben JSON-Umschlag einen Retry-After-Header.

List-Endpunkte akzeptieren limit und cursor. Der Cursor ist opak; übergeben Sie das next_cursor aus der vorherigen Antwort. Die Obergrenze für limit gilt pro Endpunkt — 200 bei Stories, Kommentaren und Projekten, 500 bei Events, 1000 bei der Suche und dem Audit-Log. Eine einfache (cursorlose) Liste, die ihre Antwort kürzen musste, sagt das in Headern: X-Tracker-Pagination-Truncated, -Limit, -Offset und -Next-Offset, das Sie als offset= für die nächste Seite zurückgeben. Einen Header mit der Gesamtzahl gibt es nicht.