De volledige REST-endpoint-referentie. Voor tutorials en voorbeelden, zie de API-gids.
Alles wat een project-member in de web-UI kan doen is hier beschikbaar — de SPA verbruikt dezelfde API. Operaties die de rol manager vereisen zijn gemarkeerd met (manager); al het andere heeft alleen projectlidmaatschap nodig (of, voor reads gemarkeerd met (viewer), een willekeurig toegangsniveau). De tabellen hieronder noemen elke routegroep die de server aanbiedt; de groepen die in één regel zijn samengevat, worden volledig beschreven in de live openapi.json.
https://eastagiletracker.com/api/v1https://api.eastagiletracker.com/api/v1 serveert de identieke API. Alle verzoeken en antwoorden zijn JSON, behalve een paar bestandsupload-endpoints die multipart accepteren.
Twee groepen staan één niveau hoger, onder /api in plaats van /api/v1: het authenticatiegedeelte (/api/auth/*) en de openbare formulieren (/api/contact, /api/feedback). Hun /api/v1/…-varianten geven 404 terug.
Authenticatie
Section titled “Authenticatie”Elk geauthenticeerd verzoek stuurt inloggegevens via een van:
X-TrackerToken: <key>Authorization: Bearer <key>
User-sleutels beginnen met ea_user_, agent-sleutels met ea_agent_, en MCP-access-tokens met ea_mcp_. Zie API-gids → Drie soorten inloggegevens.
Endpoints zonder authenticatie: /openapi.json, /docs, de /api/auth/*-endpoints, en de referentiegegevens-lookups (/story_types, /story_states, /effort_scales, /priority_scales). /meta is geauthenticeerd — elke geldige sleutel werkt, maar het is niet projectgebonden (een aan een project gebonden agent-sleutel bereikt het ook).
Rollen
Section titled “Rollen”Vier niveaus reguleren projectgebonden endpoints:
| Niveau | Wie passeert | Typische operaties |
|---|---|---|
| public viewer | iedereen, op een project met openbare zichtbaarheid | reads van het bord: stories, iteraties, zoeken, story- en epic-activiteit (met actorgegevens weggelakt) |
| viewer | viewer, member, manager | reads (stories tonen/ophalen, zoeken, metrics, lijst met exportformaten) |
| member | member, manager | alle writes op werkitems (stories, taken, reacties, …), de eventstream |
| manager | alleen manager | projectinstellingen, lidmaatschapsbeheer, agent-sleutels, verwijderen, import, exportdownloads, back-ups, auditlog |
Agents hebben dezelfde rollen als members — viewer, member of manager — begrensd op de rol van het lid dat de sleutel heeft aangemaakt. Een niet-member ontvangt 404 unfound_resource (niet 403) op paden van privéprojecten, zodat project-ID’s niet enumereerbaar zijn.
Zelfbeschrijvende endpoints
Section titled “Zelfbeschrijvende endpoints”| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /openapi.json | De live OpenAPI 3-spec, inclusief request-bodies. Zonder authenticatie. |
| GET | /docs | Swagger UI. Zonder authenticatie. |
| GET | /meta | Identiteit van de aanroeper (auth.kind/key_id/agent_id/project_id) + de transitiegraaf per story-type. Geauthenticeerd (elke geldige sleutel; niet projectgebonden). Roep dit eerst aan. |
| GET | /api/health · /api/config | Liveness, en de openbare configuratie van de deployment (single-org-modus, ingeschakelde optionele functies, naam van de instantie). Zonder authenticatie, buiten /v1. |
Auth (/api/auth/*, buiten /v1)
Section titled “Auth (/api/auth/*, buiten /v1)”Sessie-endpoints, zonder authenticatie tenzij anders vermeld. De SPA gebruikt deze; scripts gebruiken normaal gesproken een API-sleutel.
| Methode | Pad | Beschrijving |
|---|---|---|
| POST | /auth/register | Een nieuw account registreren — beschermd door reCAPTCHA; het account doorloopt daarna de sms-controle |
| POST | /auth/sms/challenge · /auth/sms/status · /auth/sms/bypass | De sms-code voor registratie versturen / controleren (bypass is afgeschermd door de beheerder) |
| GET | /auth/config | Welke inlogmethoden de deployment aanbiedt |
| POST | /auth/login | Inloggen met e-mail + wachtwoord; geeft een sessie-JWT of een TOTP-uitdaging terug |
| POST | /auth/login/totp | Een aanmelding afronden met een authenticatorcode of een herstelcode |
| POST | /auth/passkey/login/start · /auth/passkey/login/finish | Wachtwoordloos inloggen met WebAuthn |
| GET | /auth/oauth/github/start · /auth/oauth/github/callback · /auth/oauth/google/start · /auth/oauth/google/callback · POST /auth/oauth/exchange | OAuth-aanmelding met GitHub of Google |
| POST | /auth/refresh · /auth/refresh/revoke | Het refresh-token roteren / intrekken |
| POST | /auth/logout | Uitloggen (trekt het refresh-token in) |
| POST | /auth/forgot-password · /auth/reset-password | Een reset-e-mail aanvragen / het resettoken gebruiken |
| POST | /auth/accept-invite/lookup · /auth/accept-invite | Een uitnodigingstoken herleiden → e-mail / de projectuitnodiging accepteren (na authenticatie) |
Account / identiteit
Section titled “Account / identiteit”Deze handelen op de aanroeper en hebben alleen een geldige sleutel nodig (geen projectrol).
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /me | Huidig gebruikersprofiel |
| PUT | /me | Profiel bijwerken |
| DELETE | /me | Account verwijderen — geweigerd zolang je de enige owner bent van een organisatie of van een project met andere leden |
| GET | /me/deletion-impact | Wat het verwijderen van het account zou weghalen en wat het blokkeert |
| PUT | /me/password | Wachtwoord wijzigen |
| PUT | /me/settings | Instellingen bijwerken (thema, notificatievoorkeuren) |
| POST | /me/avatar | Avatar uploaden (multipart) |
| POST | /me/api-token/regenerate | Je API-token roteren — maakt bestaande sessies/sleutels ongeldig |
| GET | /me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id} | Beheer user- (ea_user_) API-sleutels |
| GET | /me/totp · POST /me/totp/setup · /me/totp/verify · /me/totp/disable | Inschrijving voor tweestapsverificatie (TOTP); verify geeft de herstelcodes eenmalig terug |
| GET | /me/passkeys · POST /me/passkeys/register/start · /me/passkeys/register/finish · DELETE /me/passkeys/{credential_id} | Passkeys registreren en verwijderen |
| GET | /me/oauth_grants · DELETE /me/oauth_grants/{grant_id} | Connected apps — de MCP-clients en OAuth-apps die je hebt geautoriseerd |
| GET | /me/activity | Je activiteit over alle projecten |
| GET | /me/stories | Stories waarvan je owner of aanvrager bent, of die je volgt, over elk project dat het token kan bereiken — role=owned|requested|following, state=, cursor= / limit= (max 200) |
| GET | /me/mentions · POST /me/mentions/{mention_id}/ack | De inbox met @-vermeldingen (unacked=true om te filteren) en bevestiging — ook opgenomen in de meldingenfeed hieronder |
| GET | /me/data-export | GDPR-zelfexport van je gegevens |
| GET | /me/consent · POST /me/consent | Toestemming lezen / registreren ({ consent_type, granted }) |
| GET | /legal/pending · POST /legal/accept | Openstaande clickwrap-documenten / acceptatie registreren |
| GET / PUT | /agent/me | De eigen identiteit en het profiel van een agent-sleutel, leesbaar en bewerkbaar door de agent (de tegenhanger van /me aan agentzijde) |
| POST | /api/contact · /api/feedback · /api/feedback/with-screenshot | Contact + in-app feedback. Buiten /v1; rate-limited per IP |
Referentiegegevens (zonder authenticatie)
Section titled “Referentiegegevens (zonder authenticatie)”Seed-lookups die worden gebruikt bij het aanmaken/schatten van stories. Stabiele ID’s.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /story_types | feature, bug, chore, release (+ allow_points) |
| GET | /story_states | unstarted … accepted, rejected |
| GET | /effort_scales | beschikbare schattingsschalen |
| GET | /effort_scales/{scale_id}/values | de puntwaarden in een schaal |
| GET | /priority_scales · /priority_scales/{scale_id}/values | de prioriteitsschalen en hun waarden (priority_id op een story verwijst hiernaar) |
Organisaties
Section titled “Organisaties”Alleen op de gehoste dienst — een self-hosted installatie draait in single-organization-modus en biedt deze niet aan (behalve de lijst met organisaties). Rollen zijn organisatierollen: owner, admin, member.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET / POST | /organizations | Je organisaties tonen / er een aanmaken |
| GET / PUT / DELETE | /organizations/{oid} | Lezen, hernoemen (naam + slug; owner of admin), verwijderen |
| GET / POST | /organizations/{oid}/memberships · PUT / DELETE …/memberships/{member_id} | Leden en uitnodigingen; uitnodigingen hebben een rolplafond (nooit hoger dan dat van de aanroeper; owner wordt nooit uitgenodigd) |
| POST | /organizations/{oid}/memberships/bulk-role · …/memberships/bulk-remove | Wijzig de rol van maximaal 200 leden tegelijk of verwijder ze. Alles of niets: een batch die de laatste owner zou verwijderen of een project zonder eigenaar zou achterlaten, wordt in zijn geheel geweigerd; met reassign_confirmed word je in plaats daarvan eigenaar van die projecten |
| DELETE | /organizations/{oid}/invitations/{invitation_id} | Een openstaande uitnodiging intrekken |
| POST | /organizations/{oid}/transfer-ownership | De rol owner overdragen aan een ander lid |
| PUT | /organizations/{oid}/memberships/{member_id}/anonymization | De naam / het e-mailadres / de avatar van een lid in de hele organisatie maskeren |
| GET | /organization-invitations/{token} · POST …/{token}/accept | Een per e-mail ontvangen organisatie-uitnodiging herleiden / accepteren |
| POST | /organizations/{oid}/export · GET / POST …/export/jobs · GET …/export/jobs/{job_id} · …/export/jobs/{job_id}/download | Organisatie-export, alleen voor owners: een zip met een SQL-dump en elke bijlage, uitgevoerd als job |
Projecten
Section titled “Projecten”| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects | Je projecten tonen (limit ≤ 200) |
| POST | /projects | Een project aanmaken |
| GET | /projects/{id} | Projectdetails ophalen (viewer) |
| PUT | /projects/{id} | Projectinstellingen bijwerken (manager) |
| DELETE | /projects/{id} | Een project verwijderen (manager) |
| POST | /projects/{id}/pin | Het project vastzetten / losmaken in je projectlijst |
| POST | /projects/{id}/transfer-organization | Het project naar een andere organisatie verplaatsen (manager) |
| POST | /projects/{id}/slack/test | Een testbericht naar de Slack-feed van het project sturen (manager) |
| GET / POST | /projects/{id}/showcase_claim_eligibility · /projects/{id}/showcase_claim · /projects/{id}/showcase_seed | Openbare showcaseprojecten: controleren of je er een kunt claimen, het claimen, het vullen |
| GET | /projects/{id}/audit-log | Audit-log lezen — projecthistorie plus activiteit per story / per epic via surface=; toegang verschilt per surface, zie hieronder |
| GET | /projects/{id}/events | Cursor-gepagineerde eventstream (member) — zie Events |
Query-parameters van de audit-log: event_type= (één type of kommagescheiden lijst), limit= (≤ 1000), before= (keyset-cursor, ISO-8601 created_at), surface= (project_history, story_activities, epic_activities), target_id= (het story-/epic-id — verplicht wanneer surface=story_activities of epic_activities). Toegang: de ongefilterde log en surface=project_history zijn (manager); story_activities / epic_activities zijn leesbaar voor elk projectlid, en anoniem op publieke projecten met de PII van de actor weggelakt.
Members, agents en agent-sleutels
Section titled “Members, agents en agent-sleutels”| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects/{id}/memberships | Members tonen (viewer) |
| POST | /projects/{id}/memberships | Een member uitnodigen via e-mail (manager) |
| PUT | /projects/{id}/memberships/{mid} | Rol bijwerken (manager) |
| DELETE | /projects/{id}/memberships/{mid} | Een member verwijderen (manager) |
| GET | /projects/{id}/addable-members · POST /projects/{id}/members/add-existing | Leden van de organisatie die nog niet in het project zitten / er een toevoegen zonder uitnodiging per e-mail (manager) |
| POST | /projects/{id}/members/join | Een owner of admin van de organisatie treedt als manager toe tot een project in zijn organisatie, of promoveert zichzelf tot manager (de actie Make me owner in de projectlijst) |
| PUT | /projects/{id}/members/{mid}/anonymization | De naam / het e-mailadres / de avatar van een lid in dit project maskeren (manager) |
| GET / POST | /projects/{id}/agent_keys | Agent-sleutels tonen / aanmaken — managers, of de rollen die het creator-roles-beleid van het project toelaat |
| DELETE | /projects/{id}/agent_keys/{kid} | Een agent-sleutel intrekken |
| GET | /projects/{id}/agent_keys/onboarding | De onboarding-bundel: prompts en configuratiebestanden voor de gangbare agent-clients |
| GET | /projects/{id}/agents · GET / PUT /projects/{id}/agents/{aid} | De agents van het project en hun profielen (naam, initialen, beschrijving, kleur) |
| POST | /projects/{id}/agents/{aid}/rotate-key · /projects/{id}/agents/{aid}/avatar | De sleutel van een agent roteren (identiteit en historie blijven behouden) / de avatar uploaden |
Stories
Section titled “Stories”Alle story-writes hebben de rol member nodig.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects/{id}/stories | Stories tonen (gepagineerd, filterbaar) (viewer) |
| POST | /projects/{id}/stories | Een story aanmaken |
| GET | /projects/{id}/stories/{sid} | Eén story ophalen (viewer) |
| PUT | /projects/{id}/stories/{sid} | Een story bijwerken |
| DELETE | /projects/{id}/stories/{sid} | Een story verwijderen |
| POST | /projects/{id}/stories/{sid}/transitions | Toestand wijzigen met validatie |
| POST | /projects/{id}/stories/{sid}/reject · /projects/{id}/stories/{sid}/restart | Een opgeleverde story afwijzen / een afgewezen story terugzetten op started (rejected is een eindtoestand voor /transitions) |
| POST | /projects/{id}/stories/{sid}/archive · /projects/{id}/stories/{sid}/unarchive | Eén story archiveren / dearchiveren |
| POST | /projects/{id}/stories/bulk_transition | Veel stories (1–100) tegelijk laten overgaan |
| POST | /projects/{id}/stories/bulk-archive · bulk-delete · bulk-duplicate · bulk-move | Veel stories archiveren, verwijderen, dupliceren of verplaatsen (naar een paneel / positie) |
| POST | /projects/{id}/stories/{sid}/duplicate | Eén story dupliceren |
| GET / POST / DELETE | /projects/{id}/stories/{sid}/epics · …/epics/{eid} | Het epic-lidmaatschap van de story |
| GET | /short-links/{code} · /story-references | Een /s/<code>-short-link herleiden tot zijn story / tot 100 story-referenties (#id, URL’s) herleiden tot de stories die de aanroeper kan lezen |
Queryparameters voor de story-lijst: archived= (exclude standaard / include / only — het archieffilter met drie standen; vervangt het verouderde include_archived=true, nu een alias voor archived=include), include_done=true (laat Done-panelstories toe die op eerdere iteraties zijn bevroren, standaard uitgesloten). Paginering (cursor= / limit= / offset=) en spaarzame veldensets (fields=) volgen Paginering en Veldprojectie.
Aanmaken (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. estimate is het label van de schaalwaarde als string ("3", "13"); een JSON-getal wordt geweigerd. labels accepteert ["auth"] of [{ "name": "auth" }]; onbekende labels worden aangemaakt. Standaardwaarden: story_type=feature, current_state=unstarted.
Bijwerken (PUT …/stories/{sid}): dezelfde velden, allemaal optioneel, plus "position" (float), "force_state_change" (bool) en "expected_updated_at" (RFC 3339 — het opslaan van een beschrijving wordt geweigerd met 409 stale_write als de story is gewijzigd sinds je hem las). Story-writes respecteren ook If-Match tegen de ETag van de story; bij een mismatch volgt 412 precondition_failed.
Transition (POST …/transitions): { "to": "<state>" }. Het veld is to. Geeft { story_id, state } terug. Ongeldige beweging → 422 invalid_transition met details: { from, to, allowed }.
Bulk transition (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>" }. Elke story wordt onafhankelijk beoordeeld; geeft { results: [ { id, status: "ok" } | { id, status: "failed", error } ] } terug.
Story-subresources
Section titled “Story-subresources”Alle member. List/GET op de meeste is (viewer).
| Methode | Pad | Body / notities |
|---|---|---|
| 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) } of { comment_emoji }. GET neemt fields= (toegestane lijst: comment_id, story_comment_id, story_id, comment_text, comment_emoji, member, created) plus 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? } — link_type ∈ relates_to, duplicates, blocks, is_blocked_by, pull_request, branch, other; GitHub-URL’s met /pull/ en /tree/ krijgen automatisch een type |
| GET / POST | /projects/{id}/stories/{sid}/reviews · PUT/DELETE …/reviews/{rid} | Aanmaken: { reviewer_id? / reviewer_agent_id?, comment? } — laat beide weg om jezelf toe te wijzen. Bijwerken: { status, comment? } |
| GET / POST | /projects/{id}/stories/{sid}/owners · DELETE …/owners/{mid} · DELETE …/owners/agents/{aid} | { member_id? / agent_id? } — laat beide weg om de aanroeper toe te voegen |
| 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-upload — video ≤ 200 MB, PDF / Word / Excel ≤ 25 MB, afbeeldingen / CSV / tekst ≤ 10 MB; list is (viewer) |
| GET / POST | /projects/{id}/stories/{sid}/link-attachments · DELETE …/link-attachments/{laid} | Linkbijlagen — een externe URL die naast de bestandsbijlagen wordt bewaard in plaats van als codelink |
| GET | /attachments/{token} · /api/avatars/{token} | Reads van een bijlage of een avatar, geadresseerd via een token — de URL’s die de API uitdeelt; geen X-TrackerToken nodig |
Dezelfde vorm als stories, zonder de toestandsmachine. member voor writes, (viewer) voor reads.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET / POST | /projects/{id}/epics · GET / PUT / DELETE …/epics/{eid} | Epics hebben een naam, een Markdown-beschrijving en een onderliggend label dat hun stories verbindt |
| GET / POST / PUT / DELETE | …/epics/{eid}/comments · …/comments/{cid} | Reacties op epics |
| GET / POST / DELETE | …/epics/{eid}/owners · …/followers (+ /agents/{aid}-varianten) | Owners en volgers, leden of agents — de owners van een epic worden doorgegeven aan zijn stories |
| GET / POST / DELETE | …/epics/{eid}/attachments (+ /json) · …/link-attachments | Bijlagen, met dezelfde limieten als bij stories |
| GET | /projects/{id}/analytics/epics · …/analytics/epics/{eid} | Voortgang per epic: burnup, doorvoer, gezondheid, voorspelling (viewer) |
Labels
Section titled “Labels”member voor writes, (viewer) voor reads.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET / POST | /projects/{id}/labels | Een label tonen / aanmaken |
| PUT / DELETE | /projects/{id}/labels/{lid} | Een label bijwerken / verwijderen |
| POST | /projects/{id}/labels/{lid}/archive | Een label archiveren (zacht verbergen) |
Iteraties
Section titled “Iteraties”Reads staan open voor elke projectrol, en anoniem op een openbaar project.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects/{id}/iterations | Iteraties tonen (≤ 500 per pagina; heeft een ETag en de vervolgheaders X-Tracker-Pagination-* wanneer afgekapt) |
| GET | /projects/{id}/iterations/{itid} | Eén iteratie |
| GET | /projects/{id}/iterations/first-preview | De datums die de eerste iteratie zou krijgen, getoond in de bevestiging bij het aanmaken |
| POST | /projects/{id}/iterations | Een handmatige iteratie aanmaken (member) |
| DELETE | /projects/{id}/iterations/{itid} | Een iteratie verwijderen (manager) |
| PUT | /projects/{id}/iterations/{itid}/velocity | De velocity van één iteratie overschrijven zonder de projectstrategie te wijzigen (manager) |
| GET | /projects/{id}/iterations/{itid}/done-stories | De geaccepteerde stories van een gesloten iteratie, gepagineerd |
Zoeken, metrics, voorkeuren
Section titled “Zoeken, metrics, voorkeuren”| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects/{id}/search?q=… | Krachtig zoeken — volledige tekst + kwalificatoren voor facetten / datumbereiken / personen (DSL in GitHub-stijl); geeft { results, total, limit, offset } terug. query is een alias voor q; limit= (standaard 50, max 1000) / offset= pagineren; sort= sorteert op relevance (standaard), created, created_asc, state of updated. (viewer) — zie de Gids |
| GET | /projects/{id}/metrics/{velocity,burndown,story-types,contributors} | De reeksen van de Metrics-pagina (viewer); epic-metrics staan onder /analytics/epics hierboven |
| GET | /projects/{id}/backlog/grouping | De geprojecteerde iteratiegroepen van de Backlog (viewer) |
| GET / PUT | /projects/{id}/preferences | Je bordvoorkeuren voor dit project — elke projectrol, alleen je eigen rij |
Events
Section titled “Events”| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects/{id}/events | Cursor-gepagineerde eventstream (member) — viewers krijgen 403 |
Query-parameters: since=<event_id>, types=story.created,story.transitioned,comment.added,…, limit= (≤ 500), cursor=. Het antwoord bevat next_cursor. Geef het laatste event_id dat je zag door als since om verder te gaan.
Meldingen
Section titled “Meldingen”De geünificeerde in-app meldingenfeed: volwaardige meldingsregels (reviewverzoeken, story-activiteit, uitnodigingen, …) samengevoegd met de @-vermeldingen-inbox tot één stream, nieuwste eerst. Feed-ids dragen een bronprefix (nt-… / sc-… / ec-…). Ledensessies en ea_user_*-sleutels lezen hun ledenregels; ea_agent_*-sleutels hun agentregels.
| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /me/notifications | Je meldingenfeed. Filters: unread=true, since_id=, kind= (mentions / reviews / stories / invitations); pagineer met cursor= / limit= |
| GET | /me/notifications/unread-count | Ongelezen totalen — { unread_count, by_category: { mentions, reviews, stories, invitations } } |
| POST | /me/notifications/read-all | Alles als gelezen markeren; geeft de verse tellers terug |
| POST | /me/notifications/{id}/ack | Eén item als gelezen markeren (idempotent) |
| POST | /me/notifications/{id}/accept | Een project-/organisatie-uitnodiging accepteren vanuit de feed (alleen leden-tokens) |
| POST | /me/notifications/{id}/decline | Een project-/organisatie-uitnodiging afwijzen (alleen leden-tokens) |
| GET | /me/notifications/resolve-invite?token=… | Een per e-mail ontvangen uitnodigingstoken herleiden tot je meldings-id — { "id": "nt-…" } of { "id": null } |
| GET | /me/notifications/stream | Live push — Server-Sent Events (text/event-stream); zie hieronder |
Het stream-endpoint is geen JSON-endpoint en staat daarom niet in de OpenAPI-specificatie: het houdt de verbinding open en stuurt een frame zonder payload ({"type":"notification","kind":…}) zodra er iets nieuws binnenkomt, als signaal aan de client om de feed opnieuw op te halen. Verbindingen worden serverzijdig na 45 minuten beëindigd — opnieuw verbinden en opnieuw authenticeren. Alleen ledensessies en ea_user_*-sleutels; ea_agent_*-sleutels krijgen 403.
Import (manager)
Section titled “Import (manager)”| Methode | Pad | Beschrijving |
|---|---|---|
| POST | /projects/{id}/import | Bestandsbronnen: source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat. Multipart file=. Synchroon — antwoordt met de resultaattellingen. |
| POST | /projects/{id}/import/json | JSON-body; source=github heeft geen bestand nodig — owner, repo, optioneel token, en de opt-in-vlaggen include_pull_requests / include_milestones / include_releases / include_dependencies; de bestandsbronnen sturen file_base64. Asynchroon: geeft 202 { import_id, status } terug. De server haalt op via GitHubs GraphQL-API, die anonieme aanroepers weigert, dus er bereikt altijd een token GitHub — het jouwe, of het gedeelde van de deployment. Zie de Gids. |
| GET | /projects/{id}/imports/{import_id} | Een job pollen: status loopt pending → fetching → writing → done | failed, met progress_current / progress_total tijdens het ophalen en de resultaattellingen bij done |
Er draait per project maar één import tegelijk; een tweede POST terwijl er een loopt, geeft 409 import_already_running. dry_run: true (JSON-body of dry_run=true multipart) toont een voorbeeld van elke bron: parseert, herleidt, ontdubbelt, geeft dezelfde { imported, skipped, errors, unmatched }-tellingen terug en draait daarna terug — er wordt niets weggeschreven. Limieten: 10 MiB body en 5.000 stories per import voor de bestandsbronnen (bij overschrijding van één van beide → 400, niets weggeschreven). De GitHub-bron kent geen plafond — die schrijft in blokken in plaats van één transactie. Herimporteren is idempotent per bron-id — reeds geïmporteerde regels worden overgeslagen, niet gedupliceerd.
Export
Section titled “Export”| Methode | Pad | Beschrijving |
|---|---|---|
| GET | /projects/{id}/export/formats | Geregistreerde formaten: { id, name, content_type, drops, includes_archived }. Elke projectrol. |
| GET | /projects/{id}/export/{format} | Download er één (manager). Uitwisseling: eat (volledige getrouwheid), jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json; documenten: pdf, docx. |
| GET | /projects/{id}/export/attachments | Elke bijlage als één doorbladerbare zip (bestanden behouden hun oorspronkelijke namen; JSON- + CSV-manifest) (manager). |
Documentexports (pdf, docx) nemen extra queryparameters: page_size= (letter standaard / a4 / legal / folio), from= / to= (grenzen van het story-venster — RFC 3339 of kaal YYYY-MM-DD; een story valt binnen het bereik wanneer zijn created of completed_at erin ligt), include_icebox= / include_backlog= (beide standaard false, zodat een deelbare export alleen gepland / lopend werk toont). De uitwisselings-CSV-formaten negeren ze.
Back-ups en herstel (manager)
Section titled “Back-ups en herstel (manager)”| Methode | Pad | Beschrijving |
|---|---|---|
| GET / POST | /projects/{id}/backups · GET …/backups/{snapshot_id} · …/backups/health | Snapshots tonen, er nu een maken, er een lezen, en de gezondheidssamenvatting van de bewaring |
| GET / POST | /projects/{id}/restores · POST …/restores/partial · GET …/restores/{restore_id} | Een hele snapshot herstellen, of geselecteerde tabellen eruit, en het herstel pollen |
De POSTs vallen onder de rate-limit-laag sensitive (hieronder).
MCP- en OAuth-provider
Section titled “MCP- en OAuth-provider”East Agile Tracker is een OAuth 2.1-provider voor MCP-clients. Een client ontdekt hem via /.well-known/oauth-authorization-server en /.well-known/oauth-protected-resource/mcp, stuurt je naar /oauth/authorize (de toestemmingspagina), wisselt de code in bij /oauth/token, en spreekt daarna MCP op /mcp met het resulterende ea_mcp_*-token. Autorisaties worden getoond en ingetrokken via /me/oauth_grants. De provider-endpoints hebben een eigen rate-limit-laag.
WebSocket
Section titled “WebSocket”wss://eastagiletracker.com/ws/control?token=<session JWT>Voor interactieve UI-afstandsbediening ({ "action": "get_state", "id": "req-1" }). Het token is een JWT van een browsersessie — een API-sleutel wordt vóór de upgrade geweigerd met 401. Geen datakanaal — alle reads/writes gaan via REST. Alleen single-instance; niet uitgewaaierd over replica’s.
Idempotentie
Section titled “Idempotentie”Write-endpoints (POST, PUT, DELETE) accepteren een Idempotency-Key-header. Dezelfde sleutel + dezelfde body speelt het gecachte antwoord opnieuw af (venster van 24 uur); dezelfde sleutel + een andere body geeft 409 idempotency_conflict terug. De sleutel is gebonden aan de inloggegevens die hem hebben verstuurd. Niet toegepast op GET/HEAD/OPTIONS, /openapi.json en /docs, /api/auth/*, of multipart-uploads op /attachments-paden. Antwoorden die geen domeinantwoord hebben bereikt, worden nooit gecacht — 401, 403, 404, 429 en elke 5xx — dus een retry na een van deze bereikt de handler; 400, 409, 412 en 422 zijn het antwoord van het domein en worden net als een succes opnieuw afgespeeld.
Paginering
Section titled “Paginering”List-endpoints accepteren cursor=<opaque> en limit=<n>. Indien ingesteld is het antwoord { "items": [...], "next_cursor": "<str|null>" }; geef next_cursor terug om te pagineren. Het plafond voor limit verschilt per endpoint: 200 voor stories, reacties en projecten; 500 voor events; 1000 voor zoeken en het auditlog.
Een gewone lijst (zonder cursor/limit) die zijn antwoord moest afkappen, meldt dat in headers — X-Tracker-Pagination-Truncated, X-Tracker-Pagination-Limit, X-Tracker-Pagination-Offset en X-Tracker-Pagination-Next-Offset; stuur de laatste terug als offset= voor de volgende pagina. Er is geen header met het totale aantal.
Veldprojectie
Section titled “Veldprojectie”List-endpoints accepteren fields= (komma-gescheiden) om alleen specifieke velden terug te geven. story_id wordt altijd opgenomen; een onbekende veldnaam geeft 400 validation_failed terug met de schendende namen in details.fields.
GET /projects/123/stories?fields=story_id,name,current_state,ownersFoutformaat
Section titled “Foutformaat”Elke JSON-fout heeft code en error; sommige voegen details toe:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`", "details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }| Status | code | Wanneer |
|---|---|---|
| 400 | invalid_parameter | foute invoer; bericht in error, geen details (meeste validatie: blank/lengte/null-byte/e-mail) |
| 400 | validation_failed | gestructureerde invoerfout; details.fields is een array van schendende veldnamen |
| 401 | unauthenticated | ontbrekend/ongeldig token |
| 403 | unauthorized_operation | geauthenticeerd maar onvoldoende rol |
| 404 | unfound_resource | niet gevonden — ook teruggegeven aan niet-members |
| 409 | conflict | resourceconflict (bijv. duplicaat) |
| 409 | idempotency_conflict | Idempotency-Key hergebruikt met een andere body |
| 409 | stale_write · import_already_running | de story is gewijzigd sinds je expected_updated_at · er loopt al een import |
| 412 | precondition_failed | If-Match kwam niet overeen met de huidige ETag van de resource; details bevat expected en current |
| 413 | request_too_large | de body overschrijdt de groottelimiet van de route |
| 422 | invalid_transition | ongeldige toestandsbeweging; details draagt { from, to, allowed } |
| 429 | rate_limited | te veel verzoeken vanaf dit IP op een route met rate limit; Retry-After-header |
| 500 | internal_error | serverfout — generiek bericht; veilig om opnieuw te proberen |
| 503 | not_configured | de deployment mist de integratie die deze route nodig heeft (sms, objectopslag, …) |
details.fields is een JSON-array van veldnamen (bijv. ["to"]), soms met extra sleutels zoals max. Er is geen veld→bericht-map.
{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }Rate limits
Section titled “Rate limits”Per client-IP, op een handvol routes; geauthenticeerd API-verkeer elders kent geen rate limit. Standaardwaarden (elk paar is het aanhoudende tempo en de burst, instelbaar door de beheerder):
- Auth —
/api/auth/*: 0,5 req/s, burst 20. - OAuth provider —
/oauth/*: 1 req/s, burst 60. - Public —
/api/contact: 0,2 req/s, burst 10. - Feedback —
/api/feedback: drie gestapelde lagen — één inzending per 15 s, 10 per uur, 36 per dag. - Avatars — de avatar-redirect zonder authenticatie: 20 req/s, burst 200.
- Sensitive — de
POSTs voor back-up en herstel: ~0,002 req/s, burst 5.
Een overschreden limiet geeft 429 terug met een Retry-After-header en de standaard JSON-foutenvelop, code: "rate_limited".