L’API di East Agile Tracker è progettata tanto per gli agenti quanto per gli umani. Tutto ciò che puoi fare nell’interfaccia, puoi farlo via API — e alcune cose che l’interfaccia non espone sono lì anch’esse.
Questa guida ti porta da zero allo “scripting del tuo backlog” in meno di dieci minuti. Per il riferimento completo degli endpoint, vedi Specifica API.
Tre tipi di credenziali
Sezione intitolata “Tre tipi di credenziali”Ti autentichi con una chiave nell’header X-TrackerToken. Ci sono due tipi di chiave che generi tu stesso, e un terzo che un client MCP ottiene per te:
- Chiavi utente (
ea_user_…) — Agiscono come te. Creale in Account Settings → API Keys. Usale per script personali, strumenti da CLI, integrazioni. - Chiavi agente (
ea_agent_…) — Agiscono come un agente con nome in un progetto. Creale in Project Settings → Agents. Usale per agenti IA — Claude Code, Codex, il tuo — che dovrebbero partecipare al progetto come compagni di squadra con nome. - Token MCP (
ea_mcp_…) — Token di accesso OAuth 2.1 rilasciati a un client MCP (Claude, un IDE) dopo che lo hai approvato nella pagina di consenso. Agiscono come te, e puoi revocarli in Account Settings → Connected apps.


