A referência completa de endpoints REST. Para tutoriais e exemplos, veja o Guia da API.
Tudo o que um member do projeto pode fazer na interface web está disponível aqui — o SPA consome esta mesma API. As operações que exigem o papel de owner são marcadas com (owner); todo o resto precisa apenas de associação ao projeto (ou, para leituras marcadas com (viewer), qualquer nível de acesso).
https://eastagiletracker.com/api/v1https://api.eastagiletracker.com/api/v1 serve a API idêntica. Todas as requisições e respostas são JSON, exceto alguns endpoints de upload de arquivo que aceitam multipart.
Autenticação
Seção intitulada “Autenticação”Toda requisição autenticada envia uma chave de API por uma das opções:
X-TrackerToken: <key>Authorization: Bearer <key>
As chaves de usuário começam com ea_user_. As chaves de agente começam com ea_agent_. Veja Guia da API → Dois tipos de chave.
Endpoints não autenticados: /openapi.json, /docs, os endpoints /auth/* e as consultas de dados de referência (/story_types, /story_states, /effort_scales, …). /meta é autenticado — qualquer chave válida funciona, mas não tem escopo de projeto (uma chave de agente vinculada a um projeto também o alcança).
Três níveis controlam os endpoints com escopo de projeto:
| Nível | Quem passa | Operações típicas |
|---|---|---|
| viewer | viewer, member, owner | leituras (listar/obter histórias, buscar, análises) |
| member | member, owner | todas as escritas de item de trabalho (histórias, tarefas, comentários, …) |
| owner | apenas owner | configurações do projeto, gerenciamento de associação, chaves de agente, exclusão, importação, trilha de auditoria |
Um não-membro recebe 404 unfound_resource (não 403) em caminhos de projeto, então os IDs de projeto não são enumeráveis.
Endpoints autodescritivos
Seção intitulada “Endpoints autodescritivos”| Método | Caminho | Descrição |
|---|---|---|
| GET | /openapi.json | A especificação OpenAPI 3 ao vivo. Não autenticado. |
| GET | /docs | Swagger UI. Não autenticado. |
| GET | /meta | Identidade do chamador (auth.kind/key_id/agent_id/project_id) + o grafo de transições por tipo de história. Autenticado (qualquer chave válida; sem escopo de projeto). Chame isto primeiro. |
Conta / identidade
Seção intitulada “Conta / identidade”Estes atuam sobre o chamador e precisam apenas de uma chave válida (sem papel de projeto).
| Método | Caminho | Descrição |
|---|---|---|
| POST | /auth/register | Registra uma nova conta |
| POST | /auth/login | Faz login, retorna um token de sessão |
| POST | /auth/logout | Faz logout |
| POST | /auth/forgot-password | Solicita um e-mail de redefinição de senha |
| POST | /auth/reset-password | Usa um token de redefinição para definir uma nova senha |
| GET | /auth/verify-email | Verifica um endereço de e-mail |
| POST | /auth/accept-invite/lookup | Resolve um token de convite → e-mail (não autenticado) |
| POST | /auth/accept-invite | Aceita um convite de projeto (após autenticar) |
| GET | /me | Perfil do usuário atual |
| PUT | /me | Atualiza o perfil |
| DELETE | /me | Exclui a conta |
| PUT | /me/password | Altera a senha |
| PUT | /me/settings | Atualiza as configurações (tema, preferências de notificação) |
| POST | /me/avatar | Faz upload do avatar (multipart) |
| POST | /me/api-token/regenerate | Rotaciona seu token de API — invalida sessões/chaves existentes |
| GET | /me/api_keys · POST /me/api_keys · DELETE /me/api_keys/{id} | Gerencia chaves de API de usuário (ea_user_) |
| GET | /me/activity | Sua atividade em todos os projetos |
| GET | /me/data-export | Autoexportação GDPR dos seus dados |
| GET | /me/consent · POST /me/consent | Lê / registra consentimento ({ consent_type, granted }) |
| GET | /legal/pending · POST /legal/accept | Documentos clickwrap pendentes / registra aceitação |
| POST | /contact · POST /feedback · POST /feedback/with-screenshot | Contato + feedback no aplicativo |
Dados de referência (não autenticados)
Seção intitulada “Dados de referência (não autenticados)”Consultas de seed usadas ao criar/estimar histórias. IDs estáveis.
| Método | Caminho | Descrição |
|---|---|---|
| GET | /story_types | feature, bug, chore, release (+ allow_points) |
| GET | /story_states | unstarted … accepted, rejected |
| GET | /effort_scales | escalas de estimativa disponíveis |
| GET | /effort_scales/{scale_id}/values | os valores de pontos em uma escala |
Projetos
Seção intitulada “Projetos”| Método | Caminho | Descrição |
|---|---|---|
| GET | /projects | Lista seus projetos |
| POST | /projects | Cria um projeto |
| GET | /projects/{id} | Obtém detalhes do projeto (viewer) |
| PUT | /projects/{id} | Atualiza as configurações do projeto (owner) |
| DELETE | /projects/{id} | Exclui um projeto (owner) |
| GET | /projects/{id}/audit-log | Fluxo de atividade do projeto (owner) |
| GET | /projects/{id}/events | Fluxo de eventos paginado por cursor (viewer) — veja Eventos |
Membros e chaves de agente
Seção intitulada “Membros e chaves de agente”| Método | Caminho | Descrição |
|---|---|---|
| GET | /projects/{id}/memberships | Lista membros (viewer) |
| POST | /projects/{id}/memberships | Convida um membro por e-mail (owner) |
| PUT | /projects/{id}/memberships/{mid} | Atualiza o papel (owner) |
| DELETE | /projects/{id}/memberships/{mid} | Remove um membro (owner) |
| GET / POST | /projects/{id}/agent_keys | Lista / emite chaves de agente (owner) |
| DELETE | /projects/{id}/agent_keys/{kid} | Revoga uma chave de agente (owner) |
Histórias
Seção intitulada “Histórias”Todas as escritas de história precisam do papel member.
| Método | Caminho | Descrição |
|---|---|---|
| GET | /projects/{id}/stories | Lista histórias (paginadas, filtráveis) (viewer) |
| POST | /projects/{id}/stories | Cria uma história |
| GET | /projects/{id}/stories/{sid} | Obtém uma história (viewer) |
| PUT | /projects/{id}/stories/{sid} | Atualiza uma história |
| DELETE | /projects/{id}/stories/{sid} | Exclui uma história |
| POST | /projects/{id}/stories/{sid}/transitions | Altera o estado com validação |
| POST | /projects/{id}/stories/bulk_transition | Transiciona muitas histórias (1–100) de uma vez |
| POST | /projects/{id}/stories/bulk-delete | Exclui muitas histórias |
| POST | /projects/{id}/stories/bulk-duplicate | Duplica muitas histórias |
| POST | /projects/{id}/stories/{sid}/duplicate | Duplica uma história |
Criar (POST …/stories): { "name" (required), "story_type": "feature|bug|chore|release", "description"?, "estimate"?, "current_state"?, "icebox"?, "labels"? }. labels aceita ["auth"] ou [{ "name": "auth" }]; labels desconhecidas são criadas. Padrões: story_type=feature, current_state=unstarted.
Atualizar (PUT …/stories/{sid}): os mesmos campos, todos opcionais, mais "position" (float) e "force_state_change" (bool).
Transição (POST …/transitions): { "to": "<state>", "reason"? }. O campo é to. Retorna { story_id, state }. Movimento ilegal → 422 invalid_transition com details: { from, to, allowed }.
Transição em massa (POST …/bulk_transition): { "story_ids": [int,…] (1–100), "to": "<state>", "reason"? }. Cada história é julgada de forma independente; retorna { results: [ { id, status: "ok" } | { id, status: "failed", error } ] }.
Sub-recursos da história
Seção intitulada “Sub-recursos da história”Todos member. Listar/GET na maioria é (viewer).
| Método | Caminho | Corpo / observações |
|---|---|---|
| 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? } — omita ambos para adicionar o chamador |
| 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} | upload multipart (≤ 2 GB cada); listar é (viewer) |
member para escritas, (viewer) para leituras.
| Método | Caminho | Descrição |
|---|---|---|
| GET / POST | /projects/{id}/labels | Lista / cria uma label |
| PUT / DELETE | /projects/{id}/labels/{lid} | Atualiza / exclui uma label |
| POST | /projects/{id}/labels/{lid}/archive | Arquiva (oculta suavemente) uma label |
Iterações
Seção intitulada “Iterações”| Método | Caminho | Descrição |
|---|---|---|
| GET | /projects/{id}/iterations | Lista iterações (member) |
| POST | /projects/{id}/iterations | Cria uma iteração manual (owner) |
| DELETE | /projects/{id}/iterations/{itid} | Exclui uma iteração (owner) |
Busca, análises, métricas, preferências
Seção intitulada “Busca, análises, métricas, preferências”| Método | Caminho | Descrição |
|---|---|---|
| GET | /projects/{id}/search?query=… | Busca com sintaxe de filtro (viewer) — veja o Guia |
| GET | /projects/{id}/analytics/{overview,iteration,releases,activity,cycle-time,projections} | Análises (viewer). O detalhamento por iteração recebe ?iteration_id= |
| GET | /projects/{id}/metrics/{velocity,burndown,story-types} | Métricas (viewer) |
| GET / PUT | /projects/{id}/preferences | Suas preferências de quadro para este projeto (member) |
Eventos
Seção intitulada “Eventos”| Método | Caminho | Descrição |
|---|---|---|
| GET | /projects/{id}/events | Fluxo de eventos paginado por cursor (viewer) |
Parâmetros de consulta: since=<event_id>, types=story.created,story.transitioned,comment.created,…, limit=, cursor=. A resposta inclui next_cursor. Passe o último event_id que você viu como since para retomar.
Importação (owner)
Seção intitulada “Importação (owner)”| Método | Caminho | Descrição |
|---|---|---|
| POST | /projects/{id}/import (+ /json) | Upload multipart. source= ∈ pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json. |
WebSocket
Seção intitulada “WebSocket”wss://eastagiletracker.com/ws/control?token=<key>Para controle remoto interativo da interface ({ "action": "get_state", "id": "req-1" }). Não é um canal de dados — todas as leituras/escritas passam pelo REST. Apenas instância única; não distribuído entre réplicas.
Idempotência
Seção intitulada “Idempotência”Os endpoints de escrita (POST, PUT, DELETE) aceitam um cabeçalho Idempotency-Key. A mesma chave + o mesmo corpo reproduz a resposta em cache (janela de 24 horas); a mesma chave + um corpo diferente retorna 409 idempotency_conflict. Não se aplica a GET/HEAD/OPTIONS, /auth/* ou caminhos /attachments. As respostas 5xx nunca são armazenadas em cache — uma nova tentativa alcança o handler.
Paginação
Seção intitulada “Paginação”Os endpoints de listagem aceitam cursor=<opaque> e limit=<n≤200>. Quando definidos, a resposta é { "items": [...], "next_cursor": "<str|null>" }; passe next_cursor de volta para paginar. Algumas listas também retornam um cabeçalho X-Tracker-Pagination-Total.
Projeção de campos
Seção intitulada “Projeção de campos”Os endpoints de listagem aceitam fields= (separados por vírgula) para retornar apenas campos específicos. story_id é sempre incluído; um nome de campo desconhecido retorna 400 validation_failed com os nomes problemáticos em details.fields.
GET /projects/123/stories?fields=story_id,name,current_state,ownersFormato de erro
Seção intitulada “Formato de erro”Todo erro JSON tem code e error; alguns adicionam details:
{ "code": "invalid_transition", "error": "Cannot move story from `unstarted` to `accepted`", "details": { "from": "unstarted", "to": "accepted", "allowed": ["started"] } }| Status | code | Quando |
|---|---|---|
| 400 | invalid_parameter | entrada inválida; mensagem em error, sem details (a maioria das validações: em branco/comprimento/byte nulo/e-mail) |
| 400 | validation_failed | erro de entrada estruturado; details.fields é um array dos nomes dos campos problemáticos |
| 401 | unauthenticated | token ausente/inválido |
| 403 | unauthorized_operation | autenticado, mas com papel insuficiente |
| 404 | unfound_resource | não encontrado — também retornado a não-membros |
| 409 | conflict | conflito de recurso (por exemplo, duplicata) |
| 409 | idempotency_conflict | Idempotency-Key reutilizado com um corpo diferente |
| 422 | invalid_transition | movimento de estado ilegal; details carrega { from, to, allowed } |
| 500 | internal_error | falha do servidor — mensagem genérica; seguro para tentar novamente |
details.fields é um array JSON de nomes de campos (por exemplo, ["to"]), às vezes com chaves extras como max. Não há um mapa de campo→mensagem.
{ "code": "validation_failed", "error": "unknown field(s): foo", "details": { "fields": ["foo"] } }Limites de taxa
Seção intitulada “Limites de taxa”Por chave (por IP para endpoints não autenticados), token bucket GCRA:
- Auth —
/auth/*: 0,5 req/s, burst 20. - Public —
/contact,/feedback: 0,2 req/s, burst 10. - Sensitive — redefinição de senha: ~0,002 req/s, burst 5.
Um limite excedido retorna 429 Too Many Requests com um cabeçalho Retry-After e um corpo de texto puro (não o envelope de erro JSON).