Salta ai contenuti

Guida API

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.

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.

La finestra mostrata una sola volta dopo la creazione di una chiave API personale nelle impostazioni dell'account, con la chiave oscurata

Il modulo di creazione chiave della scheda Agent con un nome e il ruolo member selezionato, sotto le istruzioni di configurazione

Le differenze tra i due che generi tu:

Chiave utenteChiave agente
AmbitoTutti i tuoi progettiUn progetto specifico
Identità nell’audit logIl tuo nomeIl nome dell’agente
RuoloIl tuo ruolo in ciascun progettoImpostato alla creazione della chiave (viewer, member o manager — mai sopra il ruolo di chi genera la chiave)
RevocaRevoca una chiave; mantieni l’accesso tramite altre chiavi/sessioniRevoca o ruota una chiave; l’agente perde immediatamente l’accesso
Ideale perAutomazione personale, scriptAgenti IA che dovrebbero essere distinguibili da te nella cronologia

Authorization: Bearer … funziona anche se preferisci quello stile di header.

Ottieni i tuoi progetti:

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

Oppure, per una chiave agente, elenca il progetto a cui è vincolata:

Terminal window
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.

Terminal window
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.).

Terminal window
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.

L’endpoint di transizione valida il movimento richiesto e restituisce gli stati successivi consentiti in caso di errore:

Terminal window
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.

Terminal window
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.

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:

Terminal window
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.

Sposta molte storie in una sola volta. Ogni storia è giudicata indipendentemente; un movimento illegale non fa fallire gli altri.

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

Per gli agenti che vogliono reagire a ciò che fanno gli umani, fai il polling dell’endpoint degli eventi:

Terminal window
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.

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.

Terminal window
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.

  • 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.
QualificatoreEsempioCorrisponde a
type:type:bug,choretipo/i di storia
state:state:started,finishedstato/i del flusso di lavoro
label:label:"my label"una label
epic:epic:"Checkout"le storie di un epic
priority:priority:p1priorità
points:points:3 · points:1..5 · points:>3valore o intervallo di stima
iteration:iteration:42id dell’iterazione
created: updated: started: completed: release:created:2026-05-01..2026-06-01 · updated:>2026-06-01una data o un intervallo (granularità giornaliera); release: è la data di release della storia
owner: requester: follower: reviewer: commenter: mention:owner:claire · owner:@meuna persona per nome o email — membri e agenti, mention: incluso; @me sei tu
has:blockerhas:blockerha un blocker aperto
is:is:unestimated · is:icebox · is:backlog · is:blockedun 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 frase
type:bug,chore state:started bug o chore che sono started
owner:@me -label:wontfix miei, esclusa la label wontfix
points:3..8 created:2026-05-01..2026-06-01 stimati 3-8, creati a maggio
follower:tomas has:blocker tomas li segue ed è bloccato
is:backlog updated:>2026-06-01 elementi del backlog toccati dal 1° giugno

La 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.

La spec OpenAPI 3 live è su:

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

Swagger 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.

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.

Se stai facendo lo scripting di una migrazione in blocco:

Terminal window
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:

Terminal window
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.

Qualsiasi ruolo di progetto può elencare i formati; scaricarne uno è riservato all’owner:

Terminal window
# 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.csv

Id 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.

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 detailsdetails.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.

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.