API externa
Consulte projetos, reports e evidências do Mira por HTTP, com uma chave de serviço.
A API externa dá a serviços e automações acesso de leitura a projetos, reports, comentários, atividade e evidências. Ela usa uma identidade de serviço: um consumidor sem login humano, com projetos autorizados e quota própria. A chave de serviço não escreve, não gerencia usuários e não emite outras chaves.
Criar o serviço e a chave
Quem faz: admin.
Criar a identidade
Em Admin, abra Serviços de API e crie um serviço. Selecione os projetos que ele pode consultar. Sem projetos, ele não vê nenhum report. Defina a quota de requisições por minuto (120 por padrão).
Escolher as permissões
Cada serviço tem duas permissões separadas, e uma não libera a outra:
- Consultas: as rotas
/api/v1/query/. Vem ativada. - Envio de source maps: só as rotas
/api/v1/upload/, usadas pelo@mira/sourcemapsno CI. Vem desativada.
Sem a permissão da rota, a resposta é 403. Para o CI, crie um serviço só com o envio de source maps, limitado aos projetos da app.
Emitir a chave
Abra Chaves, informe nome e validade e use Emitir chave. O segredo (mira_svc_...) aparece só nessa resposta. Salve o segredo no gerenciador de segredos do consumidor, nunca em URLs nem em logs.
Para rotacionar, emita a substituta, atualize o consumidor e revogue a antiga. Desativar o serviço revoga todas as chaves, e reativar exige emitir novas.
Consultar
O prefixo é /api/v1/query. Envie Authorization: Bearer <chave> por HTTPS.
curl -H "Authorization: Bearer $MIRA_SERVICE_KEY" \
"https://mira.example.com/api/v1/query/projects"
curl -G -H "Authorization: Bearer $MIRA_SERVICE_KEY" \
--data-urlencode 'status=new' \
--data-urlencode 'status=triaged' \
--data-urlencode 'limit=50' \
"https://mira.example.com/api/v1/query/projects/PROJECT_ID/reports"| GET | Conteúdo |
|---|---|
/projects | Projetos autorizados |
/projects/:projectId | Um projeto autorizado |
/projects/:projectId/environments | Ambientes e origens |
/projects/:projectId/tags | Tags, com filtro q opcional |
/projects/:projectId/reports | Lista de reports com filtros e cursor |
/reports/:reportId | Report sem URL capturada, contexto técnico ou anexos |
/reports/:reportId/comments | Comentários |
/reports/:reportId/activity | Histórico de atividade |
/reports/:reportId/evidence | URL capturada, contexto e metadados dos anexos |
/attachments/:attachmentId/content | Bytes do anexo |
As duas últimas rotas exigem a permissão de evidências do serviço.
A color de uma tag é o nome de uma cor da paleta: slate, red, orange, yellow, green, teal, blue, violet ou pink. Ao criar ou editar uma tag, a API aceita também um hex de 6 dígitos, como #3b82f6, e grava a cor da paleta mais próxima.
Anexos de vídeo e de ações
A rota /query/attachments/:attachmentId/content, desta API, devolve sempre o arquivo inteiro e ignora Range. Quem precisa buscar um trecho do vídeo usa /api/v1/attachments/:attachmentId/content, que aceita a sessão do dashboard ou um token pessoal e o cabeçalho Range. Uma faixa válida volta com 206 e Content-Range, e uma faixa fora do tamanho do arquivo volta com 416.
Um anexo recording leva metadata com cinco campos, todos obrigatórios e sem campos extras: source (tab ou desktop), startedAt (ISO 8601 com fuso), durationMs (inteiro positivo, até 300000), microphone e systemAudio (booleanos). O arquivo respeita o menor entre o limite do projeto e 100 MiB, e uma gravação acima disso volta com 413. Um recording sem esses campos volta com 400.
Um anexo actions é um JSON { "entries": [...] } com até 200 entradas e 2 MiB. Cada entrada tem type (click, navigation, reload, tab_hidden, tab_visible ou capture) e timestamp. Um clique leva selector, tag e, às vezes, label com até 80 caracteres. A navegação leva from e to, e a recarga leva url. Campos que não constam aqui, como value, são recusados com 400: nenhuma entrada carrega teclas nem valores de campo.
Filtros e paginação
A lista de reports aceita status, type, priority, assigneeId, tagId, from, to, q, sort, cursor e limit. Para vários valores de uma enumeração, repita a chave. Datas são ISO 8601 com fuso. assigneeId=unassigned traz os reports sem responsável. sort aceita newest (padrão), oldest, priority, status, number_desc e number_asc, e o cursor de uma página só vale na mesma ordenação.
A resposta é { items, nextCursor }. Passe o nextCursor sem modificar como cursor até receber null. O padrão é 50 itens, e o máximo é 100. A ordenação usa a data de criação e o id, e não serve como feed de alterações. As demais listas devolvem o array completo.
Mesmo sem a permissão de evidências, reports e comentários podem conter dados pessoais escritos por pessoas, e os reports trazem nome e email do autor e do responsável. Armazene as respostas com o mesmo cuidado que o dashboard.
Quota
Cada serviço tem um limite de requisições por minuto, compartilhado por todas as chaves dele. A resposta traz X-RateLimit-Limit e X-RateLimit-Remaining. Ao estourar a quota, a API responde 429 com Retry-After: 60. A quota conta toda requisição com chave válida e permissão para a rota, inclusive as que terminam em 400 ou 404. Chave inválida (401) e rota fora das permissões do serviço (403) não contam.
Erros
O formato é { error: { code, message, details? } }.
| HTTP | Código | O que fazer |
|---|---|---|
| 400 | validation_failed | Corrigir os parâmetros, inclusive o cursor |
| 401 | unauthorized | Conferir chave, validade e revogação |
| 403 | forbidden | Conferir a permissão de evidências ou a operação |
| 404 | not_found | O recurso não existe ou está fora dos projetos autorizados |
| 413 | payload_too_large | Reduzir o arquivo enviado, como um source map |
| 429 | rate_limited | Esperar o prazo de Retry-After |
| 500 | internal | Registrar a falha, sem imprimir a chave |
OpenAPI
https://mira.example.com/api/v1/query/docs: documentação HTML com operações, parâmetros, exemplos e schemas.https://mira.example.com/api/v1/query/openapi.json: documento de consulta, para importar em clientes OpenAPI.