Le differenze tra i due che generi tu:
| Chiave utente | Chiave agente | |
|---|---|---|
| Ambito | Tutti i tuoi progetti | Un progetto specifico |
| Identità nell’audit log | Il tuo nome | Il nome dell’agente |
| Ruolo | Il tuo ruolo in ciascun progetto | Impostato alla creazione della chiave (viewer, member o manager — mai sopra il ruolo di chi genera la chiave) |
| Revoca | Revoca una chiave; mantieni l’accesso tramite altre chiavi/sessioni | Revoca o ruota una chiave; l’agente perde immediatamente l’accesso |
| Ideale per | Automazione personale, script | Agenti IA che dovrebbero essere distinguibili da te nella cronologia |
Authorization: Bearer … funziona anche se preferisci quello stile di header.
Ciao, API
Sezione intitolata “Ciao, API”Ottieni i tuoi progetti:
curl https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: $TRACKER_TOKEN"Oppure, per una chiave agente, elenca il progetto a cui è vincolata:
curl https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: ea_agent_xxxxx"L’API è JSON, in stile REST, versionata su /api/v1/. Stesse forme per umani e agenti.
Creare un progetto
Sezione intitolata “Creare un progetto”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 }'La risposta include il project_id ed eventuali default applicati dal server (scala di stima, done state, ecc.).
Creare una storia
Sezione intitolata “Creare una storia”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 è l’etichetta del valore della scala, come stringa — "3", oppure "13" sulla scala Fibonacci — perché deve corrispondere a un punto della scala del progetto. Un numero JSON viene rifiutato.
Far muovere una storia lungo il ciclo di vita
Sezione intitolata “Far muovere una storia lungo il ciclo di vita”L’endpoint di transizione valida il movimento richiesto e restituisce gli stati successivi consentiti in caso di errore:
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" }'Il campo è to (non to_state). Se il movimento è illegale — diciamo che hai provato a saltare da unstarted dritto ad accepted — la risposta è 422 invalid_transition con dettagli d’errore strutturati:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`", "details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] }}Questa è una delle piccole cose che rendono l’API a misura di agente: un agente può leggere details.allowed e scegliere il movimento successivo giusto senza dover analizzare prosa.
rejected è terminale per l’endpoint di transizione. Per rimettere al lavoro una storia rifiutata, POST …/stories/{sid}/restart; POST …/stories/{sid}/reject è la forma a verbo del rifiuto di una storia delivered.
Commentare una storia
Sezione intitolata “Commentare una storia”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." }'Il commento è attribuito a chiunque possieda la chiave API — se è una chiave agente, l’autore del commento è l’agente.
Scritture idempotenti
Sezione intitolata “Scritture idempotenti”Ogni endpoint di scrittura accetta un header Idempotency-Key. Riprova la stessa chiave con lo stesso body e riottieni la stessa risposta. Riprova la stessa chiave con un body diverso e ottieni un 409 idempotency_conflict:
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" }'Questo è cruciale per gli agenti nei loop di retry — vai in crash a metà scrittura, riprova con la stessa chiave, nessuna storia duplicata.
Transizioni in blocco
Sezione intitolata “Transizioni in blocco”Sposta molte storie in una sola volta. Ogni storia è giudicata indipendentemente; un movimento illegale non fa fallire gli altri.
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" }'Seguire lo stream di eventi
Sezione intitolata “Seguire lo stream di eventi”Per gli agenti che vogliono reagire a ciò che fanno gli umani, fai il polling dell’endpoint degli eventi:
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"La risposta è uno stream di eventi paginato a cursore con l’attore, la risorsa e la modifica. Ogni evento ha un ID; passa l’ultimo ID che hai visto come since per riprendere da dove avevi lasciato. Nessun webhook, nessuno scraping, nessun evento perso. Lo stream richiede il ruolo member — un viewer riceve 403.
Cercare con la sintassi dei filtri
Sezione intitolata “Cercare con la sintassi dei filtri”GET /projects/{id}/search?q=<query> esegue una potente ricerca full-text +
strutturata sulle storie del progetto. Il linguaggio di query è modellato sui
qualificatori della ricerca issue di GitHub — quindi la sintassi che tu (o un
agente IA) già conosci da GitHub si applica quasi del tutto.
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'La risposta è un involucro JSON, con le storie ordinate per rilevanza:
{ "results": [ /* canonical story objects */ ], "total": 42, "limit": 50, "offset": 0 }total è il conteggio completo delle corrispondenze, non la dimensione della
pagina. Pagina con limit (default 50, max 1000) e offset; ordina con
sort=relevance (default), created, created_asc, updated o state.
Grammatica
Sezione intitolata “Grammatica”- Testo libero corrisponde a titolo, riferimento e descrizione di una storia
(full-text, con stemming e ranking). Racchiudi una frase esatta tra
"virgolette". - Qualificatori sono
field:value. Separa le alternative con una virgola (OR all’interno di un campo):type:bug,chore. Separa i qualificatori con spazi (AND tra di loro). - Nega qualsiasi termine o qualificatore con un
-iniziale:-label:wontfix. - Intervalli per date e punti: inclusivo
a..b, oppure aperto>x/<x.
Qualificatori
Sezione intitolata “Qualificatori”| Qualificatore | Esempio | Corrisponde a |
|---|---|---|
type: | type:bug,chore | tipo/i di storia |
state: | state:started,finished | stato/i del flusso di lavoro |
label: | label:"my label" | una label |
epic: | epic:"Checkout" | le storie di un epic |
priority: | priority:p1 | priorità |
points: | points:3 · points:1..5 · points:>3 | valore o intervallo di stima |
iteration: | iteration:42 | id dell’iterazione |
created: updated: started: completed: release: | created:2026-05-01..2026-06-01 · updated:>2026-06-01 | una data o un intervallo (granularità giornaliera); release: è la data di release della storia |
owner: requester: follower: reviewer: commenter: mention: | owner:claire · owner:@me | una persona per nome o email — membri e agenti, mention: incluso; @me sei tu |
has:blocker | has:blocker | ha un blocker aperto |
is: | is:unestimated · is:icebox · is:backlog · is:blocked | un flag |
mywork: è un alias di owner: — mywork:me equivale a owner:@me. Il vecchio qualificatore scheduled: è ritirato e viene ignorato silenziosamente; usa release:.
L’OR con virgola (type:bug,chore) vale per i qualificatori a faccetta; i qualificatori sulle persone (owner: requester: follower: reviewer: commenter: mention:) accettano un solo valore.
payment crash testo libero "payment" AND "crash""exact phrase" una frasetype:bug,chore state:started bug o chore che sono startedowner:@me -label:wontfix miei, esclusa la label wontfixpoints:3..8 created:2026-05-01..2026-06-01 stimati 3-8, creati a maggiofollower:tomas has:blocker tomas li segue ed è bloccatois:backlog updated:>2026-06-01 elementi del backlog toccati dal 1° giugnoLa stessa stringa di query pilota la casella di ricerca della board (che apre una colonna di risultati live) e questa API — una sola grammatica per umani e agenti. La ricerca nel contenuto di commenti, task e blocker è nella roadmap; oggi il testo libero copre titolo, riferimento e descrizione della storia stessa.
Scoprire l’API
Sezione intitolata “Scoprire l’API”La spec OpenAPI 3 live è su:
https://api.eastagiletracker.com/api/v1/openapi.jsonSwagger UI è su:
https://api.eastagiletracker.com/api/v1/docs//openapi.json e /docs non sono autenticati — un agente può leggere il contratto prima di avere una chiave. Una volta che ne possiede una, /api/v1/meta (che richiede una chiave valida) restituisce la sua identità e il grafo delle transizioni per ciascun tipo di storia; anche i lookup dei dati di riferimento (/story_types, /story_states, /effort_scales, /priority_scales) non sono autenticati. Insieme consentono agli agenti di rispondere a “cosa posso fare qui?” senza 403 per tentativi ed errori.
L’openapi.json servito include gli schemi dei request body per gli endpoint di scrittura, compreso il maxLength di ogni campo, così un client può validare prima di inviare. La Specifica riassume le stesse forme.
Controllo WebSocket
Sezione intitolata “Controllo WebSocket”Per l’automazione interattiva — pilotare una sessione browser autenticata da uno script, o controllare a distanza l’interfaccia per i tutorial — c’è un canale WebSocket:
const ws = new WebSocket('wss://eastagiletracker.com/ws/control?token=SESSION_JWT')ws.send(JSON.stringify({ action: 'get_state', id: 'req-1' }))Il token è il JWT della sessione browser, non una chiave API — una chiave ea_user_* o ea_agent_* viene rifiutata prima dell’upgrade. La maggior parte degli utenti non ne ha mai bisogno; è lì per i casi in cui REST non basta.
Importare da un altro tracker
Sezione intitolata “Importare da un altro tracker”Se stai facendo lo scripting di una migrazione in blocco:
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"Sorgenti da file supportate: pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json, eat (l’export nativo di East Agile Tracker — il formato per il round-trip). L’endpoint multipart è sincrono e risponde con i conteggi del risultato.
GitHub importa dall’API anziché da un file, tramite l’endpoint JSON — niente file, solo le coordinate del repository:
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 }'L’endpoint JSON è asincrono: risponde 202 con { "import_id", "status" } e tu interroghi GET /projects/{id}/imports/{import_id} finché il job non raggiunge done o failed. Per ogni progetto gira una sola importazione alla volta — una seconda chiamata mentre una è in corso dà 409 import_already_running. L’intero ciclo, con i campi di avanzamento del job, è in Popolare un progetto da un repo GitHub.
Il token è opzionale nella richiesta, ma il recupero si autentica sempre — passa dall’API GraphQL di GitHub, che non ha un livello anonimo. Ometti token e il server sostituisce il proprio token di piattaforma: solo repository pubblici, condiviso da ogni chiamante e rifiutato con import_github_shared_quota_low quando il suo budget GraphQL scende sotto i 500 punti. Un repository privato, o un deployment che non ha configurato alcun token di piattaforma (import_github_no_token), richiede il tuo. Qualunque token venga usato, serve solo per le chiamate a GitHub e non viene mai memorizzato né restituito. Il dettaglio completo, incluso il tetto REST non autenticato di 60 richieste di GitHub, è in Popolare un progetto da un repo GitHub.
Anteprima dry-run. Aggiungi "dry_run": true (JSON) oppure -F "dry_run=true" (multipart) a qualsiasi sorgente. L’importazione analizza, risolve e deduplica esattamente come un’esecuzione reale, produce gli stessi conteggi di risultato (imported, skipped, errors, unmatched), poi annulla tutto — non viene scritto nulla. Sull’endpoint JSON i conteggi arrivano sul job interrogato, dry run o meno.
Limiti. Il body di un upload è limitato a 10 MiB, e una singola importazione a 5.000 storie; superare l’uno o l’altro dà un 400 senza scrivere nulla. Reimportare un file è sicuro — le righe già importate (individuate dall’id di origine) vengono saltate, non duplicate.
Esportare un progetto
Sezione intitolata “Esportare un progetto”Qualsiasi ruolo di progetto può elencare i formati; scaricarne uno è riservato all’owner:
# I formati di export registrati: { id, name, content_type, drops, includes_archived }curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/formats \ -H "X-TrackerToken: $TRACKER_TOKEN"
# Scarica un formato (eat è il CSV per il round-trip a piena fedeltà)curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/export/eat \ -H "X-TrackerToken: $TRACKER_TOKEN" -o project-export.csvId dei formati di interscambio: eat, jira, pivotal, shortcut, trello, asana, gitlab, linear, plane, plane_json, più i formati documento pdf e docx. Ogni allegato è scaricabile come un unico zip da GET /projects/{id}/export/attachments.
Formato degli errori
Sezione intitolata “Formato degli errori”Tutti gli errori sono JSON con come minimo:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`"}Molte risposte d’errore includono anche un oggetto details — details.fields (un array di nomi di campo offendenti) su validation_failed, e details.allowed (accanto a from/to) su 422 invalid_transition. Usali. Un 429 rate_limited porta un header Retry-After nello stesso involucro JSON.
Paginazione
Sezione intitolata “Paginazione”Gli endpoint di elenco accettano limit e cursor. Il cursore è opaco; passa il next_cursor della risposta precedente. Il tetto di limit è per endpoint — 200 su storie, commenti e progetti, 500 sugli eventi, 1000 sulla ricerca e sull’audit log. Un elenco semplice (senza cursore) che ha dovuto troncare la risposta lo dichiara negli header: X-Tracker-Pagination-Truncated, -Limit, -Offset e -Next-Offset, che restituisci come offset= per la pagina successiva. Non esiste un header con il conteggio totale.
Cosa viene dopo
Sezione intitolata “Cosa viene dopo”- Specifica API — Ogni endpoint, ogni verbo, ogni forma.
- Istruzioni operative → Agenti — Lato interfaccia: generare chiavi agente, dare nomi agli agenti, revocare.
- Introduzione — Concetti dietro l’API: storie, stati, iterazioni, velocity, agenti.