Aller au contenu

Spécification de l'API

La référence complète des endpoints REST. Pour les tutoriels et les exemples, voir le Guide de l’API.

Tout ce qu’un membre de projet peut faire dans l’interface web est disponible ici — la SPA consomme cette même API. Les opérations nécessitant le rôle propriétaire sont marquées (owner) ; tout le reste ne requiert que l’appartenance au projet (ou, pour les lectures marquées (viewer), n’importe quel niveau d’accès).

https://eastagiletracker.com/api/v1

https://api.eastagiletracker.com/api/v1 sert l’API identique. Toutes les requêtes et réponses sont en JSON, à l’exception de quelques endpoints d’envoi de fichiers qui acceptent le multipart.

Chaque requête authentifiée envoie une clé d’API via l’un des moyens suivants :

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

Les clés utilisateur commencent par ea_user_. Les clés d’agent commencent par ea_agent_. Voir Guide de l’API → Deux types de clés.

Endpoints non authentifiés : /openapi.json, /docs, les endpoints /auth/*, et les recherches de données de référence (/story_types, /story_states, /effort_scales, …). /meta est authentifié — n’importe quelle clé valide fonctionne, mais il n’est pas restreint à un projet (une clé d’agent liée à un projet y accède également).

Trois niveaux contrôlent l’accès aux endpoints restreints à un projet :

NiveauQui passeOpérations types
viewerviewer, member, ownerlectures (lister/obtenir des stories, recherche, analyses)
membermember, ownertoutes les écritures sur les éléments de travail (stories, tâches, commentaires, …)
ownerowner uniquementparamètres du projet, gestion des membres, clés d’agent, suppression, import, journal d’audit

Un non-membre reçoit 404 unfound_resource (et non 403) sur les chemins de projet, de sorte que les identifiants de projet ne sont pas énumérables.

MéthodeCheminDescription
GET/openapi.jsonLa spécification OpenAPI 3 en direct. Non authentifié.
GET/docsSwagger UI. Non authentifié.
GET/metaIdentité de l’appelant (auth.kind/key_id/agent_id/project_id) + le graphe de transitions par type de story. Authentifié (n’importe quelle clé valide ; non restreint à un projet). À appeler en premier.

Ces opérations agissent sur l’appelant et ne nécessitent qu’une clé valide (aucun rôle de projet).

MéthodeCheminDescription
POST/auth/registerEnregistrer un nouveau compte
POST/auth/loginSe connecter, renvoie un jeton de session
POST/auth/logoutSe déconnecter
POST/auth/forgot-passwordDemander un e-mail de réinitialisation du mot de passe
POST/auth/reset-passwordUtiliser un jeton de réinitialisation pour définir un nouveau mot de passe
GET/auth/verify-emailVérifier une adresse e-mail
POST/auth/accept-invite/lookupRésoudre un jeton d’invitation → e-mail (non authentifié)
POST/auth/accept-inviteAccepter une invitation à un projet (après authentification)
GET/meProfil de l’utilisateur actuel
PUT/meMettre à jour le profil
DELETE/meSupprimer le compte
PUT/me/passwordChanger le mot de passe
PUT/me/settingsMettre à jour les paramètres (thème, préférences de notification)
POST/me/avatarTéléverser un avatar (multipart)
POST/me/api-token/regenerateRégénérer votre jeton d’API — invalide les sessions/clés existantes
GET/me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id}Gérer les clés d’API utilisateur (ea_user_)
GET/me/activityVotre activité sur tous les projets
GET/me/data-exportAuto-export RGPD de vos données
GET/me/consent · POST /me/consentLire / enregistrer le consentement ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptDocuments clickwrap en attente / enregistrer l’acceptation
POST/contact · POST /feedback · POST /feedback/with-screenshotContact + retours dans l’application

Recherches sur les données de référence utilisées lors de la création/estimation des stories. Identifiants stables.

MéthodeCheminDescription
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scaleséchelles d’estimation disponibles
GET/effort_scales/{scale_id}/valuesles valeurs de points d’une échelle
MéthodeCheminDescription
GET/projectsLister vos projets
POST/projectsCréer un projet
GET/projects/{id}Obtenir les détails du projet (viewer)
PUT/projects/{id}Mettre à jour les paramètres du projet (owner)
DELETE/projects/{id}Supprimer un projet (owner)
GET/projects/{id}/audit-logFlux d’activité du projet (owner)
GET/projects/{id}/eventsFlux d’événements paginé par curseur (viewer) — voir Événements
MéthodeCheminDescription
GET/projects/{id}/membershipsLister les membres (viewer)
POST/projects/{id}/membershipsInviter un membre par e-mail (owner)
PUT/projects/{id}/memberships/{mid}Mettre à jour le rôle (owner)
DELETE/projects/{id}/memberships/{mid}Retirer un membre (owner)
GET / POST/projects/{id}/agent_keysLister / créer des clés d’agent (owner)
DELETE/projects/{id}/agent_keys/{kid}Révoquer une clé d’agent (owner)

Toutes les écritures sur les stories nécessitent le rôle member.

MéthodeCheminDescription
GET/projects/{id}/storiesLister les stories (paginées, filtrables) (viewer)
POST/projects/{id}/storiesCréer une story
GET/projects/{id}/stories/{sid}Obtenir une story (viewer)
PUT/projects/{id}/stories/{sid}Mettre à jour une story
DELETE/projects/{id}/stories/{sid}Supprimer une story
POST/projects/{id}/stories/{sid}/transitionsChanger d’état avec validation
POST/projects/{id}/stories/bulk_transitionFaire transiter plusieurs stories (1–100) à la fois
POST/projects/{id}/stories/bulk-deleteSupprimer plusieurs stories
POST/projects/{id}/stories/bulk-duplicateDupliquer plusieurs stories
POST/projects/{id}/stories/{sid}/duplicateDupliquer une story

Création (POST …/stories) : { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. labels accepte ["auth"] ou [{ "name": "auth" }] ; les labels inconnus sont créés. Valeurs par défaut : story_type=feature, current_state=unstarted.

Mise à jour (PUT …/stories/{sid}) : mêmes champs, tous optionnels, plus "position" (float) et "force_state_change" (bool).

Transition (POST …/transitions) : { "to": "<state>", "reason"? }. Le champ est to. Renvoie { story_id, state }. Déplacement illégal → 422 invalid_transition avec details: { from, to, allowed }.

Transition groupée (POST …/bulk_transition) : { "story_ids": [int,…] (1–100), "to": "<state>", "reason"? }. Chaque story est évaluée indépendamment ; renvoie { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.

Toutes en member. La liste/GET sur la plupart est en (viewer).

MéthodeCheminCorps / 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) } ou { 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? } — omettez les deux pour ajouter l’appelant
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}envoi multipart (≤ 2 Go chacun) ; la liste est en (viewer)

member pour les écritures, (viewer) pour les lectures.

MéthodeCheminDescription
GET / POST/projects/{id}/labelsLister / créer un label
PUT / DELETE/projects/{id}/labels/{lid}Mettre à jour / supprimer un label
POST/projects/{id}/labels/{lid}/archiveArchiver (masquer en douceur) un label
MéthodeCheminDescription
GET/projects/{id}/iterationsLister les itérations (member)
POST/projects/{id}/iterationsCréer une itération manuelle (owner)
DELETE/projects/{id}/iterations/{itid}Supprimer une itération (owner)
MéthodeCheminDescription
GET/projects/{id}/search?query=…Recherche par syntaxe de filtres (viewer) — voir le Guide
GET/projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections}Analyses (viewer). Le détail par itération prend ?iteration_id=
GET/projects/{id}/metrics/{velocity,burndown,story-types}Métriques (viewer)
GET / PUT/projects/{id}/preferencesVos préférences de tableau pour ce projet (member)
MéthodeCheminDescription
GET/projects/{id}/eventsFlux d’événements paginé par curseur (viewer)

Paramètres de requête : since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. La réponse inclut next_cursor. Transmettez le dernier event_id que vous avez vu via since pour reprendre.

MéthodeCheminDescription
POST/projects/{id}/import (+ /json)Envoi multipart. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
wss://eastagiletracker.com/ws/control?token=<key>

Pour la télécommande interactive de l’interface ({ "action": "get_state", "id": "req-1" }). Ce n’est pas un canal de données — toutes les lectures/écritures passent par REST. Mono-instance uniquement ; non distribué entre les réplicas.

Les endpoints d’écriture (POST, PUT, DELETE) acceptent un en-tête Idempotency-Key. La même clé + le même corps rejoue la réponse mise en cache (fenêtre de 24 heures) ; la même clé + un corps différent renvoie 409 idempotency_conflict. Non appliqué aux requêtes GET/HEAD/OPTIONS, /auth/*, ni aux chemins /attachments. Les réponses 5xx ne sont jamais mises en cache — un nouvel essai atteint le gestionnaire.

Les endpoints de liste acceptent cursor=<opaque> et limit=<n≤200>. Lorsqu’ils sont définis, la réponse est { "items": [...], "next_cursor": "<str|null>" } ; renvoyez next_cursor pour paginer. Certaines listes renvoient aussi un en-tête X-Tracker-Pagination-Total.

Les endpoints de liste acceptent fields= (séparés par des virgules) pour ne renvoyer que des champs spécifiques. story_id est toujours inclus ; un nom de champ inconnu renvoie 400 validation_failed avec les noms en cause dans details.fields.

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

Chaque erreur JSON possède code et error ; certaines ajoutent details :

{ "code": "invalid_transition",
"error": "Cannot move story from `unstarted` to `accepted`",
"details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }
StatutcodeQuand
400invalid_parameterentrée incorrecte ; message dans error, pas de details (la plupart des validations : vide/longueur/octet null/e-mail)
400validation_failederreur d’entrée structurée ; details.fields est un tableau de noms de champs en cause
401unauthenticatedjeton manquant/invalide
403unauthorized_operationauthentifié mais rôle insuffisant
404unfound_resourceintrouvable — également renvoyé aux non-membres
409conflictconflit de ressource (par ex. doublon)
409idempotency_conflictIdempotency-Key réutilisée avec un corps différent
422invalid_transitiondéplacement d’état illégal ; details contient { from, to, allowed }
500internal_errordéfaillance serveur — message générique ; peut être réessayé sans risque

details.fields est un tableau JSON de noms de champs (par ex. ["to"]), parfois accompagné de clés supplémentaires comme max. Il n’y a pas de correspondance champ→message.

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

Par clé (par IP pour les endpoints non authentifiés), seau à jetons GCRA :

  • Auth/auth/* : 0,5 req/s, rafale 20.
  • Public/contact, /feedback : 0,2 req/s, rafale 10.
  • Sensible — réinitialisation du mot de passe : ~0,002 req/s, rafale 5.

Une limite dépassée renvoie 429 Too Many Requests avec un en-tête Retry-After et un corps en texte brut (et non l’enveloppe d’erreur JSON).