API REST

Issues

Buscar, criar, editar, comentar, anexar, mover, vincular e importar issues.

  • GET /issues (tracker:read): busca. Query: project, status (chaves do fluxo do projeto), category (todo, in_progress, done), severity, priority, type, nature (problem, improvement, task: a natureza do tipo, que vale em qualquer projeto) (listas separadas por vírgula), label, assignee (me, none ou id), open_only (true), blocked_only (true: só as com a marca de bloqueio), q (texto livre: código, título, descrição e comentários), query (consulta avançada, ex.: projeto = MOB e status = Aberto e responsavel = eu), saved_filter (nome de um filtro salvo), created_from e created_to (AAAA-MM-DD), limit (até 50), offset, sort (code, title, status, severity, assignee ou updated), order (asc ou desc) e done_last (true: concluídas, grupo done, no fim, antes da ordem pedida). Sem sort, mais recentes primeiro. A API não esconde nada por padrão: sem filtro de status, vêm também as concluídas. A lista de tarefas da tela esconde as concluídas até a pessoa pedir "Mostrar concluídas" (e aí as mostra no fim); para reproduzir, use open_only=true ou done_last=true. No MCP, os mesmos open_only e done_last de search_issues. Cada issue vem com close_reason (em Fechado), blocked e blocked_reason (a marca de bloqueio), retest_failed (reprovada no último reteste e ainda não aprovada), assignee, qa_owner, sprint, release, releases (todas as entregas como "GOP 1.4.8-ota002", a principal primeiro), module, parent e epic (códigos), labels, start_date, due_date, external_id e edit_version (para PATCH e o lote, sem abrir cada issue); include=description,custom_fields acrescenta a descrição e os campos personalizados.
  • GET /search?q=<texto> (tracker:read): "isto já aconteceu?". Busca híbrida, pelo sentido e pelas palavras, em issues (com os comentários) e, com kinds=issue,ticket, nos chamados do Atendimento (só de quem atende). issue=<código> no lugar de q busca as parecidas com aquela issue, sem ela. project, open_only (true) e limit (até 30, padrão 8). Cada resultado traz kind, code, title, status_label, open, project, score (0 a 1), similarity (do vetor, quando achou pelo sentido), matched_by (text, meaning), likely_duplicate e url; mode é hybrid ou text (só pelas palavras); semantic diz se a busca por significado está ligada na empresa: on, indexed (quantos itens já estão no índice; cresce a cada minuto enquanto o índice se monta) e, desligada, reason (no_vector: a busca pelo sentido não está disponível neste servidor; no_key: aqua desligada, chave própria da empresa ou sem créditos de IA). Com on true e mode text, a busca pelo sentido não respondeu a tempo ou a pessoa passou do limite de buscas pelo sentido. Com issue, a busca parte da ficha de contexto que a aqua escreve de cada issue (aqua_context de GET /issues/{ref}). explain (padrão true; false devolve só a lista da busca, mais rápida) faz a aqua conferir cada achado contra a referência: tira o que só divide palavras e preenche relation (same: o mesmo problema; related: relacionado) e reason (a ligação numa frase); explained diz se ela conferiu (sem a aqua ligada, false e a lista da busca). Antes de criar uma issue, procure aqui para não duplicar (veja "Já aconteceu antes?" acima). No MCP: search_similar.
  • GET /issues/{código ou id} (tracker:read): a issue com status (key, label, category, close_reason em Fechado com key e label, e retest_failed_at quando foi reprovada no último reteste), blocked (since e reason, ou null), releases (todas as entregas, a principal primeiro com primary: true), pai e epic (o pai, ou o pai do pai numa subtarefa), filhas, sprint, pontos, estimativa, datas, campos personalizados, labels, vínculos, quem acompanha, comentários, histórico (from/to com os valores gravados e text, como na tela: nomes de releases, pessoas e sprints; from_label/to_label quando a tela mostra de/para), aqua_summary (o último resumo da conversa feito pela aqua na tela: happened, pending, ball com quem está com a bola e outdated quando houve comentários ou mudanças depois; null sem resumo), aqua_context (a ficha de contexto que a aqua escreve sozinha, em segundo plano, para o "Já aconteceu antes?": summary com o problema em palavras neutras, area, terms, generated_at e outdated quando a issue mudou e a ficha ainda vai ser refeita; null com a aqua desligada ou antes da primeira ficha) e edit_version (para PATCH). ?fields=status,releases traz só essas partes (id, code, url e edit_version sempre): bom para conferir muitas issues sem trazer comentários e histórico.
  • GET /issues/{código ou id}/comments (tracker:read): todos os comentários, cada um com id, author, text, at, edited_at, deleted (quem excluiu e quando; o texto vem vazio), mentions e as respostas (replies).
  • POST /issues/{código ou id}/comments (tracker:write): comenta, {"text": "...", "parent_id": "<id do comentário respondido>"}. @Nome menciona alguém do projeto. "attachments": [{"file_name": "relatorio.md", "content_base64": "..."}, {"url": "https://..."}] anexa até 5 arquivos ao comentário (14 MB somados), com as regras dos anexos abaixo; um anexo com problema recusa o comentário inteiro. 201 com o id e os attachments. No GET, cada comentário traz os seus attachments (id, name, type, size_bytes, download_url).
  • GET /issues/{código ou id}/evidences (tracker:read): os anexos (evidências) da issue, do mais antigo ao mais novo, cada um com id, name, type, size_bytes, description, comment_id (quando veio num comentário) e download_url. GET /evidences/{id} (tracker:read) baixa o arquivo, com o mesmo token (aceita Range). Pelo MCP, cujo token não vale aqui, get_attachment lê o conteúdo: texto (md, csv, txt, log, json) e imagem (png, jpg, webp até 5 MB).
  • POST /issues/{código ou id}/evidences (tracker:write): anexa um arquivo, de três jeitos: multipart/form-data com o arquivo no campo file (e description e comment_id opcionais, em texto); JSON {"file_name": "avaliacao.md", "content_base64": "...", "description": "..."} (aceita o prefixo data:...;base64,); ou JSON {"url": "https://exemplo.com/print.png"}, que o tracker baixa (só https e endereço público, até 3 redirecionamentos e 20 s; a URL não fica guardada; file_name opcional troca o nome). Formatos pela extensão do nome: png, jpg, jpeg, webp, mp4, mov, pdf, json, txt, log, md, csv; até 15 MB por arquivo e 60 arquivos por hora por pessoa. comment_id põe o arquivo embaixo de um comentário seu da issue. PO/PM, QA, dev ou admin (403 para os outros). 201 com attachment (como no GET). Não há URL pré-assinada: o bucket é privado e todo arquivo passa pelo tracker, que confere o formato e o tamanho. DELETE /issues/{código ou id}/evidences/{id} remove (quem enviou ou admin do projeto; o arquivo de uma versão de aprovação fica). No MCP: attach_file, remove_attachment e attachments em add_comment; os anexos aparecem em get_issue (evidences).
  • PATCH /issues/{código ou id}/comments/{id} (tracker:write): corrige o texto, {"text": "..."}. Só quem escreveu (403 para os outros); o texto anterior fica guardado para o admin. DELETE no mesmo endereço exclui: o comentário fica no lugar, sem o texto (quem escreveu ou admin da empresa).
  • GET /issues/{código ou id}/history (tracker:read): histórico completo, mais recente primeiro (limit até 200, offset), com total e cada evento com at, by, action, field, text e, quando houver, from e to já com nome.
  • POST /issues/{código ou id}/move (tracker:write): leva a issue para outro projeto da mesma organização, {"project": "CHG", "confirm": true}. Sem confirm, só devolve a prévia (moved: false, avisos do que não tem equivalente no destino, subtarefas que vão junto); com confirm: true, move e devolve o código novo (code) e o antigo (previous_code), que continua achando a issue. 409 se a issue mudou no meio: leia de novo e repita. Exige editar a issue e criar issue no destino.
  • POST /issues/{código ou id}/links (tracker:write): vincula a outra issue, {"target": "MOB-0007", "type": "blocks"} (blocks, relates_to, o padrão, ou duplicates). Exige editar a issue. 201 com os vínculos da issue (links, cada um com id). DELETE /issues/{ref}/links/{id} remove um vínculo.
  • GET /issues/{código ou id}/proofs (tracker:read): aprovação de peças (Design). As versões enviadas, da mais nova para a mais antiga, com status (pending, approved, changes_requested, superseded), nota, decisão com comentário e o arquivo (download_url). pending é o id da versão que espera decisão.
  • POST /issues/{código ou id}/proofs (tracker:write): envia a versão seguinte, em multipart/form-data com file e note opcional (mesmos formatos e tamanho das evidências). A que esperava decisão fica substituída. PO/PM, QA, dev ou admin. 201 com version e as versões.
  • POST /issues/{código ou id}/proofs/{id}/decision (tracker:write): {"decision": "approve"} ou {"decision": "changes", "feedback": "o que mudar"}. PO/PM, QA, admin ou o cliente do projeto (stakeholder). Com o fluxo de Design, enviar leva a issue para Em aprovação, aprovar para Aprovado e pedir ajustes para Ajustes. 422 quando a versão já foi decidida ou substituída.
  • GET /issues/{código ou id}/watchers (tracker:read): quem acompanha a issue (recebe os avisos de status e de comentário novo), com watching para a pessoa do token. POST põe e DELETE tira (tracker:write): sem nada, a própria pessoa; {"person": "[email protected]"} no POST ou ?person=... no DELETE para outra pessoa do projeto, o que exige editar a issue. A resposta traz person (quem foi posto ou tirado), watching e watchers. GET /issues/{ref} também traz watchers.
  • POST /issues/{código ou id}/status (tracker:write): move a issue de status, {"status": "<chave>"}. Vale o fluxo do projeto e o perfil da pessoa nele (422 quando a transição não é permitida). Para closed (Fechado, modelo QA), mande também close_reason: duplicated, cancelled, not_reproduced ou wont_fix; com a issue já em closed, o mesmo pedido troca só o motivo.
  • POST /issues/{código ou id}/block (tracker:write): marca a issue como bloqueada, {"reason": "o que impede"} (opcional; de novo troca o motivo). A marca vale em qualquer status e sai sozinha quando a issue conclui. DELETE no mesmo endereço tira. Todo perfil do projeto menos stakeholder; issue concluída não fica bloqueada (422). Devolve blocked (since, reason) ou null. No MCP: block_issue.
  • DELETE /issues/{código ou id} (tracker:write): exclui a issue (admin ou PO/PM do projeto; 403 para os outros perfis). Ela some de listas, busca e API e pode ser restaurada por 30 dias (na tela, em Issues → Excluídas, ou por POST /issues/{ref}/restore). Issue com issues dentro dela (épico, subtarefas) não é excluída (422).
  • POST /issues/{código ou id}/restore (tracker:write): restaura uma issue excluída nos últimos 30 dias, com comentários, evidências e histórico. Admin ou PO/PM do projeto. GET /issues/deleted (tracker:read, project opcional) lista as que a pessoa pode restaurar (as 200 mais recentes), com restore_until. Depois de 30 dias a restauração devolve 422.
  • POST /issues/{código ou id}/duplicate (tracker:write): cria uma cópia no mesmo projeto, como o Duplicar da tela (conteúdo, classificação, pai, pontos, campos e labels; sem comentários, evidências, vínculos, pessoas, sprint, release e registro técnico). 201 com o code da cópia. Exige criar issue no projeto.
  • POST /issues (tracker:write): cria uma issue. 201 quando cria; 200 quando já existia uma com o mesmo external_id no projeto. assignee e qa_owner (me, id, e-mail ou nome de quem participa do projeto) já atribuem na criação: PO/PM e admin atribuem qualquer pessoa, dev assume como responsável e QA como QA responsável (403 fora disso; 422 quando a pessoa não é do projeto, sem criar a issue). Dev cria só tipos de nível subtarefa, com o pai. Com ?similar=true, a resposta da issue criada traz também similar: as parecidas que a aqua confirmou (code, title, status_label, open, relation, reason, likely_duplicate, url), para vincular.
  • PATCH /issues/{código ou id} (tracker:write): edita a issue. Só os campos enviados mudam; null tira o valor. Aceita os campos de texto, title, type, severity, priority, module, custom_fields (só as chaves enviadas mudam; chave que não existe no projeto é recusada), assignee e qa_owner (me, id, e-mail ou nome de quem participa do projeto), o registro técnico (root_cause, fix_notes, fixed_version, fixed_build), parent, story_points, sprint (nome ou id de sprint aberta; null volta ao backlog), release (a principal: versão ou id; de outro projeto da empresa, "PLT backend-1a2b3c", quando a correção sai só lá), add_releases/remove_releases (outras entregas da mesma correção, inclusive de outro projeto: id, versão no projeto da issue, "GOP 1.4.8-ota002" ou {"project": "GOP", "version": "1.4.8-ota002"}, em lista ou num texto separado por vírgula; exige vincular releases nos dois projetos) e add_labels/remove_labels. Cada grupo exige o perfil certo no projeto (403 quando não pode). Os grupos são gravados em sequência: se um falha, a resposta traz applied com os que já foram gravados. Para não sobrescrever a edição de outra pessoa, mande edit_version (o valor lido em GET /issues/{ref}): se alguém mudou a issue depois (campos, pessoas, registro técnico, pai, pontos, sprint, release, labels, estimativa ou datas; status, comentários e horas não contam), nada é gravado e a resposta é 409 (conflict); leia de novo e reaplique. A resposta de sucesso traz a edit_version nova.
  • GET /issues/{código ou id}/time (tracker:read): estimativa, início, prazo, repetição (recurrence e next_occurrence), total registrado, restante e os registros de horas.
  • POST /issues/{código ou id}/time (tracker:write): registra horas trabalhadas, {"duration": "1h30", "work_date": "AAAA-MM-DD", "comment": "..."} (ou minutes no lugar de duration; sem work_date, hoje). Perfis PO/PM, QA, dev e admin.
  • PATCH /issues/{código ou id}/plan (tracker:write): {"estimate": "8h", "start_date": "AAAA-MM-DD", "due_date": "AAAA-MM-DD", "recurrence": "monthly"}. Campo omitido fica como está; null tira o valor. recurrence (weekly, monthly, quarterly, yearly) faz a issue repetir: ao concluir, nasce a próxima ocorrência com início e prazo avançados, os mesmos responsáveis e labels; time.next_occurrence aponta para ela. Também vale em POST /issues e em cada item de POST /issues/import; null, "" ou "none" tira a repetição.
  • GET /issues/{código ou id}/code (tracker:read): PRs (GitHub), MRs (GitLab) e commits ligados à issue, com id, repositório, estado (open, draft, merged, closed), branch, autor e link.
  • POST /issues/{código ou id}/code (tracker:write): liga um PR ou commit pelo link, {"url": "https://github.com/dono/repo/pull/12", "title": "..."} (MR ou commit do GitLab também, inclusive self-hosted). Não muda o status. 409 quando já está ligado (commit pelo sha curto ou inteiro). Em repositório conectado, o webhook depois atualiza título e estado. Perfis PO/PM, QA, dev e admin.
  • DELETE /issues/{código ou id}/code?link_id=<id> (ou ?url=<link>, ou o mesmo no corpo JSON) (tracker:write): desliga. 404 quando não estava ligado.
  • GET /time (tracker:read): relatório de horas. Query: from e to (AAAA-MM-DD; padrão, o mês corrente), project (prefixo, slug ou id) e person (me ou id); filtro que não confere é erro. Totais por pessoa, por projeto e por issue, e os registros.
  • POST /issues/bulk (tracker:write): a mesma ação em até 100 issues, {"issues": ["MOB-0012", "MOB-0013"], "action": "status", "value": "done"}. action: status, assignee (só PO/PM ou admin; me, id, e-mail ou nome; none tira), priority, severity, label, unlabel, release (versão ou id; none tira), watch, unwatch e delete (as três últimas sem value). Cada issue segue a regra da ação individual; a resposta traz requested (issues distintas pedidas), updated e failed (code e error de cada uma que não mudou). Sem value numa ação que pede valor: 422.
  • POST /issues/batch (tracker:write): lote por issue, até 50, para fechar uma entrega numa chamada: {"items": [{"issue": "MOB-0045", "fixed_version": "backend 4e8998ac", "fix_notes": "...", "code_links": ["https://github.com/org/repo/pull/251"], "status": "ready_for_qa"}]}. Cada item aceita os campos do PATCH /issues/{ref} (inclusive edit_version), code_links (links, ou {url, title}; um link já ligado não é erro) e status, aplicados nessa ordem com as regras das chamadas individuais. Um item que falha não para os outros; a resposta traz requested, succeeded, failed e results (por item: ok, code, updated, linked, status e, se falhou, failed_at com issue (não achada, ou mudou depois da edit_version), fields, code_links ou status, e error; os passos anteriores ficam gravados). Sem outros campos, a edit_version protege os links e o status.
  • POST /issues/import (tracker:write): até 100 issues por pedido, {"project": "MOB", "issues": [...]} (cada item pode trazer o próprio project). Item a item: um recusado não desfaz os outros. A resposta traz created, existing, failed e results (index, ok, code, url ou error).

Campos de uma issue: project (prefixo, slug ou id), title (obrigatório), type (chave do tipo), severity (S1 a S4, padrão S3), priority (urgent, high, medium, low; só PO/PM e admin, os demais ficam com medium), module (nome), description, environment, app_version, build, device, operating_system, preconditions, steps_to_reproduce, actual_result, expected_result, impact, suggested_solution, parent (código ou id da issue pai: o épico de uma issue comum, ou a issue de uma subtarefa; o nível vem do tipo), story_points (número de 0 a 1000), start_date e due_date (início e prazo, AAAA-MM-DD; o início não vem depois do prazo), custom_fields (objeto pela chave do campo), labels (até 10 nomes; a que não existe é criada) e external_id (id na origem, até 200 caracteres).

Modelos por tipo: description, preconditions, steps_to_reproduce, actual_result, expected_result, impact e suggested_solution omitidos vêm preenchidos com o modelo do tipo (o template em GET /projects). Mande "" para deixar um desses campos vazio.

Use external_id no CI: com o nome do teste que falhou, por exemplo, rodar o pipeline de novo não duplica a issue.