Pular para o conteúdo

Especificação da API

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/v1

https://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.

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ívelQuem passaOperações típicas
viewerviewer, member, ownerleituras (listar/obter histórias, buscar, análises)
membermember, ownertodas as escritas de item de trabalho (histórias, tarefas, comentários, …)
ownerapenas ownerconfiguraçõ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.

MétodoCaminhoDescrição
GET/openapi.jsonA especificação OpenAPI 3 ao vivo. Não autenticado.
GET/docsSwagger UI. Não autenticado.
GET/metaIdentidade 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.

Estes atuam sobre o chamador e precisam apenas de uma chave válida (sem papel de projeto).

MétodoCaminhoDescrição
POST/auth/registerRegistra uma nova conta
POST/auth/loginFaz login, retorna um token de sessão
POST/auth/logoutFaz logout
POST/auth/forgot-passwordSolicita um e-mail de redefinição de senha
POST/auth/reset-passwordUsa um token de redefinição para definir uma nova senha
GET/auth/verify-emailVerifica um endereço de e-mail
POST/auth/accept-invite/lookupResolve um token de convite → e-mail (não autenticado)
POST/auth/accept-inviteAceita um convite de projeto (após autenticar)
GET/mePerfil do usuário atual
PUT/meAtualiza o perfil
DELETE/meExclui a conta
PUT/me/passwordAltera a senha
PUT/me/settingsAtualiza as configurações (tema, preferências de notificação)
POST/me/avatarFaz upload do avatar (multipart)
POST/me/api-token/regenerateRotaciona 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/activitySua atividade em todos os projetos
GET/me/data-exportAutoexportação GDPR dos seus dados
GET/me/consent · POST /me/consentLê / registra consentimento ({ consent_type, granted })
GET/legal/pending · POST /legal/acceptDocumentos clickwrap pendentes / registra aceitação
POST/contact · POST /feedback · POST /feedback/with-screenshotContato + feedback no aplicativo

Consultas de seed usadas ao criar/estimar histórias. IDs estáveis.

MétodoCaminhoDescrição
GET/story_typesfeature, bug, chore, release (+ allow_points)
GET/story_statesunstarted … accepted, rejected
GET/effort_scalesescalas de estimativa disponíveis
GET/effort_scales/{scale_id}/valuesos valores de pontos em uma escala
MétodoCaminhoDescrição
GET/projectsLista seus projetos
POST/projectsCria 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-logFluxo de atividade do projeto (owner)
GET/projects/{id}/eventsFluxo de eventos paginado por cursor (viewer) — veja Eventos
MétodoCaminhoDescrição
GET/projects/{id}/membershipsLista membros (viewer)
POST/projects/{id}/membershipsConvida 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_keysLista / emite chaves de agente (owner)
DELETE/projects/{id}/agent_keys/{kid}Revoga uma chave de agente (owner)

Todas as escritas de história precisam do papel member.

MétodoCaminhoDescrição
GET/projects/{id}/storiesLista histórias (paginadas, filtráveis) (viewer)
POST/projects/{id}/storiesCria 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}/transitionsAltera o estado com validação
POST/projects/{id}/stories/bulk_transitionTransiciona muitas histórias (1–100) de uma vez
POST/projects/{id}/stories/bulk-deleteExclui muitas histórias
POST/projects/{id}/stories/bulk-duplicateDuplica muitas histórias
POST/projects/{id}/stories/{sid}/duplicateDuplica 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 } ] }.

Todos member. Listar/GET na maioria é (viewer).

MétodoCaminhoCorpo / 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étodoCaminhoDescrição
GET / POST/projects/{id}/labelsLista / cria uma label
PUT / DELETE/projects/{id}/labels/{lid}Atualiza / exclui uma label
POST/projects/{id}/labels/{lid}/archiveArquiva (oculta suavemente) uma label
MétodoCaminhoDescrição
GET/projects/{id}/iterationsLista iterações (member)
POST/projects/{id}/iterationsCria uma iteração manual (owner)
DELETE/projects/{id}/iterations/{itid}Exclui uma iteração (owner)
MétodoCaminhoDescriçã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}/preferencesSuas preferências de quadro para este projeto (member)
MétodoCaminhoDescrição
GET/projects/{id}/eventsFluxo 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.

MétodoCaminhoDescrição
POST/projects/{id}/import (+ /json)Upload multipart. source=pivotal, jira, asana, gitlab, shortcut, trello, linear, plane, plane_json.
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.

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.

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.

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,owners

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"] } }
StatuscodeQuando
400invalid_parameterentrada inválida; mensagem em error, sem details (a maioria das validações: em branco/comprimento/byte nulo/e-mail)
400validation_failederro de entrada estruturado; details.fields é um array dos nomes dos campos problemáticos
401unauthenticatedtoken ausente/inválido
403unauthorized_operationautenticado, mas com papel insuficiente
404unfound_resourcenão encontrado — também retornado a não-membros
409conflictconflito de recurso (por exemplo, duplicata)
409idempotency_conflictIdempotency-Key reutilizado com um corpo diferente
422invalid_transitionmovimento de estado ilegal; details carrega { from, to, allowed }
500internal_errorfalha 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"] } }

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