API REST

Leia e grave seus monitores, leia e atualize incidentes e envie source maps. Tudo aqui usa as mesmas verificações de permissão e o mesmo filtro de isolamento entre clientes que o painel — não existe uma implementação separada do lado da API que possa divergir dele.

Incluída em todos os planos, inclusive o gratuito. Não há complemento para comprar nem nível que a libere.

URL base

https://vitrinaengine.com/api/v1

Descrição legível por máquina

/openapi.json é um documento OpenAPI 3.1 que cobre todas as rotas desta página. Aponte um gerador de clientes para ele, ou entregue-o a um agente que precise chamar esta API sem que ninguém a explique.

Ele é gerado a partir do serviço em vez de escrito ao lado dele: as rotas vêm da superfície que a própria API publica em GET /, os formatos e sua prosa dos mesmos arquivos .proto em /api/proto, e os limites de requisições do código que os aplica. A compilação falha quando o documento versionado e a API discordam, então ele descreve o que é servido e não o que era verdade da última vez que alguém o editou.

Ele descreve os formatos. Os motivos estão nesta página — que um id de outra organização responde 404, que config nunca é devolvido — e nenhum gerador escreve isso.

Para agentes: MCP

https://vitrinaengine.com/mcp é um servidor Model Context Protocol. Adicione-o a um cliente MCP com uma chave de API como token bearer e um agente poderá ler seus monitores, incidentes, erros e analytics — e criar, alterar e excluir monitores — sem que ninguém explique como esta API funciona.

{
  "mcpServers": {
    "vitrina-engine": {
      "type": "http",
      "url": "https://vitrinaengine.com/mcp",
      "headers": { "Authorization": "Bearer vte_your_key_here" }
    }
  }
}

Ele lê tudo e escreve três coisas. Cada operação GET desta página é uma ferramenta, e também são POST /monitors, PATCH /monitors/{id} e DELETE /monitors/{id}. Nada mais que escreva está ao alcance — nem um espaço de trabalho, nem um membro, nem uma chave de API, nem uma página de status, nem a sua conta — porque não existe ferramenta para nenhum deles, e a lista das escritas permitidas são três linhas que alguém precisa acrescentar de propósito.

Uma chave que não pode escrever continua sendo recusada. Uma chamada de ferramenta é a mesma requisição que a chave faria diretamente, com a mesma verificação de permissão e o mesmo filtro de inquilino: um agente com uma chave somente de leitura lê. Dê uma dessas a ele, a menos que queira que altere seu monitoramento — e conte com um cliente perguntando antes de excluir: excluir um monitor leva junto o histórico dele e não há como desfazer. Para calar um monitor sem perdê-lo, pause-o com PATCH.

Por ser a mesma requisição, ela enxerga exatamente o que a chave enxerga, escreve a mesma entrada de auditoria que o painel escreveria e conta no mesmo limite de requisições, duas vezes: uma pela chamada e outra pela requisição dentro dela. Uma escrita consome o limite de escrita.

Vale saber de uma coisa antes de um agente editar um monitor: config é substituído por inteiro, não mesclado. Leia o monitor primeiro, mude o campo desejado e devolva o objeto inteiro. Uma configuração parcial descarta silenciosamente os cabeçalhos e as credenciais de que a verificação depende, e a deixa rodando.

Autenticação

Crie uma chave em Configurações → Chaves de API e envie-a como token bearer. A chave é mostrada uma única vez, no momento da criação, e guardada apenas como hash — se você a perder, crie outra.

curl https://vitrinaengine.com/api/v1/summary \
  -H "Authorization: Bearer vte_your_key_here"

Uma chave nunca concede mais do que tinha quem a criou. Ela está ligada à participação dessa pessoa, então carrega o papel dela: uma chave criada por alguém com um papel somente de leitura não consegue gravar, não importa o que você envie. Uma chave também pode ser restrita a um único espaço de trabalho e, nesse caso, cada resposta é filtrada para esse espaço, e o que estiver fora dele não existe para essa chave.

Remover alguém da sua organização revoga as chaves que essa pessoa criou, na mesma operação. Revogar o acesso tem que levar as credenciais junto, senão a pessoa fica com uma que funciona.

Convenções

Toda resposta bem-sucedida é um objeto JSON com uma propriedade data. Toda falha é um objeto JSON com uma propriedade error contendo uma frase escrita para uma pessoa.

{ "data": { "id": "8f14e45f-…", "name": "Marketing site" } }

{ "error": "This key cannot create monitors." }

As respostas são enviadas com Cache-Control: private, no-store. São dados de uma chave específica em uma origem compartilhada e nunca devem ficar guardados em um proxy.

Protobuf e gzip

Todos os endpoints sob /api/v1 também falam Protocol Buffers. Envie Accept: application/x-protobuf e a resposta volta em protobuf; envie um corpo em protobuf com Content-Type: application/x-protobuf e a resposta volta no mesmo formato. Sem nenhum dos dois, é JSON, exatamente como antes.

curl https://vitrinaengine.com/api/v1/monitors \
  -H "Authorization: Bearer vte_your_key_here" \
  -H "Accept: application/x-protobuf" \
  --compressed -o monitors.pb

As mensagens são publicadas: /api/proto lista todos os arquivos. Baixe-os preservando os caminhos e aponte protoc -I para esse diretório. Três coisas diferem do que se esperaria em protobuf: um campo que pode ficar vazio é null em JSON e está ausente em protobuf; alguns campos cujo formato varia — o config de um monitor ou de um canal, por exemplo — são documentos JSON carregados dentro de uma string; e StringList envolve uma lista que pode ela própria ser null.

O gzip funciona nos dois sentidos: Accept-Encoding: gzip para as respostas e Content-Encoding: gzip para as requisições. Como dois clientes agora podem receber bytes diferentes da mesma URL, toda resposta carrega Vary: Accept, Content-Type.

Códigos de status

CódigoSignifica
200Tudo certo. 201 quando algo foi criado.
400O corpo não era JSON, falta um campo, ou nada foi pedido.
401Sem chave, ou com uma que não é válida. De propósito nunca diz qual das duas — uma mensagem que as distinguisse seria uma forma de testar chaves.
403Uma chave válida sem permissão para esta ação. A mensagem a nomeia.
404Não existe esse registro para você. Veja abaixo.
413Um source map acima do limite de tamanho.
429Acima de um limite de requisições. Carrega Retry-After. Veja abaixo.

Códigos de recusa

Todo corpo que não seja 2xx traz um code ao lado da frase — not_found, limit_reached, rate_limited — e é esse o campo em que ramificar. A cadeia error é prosa para quem lê um registo e pode ser reescrita a qualquer momento; o código é estável. Onde a frase nomeia um valor, vars leva esses valores como cadeias, para que os coloques onde a tua própria gramática os quer em vez de os extrair do inglês.

{
  "error": "The Pro plan includes 50 monitors, and you have 50.",
  "code": "limit_reached",
  "vars": { "plan": "pro", "limit": "50", "current": "50", "resource": "monitors" }
}

É daqui que as nossas próprias aplicações desenham uma recusa na língua de quem a lê. Trata um código que não reconheças da mesma forma — recorre ao error — porque são acrescentados códigos sem mudança de versão.

Limites de requisições

Por organização, e não por chave — criar outra chave não os aumenta.

BucketLimite
Leituras (GET)120 por minuto
Gravações (POST, PATCH, DELETE)30 por minuto
Envios de source maps300 por hora

Passar do limite responde 429 com um cabeçalho Retry-After que informa quantos segundos inteiros faltam para a janela reiniciar. Respeite-o em vez de tentar de novo imediatamente.

Eles estão postos onde uma integração normal nunca chega: um painel de parede que consulta a cada dez segundos gasta seis das 120 leituras. São iguais em todos os planos, porque os endpoints de coleção devolvem tudo em uma única resposta — uma conta com quinhentos monitores não precisa de mais requisições do que uma com vinte. Os source maps têm uma janela por hora porque chegam em bloco na hora do deploy, quando um front end pode facilmente ter cem chunks.

404 em vez de 403, de propósito

Um id que pertence a outro cliente responde “Not found.”, e não “Forbidden.”. Um 403 confirmaria que o registro existe, o que transformaria o endpoint em uma forma de descobrir se um id é real. Não leia um 404 como prova de que nada existe em lugar nenhum — apenas de que não existe nada que esta chave possa ver.

Endpoints

Tudo na conta que corresponde a ?q=: monitores, incidentes e as suas análises pós-incidente, servidores, páginas de estado, espaços de trabalho, canais de notificação, janelas de manutenção, projetos de erros e problemas, sites de analítica, membros e convites, chaves de API, agentes e sondas privadas. Um pedido em vez de um por tipo.

?type= restringe a uma lista de tipos separada por vírgulas e ?limit= limita os resultados de cada tipo entre 1 e 20 (5 por omissão). Cada tipo exige a mesma permissão que o seu próprio endpoint; um tipo que a sua chave não pode ler está ausente tal como um tipo sem correspondências. Nada selado, com hash ou secreto é pesquisado ou devolvido.

Parâmetros e respostas
NomeLocalTipo
limitqueryinteger
qquerystring
typequerystring
RespostaSearchResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /summary

Contagens, para um painel de parede ou um resumo diário. Requer monitor:read.

{
  "data": {
    "total": 42, "up": 39, "degraded": 1, "down": 1,
    "paused": 1, "pending": 0,
    "openIncidents": 2, "suppressedIncidents": 1
  }
}

suppressedIncidents conta os incidentes retidos por serem raio de impacto de outro. Eles são reais, e não são quedas separadas.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaGetSummaryResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /setup

O que ainda falta fazer em uma conta nova: as mesmas quatro perguntas que a lista de primeiros passos do painel faz, derivadas a cada leitura. Requer monitor:read.

{
  "data": {
    "hasMonitor": true,
    "hasConfirmedChannel": false,
    "hasStatusPage": false,
    "hasColleague": false,
    "dismissedAt": null
  }
}

hasConfirmedChannel pergunta se um alerta realmente conseguiria chegar, e não se existe um canal. As duas coisas se separaram feio uma vez, e uma lista que desse os alertas por prontos com um canal para o qual não entregamos repetiria aquele bug em forma de tranquilidade.

hasColleague conta participações e nunca convites: um convite enviado e não aceito não adicionou ninguém.

Não está embutido em /summary porque aquele endpoint são contagens por estado e nada mais: um painel de parede que o consulta a cada poucos segundos não quer cinco consultas a mais para desenhar um aviso dirigido a quem montou a conta meses atrás.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaGetSetupResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

DELETE /setup

Dispensa a lista. Requer org:update, porque descartá-la é uma linha de toda a organização e não uma preferência de cada pessoa: quem chegar depois não a verá de novo.

Nada mais muda na conta e nenhuma entrada de auditoria é gravada: esconder um aviso não altera nada de como o produto se comporta, nem de como ele alerta, nem de como ele cobra.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaDismissedResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /monitors

Todos os monitores que a chave pode ver. Requer monitor:read. Cada um traz id, name, kind, status, statusSince, enabled, intervalSeconds, tags, workspace, lastCheckedAt, lastResponseTimeMs, lastMessage, uptime24h, uptime30d e openIncidentId.

?tag=prod,eu reduz a lista aos monitores que levam todas as tags nomeadas — E, não OU, de modo que nomear uma segunda tag sempre devolve menos monitores em vez de mais. O filtro do painel se lê do mesmo jeito. As tags são guardadas em minúsculas, e aqui o valor é convertido do mesmo jeito antes de ser comparado, então ?tag=Prod as encontra. Uma entrada que não poderia ser uma tag — vazia, ou mais longa do que uma tag pode ser — é descartada e o resto do filtro continua valendo, em vez de a chamada ser recusada: um link não deveria parar de funcionar porque uma das suas tags foi renomeada.

config nunca é devolvido. Em alguns tipos ele contém cabeçalhos de requisição e credenciais, e uma chave somente de leitura não deveria ser um jeito de recuperar os segredos que alguém digitou em um formulário.

Parâmetros e respostas
NomeLocalTipo
tagquerystring
RespostaListMonitorsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /monitors

Requer monitor:create. Precisa de name, kind, workspaceId e config. Opcionais: intervalSeconds (padrão 300), confirmations, dependsOn.

curl -X POST https://vitrinaengine.com/api/v1/monitors \
  -H "Authorization: Bearer vte_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Marketing site",
    "kind": "http",
    "workspaceId": "…",
    "intervalSeconds": 60,
    "config": {
      "url": "https://example.com",
      "assertions": [{ "type": "status_code", "operator": "lt", "value": "400" }]
    }
  }'

Responde 201 com o id novo. O intervalo é ajustado ao mínimo do seu plano em vez de ser recusado, então pedir 10 segundos em um plano cujo mínimo é 60 dá 60 — se isso importa para você, leia o monitor de volta.

Parâmetros e respostas
NomeLocalTipo
namebodystring
kindbodystring
workspaceIdbodystring
configbodystring
intervalSecondsbodyinteger
confirmationsbodyinteger
dependsOnbodystring[]
probeIdbodystring
tagsbodystring[]
RespostaCreatedResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

GET /monitors/{id}

Um monitor, com tudo o que a lista dá mais paused. Requer monitor:read.

Para mail_posture, tls_audit e snmp ele inclui ainda lastCheckDetail, o resultado da última verificação: as constatações por trás do estado, cada uma com um code estável e uma severity, mais uma nota de TLS ou as leituras SNMP. É null até a primeira verificação e não aparece nos outros tipos.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaGetMonitorResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PATCH /monitors/{id}

Envie apenas o que quiser mudar: name, intervalSeconds, confirmations, enabled, config ou paused.

paused é verificado contra monitor:pause e todo o resto contra monitor:update, separadamente — uma chave que pode pausar mas não editar continua podendo pausar. Enviar uma alteração vazia dá 400.

O monitor é lido de novo e devolvido, em vez de repetirmos o que você enviou, de modo que o que você vê é o que ficou gravado.

# Silence a monitor for the length of a deploy.
curl -X PATCH https://vitrinaengine.com/api/v1/monitors/$ID \
  -H "Authorization: Bearer vte_…" \
  -H "Content-Type: application/json" \
  -d '{"paused": true}'
Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
namebodystring
intervalSecondsbodyinteger
confirmationsbodyinteger
enabledbodyboolean
pausedbodyboolean
configbodystring
tagsbodyStringList
RespostaUpdatedMonitorResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /monitors/{id}

Requer monitor:delete. Responde { "data": { "id": "…", "deleted": true } }.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /hosts · POST /hosts

Servidores são a segunda forma de agrupar monitores: o espaço de trabalho diz de quem é um monitor, o servidor diz onde ele roda. Totalmente opcional — uma conta que nunca criar um não perde nada, e a maioria dos monitores não nomeia servidor algum.

Cada servidor traz status, pinned e spanning. status vem apenas dos monitores que rodam só naquele servidor. Um monitor que roda em várias máquinas conta em spanning e não colore nenhuma delas, porque um endpoint balanceado que falha diz que o serviço quebrou, não qual máquina quebrou. Um servidor sem nada exclusivo responde "status": null em vez de up.

POST exige monitor:create e um name. Os campos opcionais provider, address e notes são seus — nada no produto os usa. Um nome que coincide com um que você já tem — ignorando maiúsculas e o ponto final — responde 409.

Parâmetros e respostas

GET /hosts

Sem parâmetros nem campos de corpo declarados.

RespostaListHostsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /hosts

NomeLocalTipo
namebodystring
providerbodystring
addressbodystring
notesbodystring
RespostaCreatedResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

GET /hosts/{id} · PATCH /hosts/{id} · DELETE /hosts/{id}

O detalhe traz o servidor e os monitores nele, cada um marcado com pinned e, quando não está, com alsoOn: as outras máquinas de onde ele responde, que é o que você lê antes de reiniciar uma. DELETE aposenta o servidor e todos os monitores continuam funcionando — um servidor não tem agenda nem histórico próprios.

Parâmetros e respostas

GET /hosts/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaGetHostResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PATCH /hosts/{id}

NomeLocalTipo
id obrigatóriopathstring
namebodystring
providerbodystring
addressbodystring
notesbodystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /hosts/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /hosts/{id}/monitors · DELETE /hosts/{id}/monitors

Um monitor dentro ou fora de um servidor, com monitorId no corpo ou ?monitorId=. Deliberadamente não é uma lista inteira: numa conta de agência um servidor carrega monitores de vários espaços de trabalho, e quem substituísse “a lista” estaria substituindo linhas que nunca viu. As duas direções são idempotentes.

Parâmetros e respostas

POST /hosts/{id}/monitors

NomeLocalTipo
id obrigatóriopathstring
monitorIdbodystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /hosts/{id}/monitors

NomeLocalTipo
id obrigatóriopathstring
monitorIdquerystring
monitorIdbodystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /monitors/{id}/hosts · PUT /monitors/{id}/hosts

O outro lado da mesma relação, e este é uma lista inteira: esses vínculos pertencem a um único monitor, então não há nada do outro lado que outro espaço de trabalho possa ver. Envie hostIds; um array vazio é um pedido real e significa que o monitor não roda em nenhum servidor em particular. Ids que não são seus são descartados em vez de recusados. Toda resposta de monitor traz também hosts, vazio quando não há nenhum.

Parâmetros e respostas

GET /monitors/{id}/hosts

NomeLocalTipo
id obrigatóriopathstring
RespostaListMonitorHostsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PUT /monitors/{id}/hosts

NomeLocalTipo
id obrigatóriopathstring
hostIdsbodystring[]
RespostaListMonitorHostsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /incidents

Requer incident:read. Aceita ?status= — um entre open, acknowledged, resolved ou suppressed — e ?open=true para os três que não estão resolvidos. Um status desconhecido é ignorado em vez de recusado, do mesmo jeito que ?limit= (padrão 50) é limitado a 200 em vez de rejeitado.

Cada um traz id, monitorId, monitorName, title, cause, status, severity, startedAt, resolvedAt, durationSeconds, acknowledgedAt e rootIncidentId.

rootIncidentId é o campo a olhar se você montar um feed de alertas. Quando ele está presente, este incidente é raio de impacto de outro — o servidor de banco de dados caiu e este é um dos doze serviços que estão atrás dele. Pule esses e você recebe um alerta em vez de treze.

Parâmetros e respostas
NomeLocalTipo
limitqueryinteger
openqueryboolean
statusquerystring
RespostaListIncidentsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /incidents/{id}

Um incidente. Requer incident:read. Os mesmos campos da lista, mais workspaceId.

Não devolve a linha do tempo do incidente — os comentários e as mudanças de estado que aparecem no painel não estão neste endpoint. Se você precisar deles, peça e eles podem ser acrescentados; documentá-los aqui sem que existissem seria pior do que a ausência.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaGetIncidentResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PATCH /incidents/{id}

Envie status com o valor "acknowledged" ou "resolved", ou um comment, ou os dois. Cada um é verificado contra sua própria permissão: incident:acknowledge, incident:resolve, incident:comment. Acrescentar "publish": true a um comentário o publica na página de status e requer também status_page:manage.

# A runbook that fixed the thing itself can close its own incident.
curl -X PATCH https://vitrinaengine.com/api/v1/incidents/$ID \
  -H "Authorization: Bearer vte_…" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved", "comment": "Restarted by runbook.", "publish": true}'
Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
statusbodystring
commentbodystring
publishbodyboolean
RespostaGetIncidentResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

PUT /incidents/{id}/postmortem

Escreve ou substitui a análise pós-incidente do incidente. Exige incident:resolve, e o incidente já precisa estar resolvido — caso contrário, 409 com o código incident_not_resolved. Envie body em Markdown, de 1 a 50.000 caracteres depois de remover espaços (postmortem_required, postmortem_too_long). Há uma por incidente, então cada chamada substitui a anterior. A resposta é o incidente, como GET /incidents/{id} o retorna.

GET /incidents/{id} a traz como postmortem: { body, authorName, updatedAt }, ou null, e a lista traz hasPostmortem. Renderize body como Markdown e nunca como HTML: é texto que uma pessoa digitou. Uma análise pós-incidente é interna e nunca aparece em uma página de status.

curl -X PUT https://vitrinaengine.com/api/v1/incidents/$ID/postmortem \
  -H "Authorization: Bearer vte_…" \
  -H "Content-Type: application/json" \
  -d '{"body": "## What happened\n\nThe connection pool ran dry after a deploy."}'
Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
bodybodystring
RespostaGetIncidentResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /probes

As sondas privadas da sua organização: id, name, lastSeenAt, version, hostname, monitorCount, revoked e createdAt. Exige agent:read. É o que o seletor de sonda de um monitor oferece.

Não há campo de região, e não haverá. Você escolhe uma sonda pelo nome; onde uma verificação roda por trás dela cabe a nós decidir e mudar. Sondas revogadas aparecem com revoked: true e não recebem mais trabalho, então não as ofereça.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaListProbesResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /monitors/{id}/push-url

A URL de ping de um monitor heartbeat, exibida de novo. Exige monitor:read. url é null para um tipo que não recebe ping e para um token que não pode mais ser descriptografado — o monitor continua funcionando, e renovar o token no painel gera uma URL que pode ser exibida.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaGetPushUrlResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /organizations · PUT /organizations/active

As organizações às quais a pessoa conectada pertence, cada uma com seu role lá e active na que está em uso, e a troca entre elas. Envie organizationId; a resposta é a associação agora em uso.

Apenas com sessão iniciada. Uma chave pertence a uma única associação e recebe 403 com session_required. Trocar move todas as sessões dessa pessoa, inclusive o painel, e uma organização da qual ela não faz parte responde 404.

Parâmetros e respostas

GET /organizations

Sem parâmetros nem campos de corpo declarados.

RespostaListOrganizationsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PUT /organizations/active

NomeLocalTipo
organizationIdbodystring
RespostaActiveOrganizationResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /sms/enrolment · POST /sms/enrolment/confirm

Cadastre o seu próprio número de celular para alertas por SMS: envie phone (e, opcionalmente, name), e enviamos um código de seis dígitos para ele; envie esse code para a segunda rota para confirmar. Exige notification_channel:manage e uma sessão iniciada — um número é adicionado pela pessoa que está com o aparelho, nunca por uma chave.

O número é guardado sem confirmação e não recebe nada até o código voltar. Cadastrar de novo substitui o número anterior. Recusas: sms_not_included (402, o plano não inclui SMS), not_a_phone_number, sms_country_unsupported, sms_route_not_open, verification_code_not_sent (502; chame de novo para receber um código novo), verification_code_malformed e verification_code_incorrect. Um início bem-sucedido traz country e caveatsender-replaced, registration-pending, unverified ou null —, que vale mostrar antes que alguém dependa do número.

Parâmetros e respostas

POST /sms/enrolment

NomeLocalTipo
phonebodystring
namebodystring
RespostaSmsEnrolmentResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

POST /sms/enrolment/confirm

NomeLocalTipo
codebodystring
RespostaSmsConfirmedResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /channels/{id}/confirmation

Reenvia a mensagem de confirmação de um canal de e-mail. Exige notification_channel:manage. Cada chamada emite um link novo e o anterior deixa de funcionar. sent: false significa que não havia nada a enviar — o endereço já confirmou — e um endereço confirmado nunca é contatado de novo por aqui. Um envio recusado pelo provedor de e-mail responde 502 com confirmation_not_sent.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaChannelConfirmationResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

PATCH /workspaces/{id}

Renomeia um espaço de trabalho. Exige workspace:update. name é obrigatório (1 a 80 caracteres) e clientReference, opcional — null o apaga. O slug nunca muda, porque está nas URLs das páginas de status. A resposta é o espaço de trabalho como ficou.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
namebodystring
clientReferencebodyrequests.NullableString
RespostaUpdatedWorkspaceResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /sourcemaps

Envie um source map para que os stack traces minificados sejam resolvidos. Requer monitor:create. Precisa de projectRef (um número) e filename, mais o próprio mapa como map (JSON) ou mapGzipBase64. Opcionais: debugId e release.

Envie um debug id ou um release. Um mapa sem nenhum dos dois não pode ser associado a um stack trace e vai ficar ali sem fazer nada. A correspondência é buscada primeiro por debugId e depois por release mais nome de arquivo.

Os mapas são resolvidos quando um problema é lido, e não no envio, então um que seja enviado depois que os erros chegaram ainda serve — que é a ordem de sempre.

Parâmetros e respostas
NomeLocalTipo
projectRefbodyinteger
filenamebodystring
debugIdbodystring
releasebodystring
mapbodystring
mapGzipBase64bodystring
RespostaUploadedSourceMapResponse
Códigos de status201 400 401 403 404 429
Limite de requisições300 por hora

POST /symbols

A mesma ideia para um aplicativo nativo: envie um .dSYM do iOS ou um mapping.txt do R8 no Android para que as pilhas de crash sejam resolvidas. Requer monitor:create. Vinte envios por hora, e vinte builds guardados por projeto.

Diferente de /sourcemaps, o corpo é o próprio arquivo compactado com gzip e os metadados vão em cabeçalhos: X-Vitrina-Project-Ref, X-Vitrina-Platform (ios ou android), X-Vitrina-Symbol-Name e X-Vitrina-Release. Um dSYM tem dezenas de megabytes, e base64 dentro de um campo JSON custa um terço a mais de transferência.

As duas plataformas são associadas de formas diferentes. Um frame do iOS nomeia o UUID Mach-O da imagem à qual pertence, então um envio de iOS precisa carregar X-Vitrina-Debug-Ids e é associado exatamente por ele. O R8 não emite um id assim, então um mapping de Android é associado só pelo release — que precisa ser exatamente o que o aplicativo reporta, <applicationId>@<versionName>+<versionCode>. Um dígito fora e os frames resolvem para linhas que parecem plausíveis e estão erradas.

Reenviar o mesmo build substitui os símbolos dele em vez de falhar, então um job de release repetido não é um erro. Como acontece com os source maps, a resolução acontece quando um problema é lido.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaUploadedSymbolsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições20 por hora

GET /errors/projects

Os projetos de rastreamento de erros que esta conta tem. Requer monitor:read. Cada um traz ref — o número que aparece no DSN — mais publicKey, unresolved e eventsLast24h. Somente leitura: um projeto é criado com uma chave que ainda precisa ser colada na configuração de um aplicativo, então não há aqui nada que um endpoint terminasse.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaListErrorProjectsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /errors/issues

Erros agrupados, atividade mais recente primeiro. Requer monitor:read. Um problema é uma impressão digital e não um evento, então mil ocorrências de uma mesma exceção são uma única linha com timesSeen em mil. ?status= tem padrão unresolved e aceita também resolved, ignored ou all; ?project= filtra por id de projeto, ?q= pesquisa o tipo, o valor e o culpado, e ?limit= tem teto de 200. spark são vinte e quatro contagens por hora, da mais antiga para a mais nova.

Parâmetros e respostas
NomeLocalTipo
limitqueryinteger
projectquerystring
qquerystring
statusquerystring
RespostaListIssuesResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /errors/issues/{id}

Um problema com sua pilha. Requer monitor:read. exceptions é a própria cadeia do SDK, com o erro lançado por último e suas causas antes dele, e seus frames são resolvidos contra qualquer source map que você tenha enviado — a mesma resolução que o painel faz, de modo que um script e a pessoa com quem você está conversando nunca estão olhando pilhas diferentes. Um mapa que não pode ser aplicado recorre aos frames originais em vez de fazer a requisição falhar.

lastEvent traz dois carimbos de tempo de propósito. occurredAt é o que o SDK reportou e receivedAt é quando a ingestão o gravou; um dispositivo que estava offline, ou uma fila que acumulou, é exatamente a diferença entre os dois.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaGetIssueResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PATCH /errors/issues/{id}

Resolver, ignorar ou reabrir: { "status": "resolved" }. Requer monitor:update. ignoreHours pode acompanhar ignored para deixar de ignorá-lo depois, e tem teto de 90 dias.

Resolver registra o release em que ele foi resolvido, então um retardatário de uma implantação mais antiga não reabre o problema. Quando o SDK não enviou release não há com o que comparar e qualquer evento posterior o reabre mesmo — sem forma de distinguir um retardatário de uma regressão, o mais seguro é supor que o bug voltou.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
statusbodystring
ignoreHoursbodyinteger
RespostaIssueStatusResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /analytics

Os sites que esta conta mede. Requer monitor:read. Traz publicId — o valor que vai na tag de script, que é público por desenho — mais viewsLast24h e trafficAlerting, que é verdadeiro enquanto o tráfego de um site está abaixo do que aquela hora costuma ver.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaListAnalyticsSitesResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /analytics/{id}

Os números de um site, para uma planilha ou um relatório. Requer monitor:read. ?days= tem padrão 7 e teto de 365. ?dimensions= aceita uma lista separada por vírgulas entre path, referrer, country, browser, os, device, utm_source, utm_medium, utm_campaign e event; uma desconhecida dá 400 em vez de uma resposta vazia, porque um erro de digitação que não devolve nada se lê como “sem tráfego”.

O número de visitantes se chama dailyUniqueVisitors, e é isso mesmo que ele é. É a soma dos únicos diários e não pode ser outra coisa: o segredo por trás do hash de um visitante é destruído no fim do seu dia UTC, então quem visitou em dois dias conta duas vezes e não existe chave que os junte. Isso é o desenho de privacidade funcionando e não uma aproximação — mas um campo chamado visitors ao lado de um intervalo de 30 dias convidaria você a reportar um número que significa outra coisa.

curl "https://vitrinaengine.com/api/v1/analytics/$ID?days=30&dimensions=path,referrer" \
  -H "Authorization: Bearer vte_…"
Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
daysqueryinteger
RespostaGetAnalyticsSiteResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /billing

O plano, e onde ele é cobrado. Requer billing:read. Traz plan, status, cadence, currentPeriodEnd, cancelAt, addOnPacks e os últimos doze recibos.

source é paddle, apple, manual ou none. Isso importa: uma assinatura comprada no aplicativo iOS é da Apple para alterar, e o plano, o cartão e o cancelamento vivem todos nas configurações da App Store do cliente e não aqui. canCheckoutOnWeb e canPurchaseInApp dizem quais ofertas é seguro mostrar, para que um cliente não precise rededuzir essa regra e errá-la na direção que cobra alguém duas vezes.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaGetBillingResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /monitors/{id}/history

Disponibilidade diária de um monitor. Requer monitor:read. Aceita days, até o limite de retenção de histórico do seu plano.

É calculada a partir de consolidações diárias e não de resultados de verificação individuais, que é por isso que ela continua respondendo para períodos cujos resultados brutos a retenção já apagou.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
daysqueryinteger
RespostaGetMonitorHistoryResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /monitors/{id}/graph · GET /monitors/graphs

As últimas horas de um monitor, hora a hora, ou de todos os monitores que esta chave vê numa só resposta — o que o painel desenha na linha e na página de um monitor. Requer monitor:read. Aceita hours, 24 por padrão e no máximo 168.

Um gráfico uptime traz a proporção de verificações aprovadas em cada hora, com null para uma hora sem nenhuma; um gráfico value, para os tipos quantitativos, traz suas leituras como séries com a unidade. Toda hora da janela está presente, tenha sido registrado algo ou não, para que uma lacuna apareça como lacuna. As leituras são enviadas como foram medidas: uma série raw não tem escala conhecida, então desenhe-a contra a sua própria leitura mais alta e nunca mostre essa proporção como se fosse a leitura.

Parâmetros e respostas

GET /monitors/{id}/graph

NomeLocalTipo
id obrigatóriopathstring
hoursqueryinteger
RespostaGetMonitorGraphResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /monitors/graphs

NomeLocalTipo
hoursqueryinteger
RespostaListMonitorGraphsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /monitors/{id}/channels · PUT /monitors/{id}/channels

Quais canais este monitor alerta, e como defini-los. Ler requer notification_channel:read; gravar requer monitor:update.

O PUT substitui o conjunto inteiro — envie todos os ids de canal que você quer, não apenas os que está acrescentando. Um array vazio significa que o monitor não alerta ninguém, o que é uma coisa válida de se querer e uma coisa ruim de se fazer sem querer.

Parâmetros e respostas

GET /monitors/{id}/channels

NomeLocalTipo
id obrigatóriopathstring
RespostaGetMonitorChannelsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PUT /monitors/{id}/channels

NomeLocalTipo
id obrigatóriopathstring
channelIdsbodyStringList
RespostaGetMonitorChannelsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /incidents/{id}/events

A linha do tempo de um incidente: mudanças de estado, reconhecimentos, comentários, etapas de escalonamento. Requer incident:read. É a linha do tempo que GET /incidents/{id} não inclui.

Parâmetros e respostas
NomeLocalTipo
id obrigatóriopathstring
RespostaListIncidentEventsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /channels · POST /channels

Ler requer notification_channel:read; criar requer notification_channel:manage. Cada um traz id, kind, name, target e workspaceId.

secret é devolvido apenas quando um canal é criado, e nunca mais. Ele é a chave de assinatura de um webhook; guardá-lo em algum lugar de onde você pudesse lê-lo de volta faria de uma chave somente de leitura um jeito de forjar requisições assinadas.

Você pode criar os tipos que uma pessoa cria no painel: email, webhook, telegram, slack, teams, discord, pagerduty e jsm. SMS, WhatsApp, satélite e push são inscritos pela pessoa que os recebe e não podem ser criados pela API — é isso que faz deles um consentimento e não um campo que alguém digitou.

Um canal de e-mail é criado não confirmado e recebe uma única mensagem perguntando se quer alertas. Nada mais é enviado até que ele concorde, então criar um pela API não coloca um endereço na sua escala de plantão por conta própria.

Parâmetros e respostas

GET /channels

Sem parâmetros nem campos de corpo declarados.

RespostaListChannelsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /channels

NomeLocalTipo
kindbodystring
namebodystring
targetbodystring
workspaceIdbodyrequests.NullableString
RespostaCreatedChannelResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

PATCH /channels/{id} · DELETE /channels/{id} · POST /channels/{id}/test

Todos requerem notification_channel:manage. O envio de teste é recusado para um endereço que não confirmou — senão seria uma forma ilimitada de escrever para um endereço que não consentiu, com um rótulo prestativo.

Parâmetros e respostas

PATCH /channels/{id}

NomeLocalTipo
id obrigatóriopathstring
enabledbodyboolean
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /channels/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /channels/{id}/test

NomeLocalTipo
id obrigatóriopathstring
RespostaTestDeliveryResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /status-pages · POST /status-pages

Ler requer status_page:read; gravar requer status_page:manage. Cada uma traz id, name, slug, visibility, customDomain, domainVerifiedAt, subscribersEnabled, componentCount, workspace e createdAt.

Parâmetros e respostas

GET /status-pages

Sem parâmetros nem campos de corpo declarados.

RespostaListStatusPagesResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /status-pages

NomeLocalTipo
namebodystring
workspaceIdbodystring
RespostaCreatedResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

GET /status-pages/{id} · PATCH /status-pages/{id} · DELETE /status-pages/{id}

Ler requer status_page:read; alterar ou excluir requer status_page:manage.

Parâmetros e respostas

GET /status-pages/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaGetStatusPageResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

PATCH /status-pages/{id}

NomeLocalTipo
id obrigatóriopathstring
namebodystring
headlinebodyrequests.NullableString
descriptionbodyrequests.NullableString
logoUrlbodyrequests.NullableString
themeAccentbodystring
languagebodystring
historyDaysbodyinteger
showResponseTimesbodyboolean
showIncidentHistorybodyboolean
subscribersEnabledbodyboolean
visibilitybodystring
passwordbodyrequests.NullableString
customCssbodyrequests.NullableString
hideVitrinaBrandingbodyboolean
groupByHostbodyboolean
RespostaUpdatedStatusPageResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /status-pages/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /status-pages/{id}/components · DELETE /status-pages/{id}/components

Acrescenta ou remove um monitor de uma página. Requer status_page:manage.

O monitor precisa estar no mesmo espaço de trabalho que a página, e não apenas na mesma organização. Em uma conta de agência é isso que impede que o monitor de um cliente seja publicado na página de outro.

Parâmetros e respostas

POST /status-pages/{id}/components

NomeLocalTipo
id obrigatóriopathstring
monitorIdbodystring
displayNamebodystring
RespostaComponentAckResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /status-pages/{id}/components

NomeLocalTipo
id obrigatóriopathstring
componentquerystring
componentIdbodystring
RespostaComponentAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /workspaces · POST /workspaces · DELETE /workspaces/{id}

Ler requer workspace:read, e o resto suas próprias permissões. Cada um traz id, name, slug, clientReference e isDefault.

Uma chave de um membro restrito vê apenas os espaços de trabalho aos quais esse membro está restrito. O espaço de trabalho padrão não pode ser excluído.

Parâmetros e respostas

GET /workspaces

Sem parâmetros nem campos de corpo declarados.

RespostaListWorkspacesResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /workspaces

NomeLocalTipo
namebodystring
clientReferencebodystring
RespostaCreatedResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /workspaces/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /members · POST /members

Ler requer member:read; convidar requer member:invite. A resposta traz members e invitations separadamente — um convite que ninguém aceitou não adicionou ninguém, e juntar os dois daria uma contagem de assentos que discorda do que é cobrado de você.

O POST envia um convite em vez de criar uma conta. Ele aceita um e-mail, um papel e, opcionalmente, workspaceIds para restringir a pessoa.

Parâmetros e respostas

GET /members

Sem parâmetros nem campos de corpo declarados.

RespostaListMembersResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /members

NomeLocalTipo
emailbodystring
rolebodystring
workspaceIdsbodystring[]
RespostaAckResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

PATCH /members/{id} · DELETE /members/{id} · DELETE /invitations/{id}

Mudar um papel requer member:update_role; remover requer member:remove; revogar um convite requer member:invite.

Remover um membro apaga os canais de alerta pessoais dele — o aparelho, a conversa privada, o número de celular — junto com as chaves de API dele. Os canais compartilhados não são tocados. O último proprietário não pode ser removido nem rebaixado.

Parâmetros e respostas

PATCH /members/{id}

NomeLocalTipo
id obrigatóriopathstring
rolebodystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /members/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /invitations/{id}

NomeLocalTipo
id obrigatóriopathstring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /maintenance · POST /maintenance · DELETE /maintenance

Janelas durante as quais nada aciona ninguém. Por padrão as verificações continuam rodando e continuam gravando, então esses minutos contam para a disponibilidade como quaisquer outros; com keepChecking em false nada é verificado enquanto a janela está aberta, o que deixa uma lacuna no histórico em vez de uma queda. Ler requer incident:read; gravar requer maintenance:manage.

Traz title, startsAt, endsAt, timezone, monitorIds, recurrenceRule, keepChecking, showOnStatusPage e notifySubscribers. Uma janela recorrente é uma linha só, e não várias.

Uma regra repete a janela no mesmo horário local do seu próprio timezone, então uma janela que atravessa a mudança de horário continua na hora prevista. FREQ=DAILY, FREQ=WEEKLY e FREQ=MONTHLY são expandidas, opcionalmente com INTERVAL, COUNT, UNTIL e um BYDAY ou BYMONTHDAY que nomeie o dia em que a própria janela começa. Qualquer outra regra é guardada e devolvida sem alteração e retém alertas apenas na primeira ocorrência — nada é adivinhado.

Parâmetros e respostas

GET /maintenance

NomeLocalTipo
pastqueryboolean
RespostaListMaintenanceResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /maintenance

NomeLocalTipo
titlebodystring
descriptionbodystring
workspaceIdbodystring
monitorIdsbodystring[]
startsAtbodystring
endsAtbodystring
recurrenceRulebodystring
timezonebodystring
keepCheckingbodyboolean
showOnStatusPagebodyboolean
notifySubscribersbodyboolean
RespostaCreatedResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /maintenance

NomeLocalTipo
idquerystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /on-call

Escalas, políticas de escalonamento, substituições e quem está de plantão agora. Requer oncall:read.

onCallNow é resolvido no momento em que você pergunta, com viaOverride dizendo se veio da rotação ou de alguém cobrindo. unreachable nomeia os participantes sem nenhum canal que realmente consiga alcançá-los, que é a falha que vale a pena descobrir antes de um incidente e não durante um.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaGetOnCallResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /agents · POST /agents · DELETE /agents · GET /agents/{id}/metrics

Os agentes de servidor reportam CPU, memória e disco das suas próprias máquinas. Registrar requer agent:enroll, ler requer agent:read, remover requer agent:delete.

Registrar devolve um token, uma única vez. É com ele que o agente se autentica, então depois disso ele nunca mais é legível.

Parâmetros e respostas

GET /agents

Sem parâmetros nem campos de corpo declarados.

RespostaListAgentsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /agents

NomeLocalTipo
namebodystring
workspaceIdbodyrequests.NullableString
RespostaEnrolledAgentResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /agents

NomeLocalTipo
idquerystring
idbodystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /agents/{id}/metrics

NomeLocalTipo
id obrigatóriopathstring
hoursqueryinteger
limitqueryinteger
RespostaGetAgentMetricsResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /api-keys · POST /api-keys · DELETE /api-keys

Ler requer api_key:read; criar e revogar requerem api_key:manage. Cada uma traz id, name, prefix, scopes, workspaceIds, owner, createdAt, lastUsedAt, expiresAt e revokedAt.

token só é devolvido na criação. prefix é a parte exibível, que é o que permite distinguir duas chaves em uma lista sem que nenhuma delas seja legível.

Uma chave herda o papel e a restrição de espaços de trabalho da participação que a criou, de modo que uma chave não pode ser um jeito de contornar um limite de quem a criou.

Parâmetros e respostas

GET /api-keys

Sem parâmetros nem campos de corpo declarados.

RespostaListApiKeysResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

POST /api-keys

NomeLocalTipo
namebodystring
scopesbodystring[]
workspaceIdsbodystring[]
expiresInDaysbodyrequests.NullableInt64
RespostaCreatedApiKeyResponse
Códigos de status201 400 401 403 404 429
Limite de requisições30 por minuto

DELETE /api-keys

NomeLocalTipo
idquerystring
idbodystring
RespostaAckResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /audit

Mudanças de configuração, com quem as fez e o que mudou. Requer audit_log:read, que é do plano Business para cima.

Paginado por nextBefore e não por número de página, de modo que o limite de uma página não se desloca enquanto você a lê. As entradas são gravadas em todos os planos — o plano controla a leitura, então uma atualização de plano abre todo o histórico em vez de começar um.

Credenciais, hashes e segredos nunca são gravados em changes.

Parâmetros e respostas
NomeLocalTipo
limitqueryinteger
RespostaListAuditResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

GET /me

Quem é esta chave, o que ela alcança e o que o plano permite. Não precisa de permissão — toda chave pode se descrever.

Traz user, organization, membership(papel e restrição de espaços de trabalho), entitlements (os limites resolvidos do plano, já com os pacotes complementares somados) e usage. Use-o para conferir um limite antes de tentar criar algo, em vez de depois de ser recusado.

Uma sessão recebe também organizations, listando todas as organizações às quais a pessoa pertence. Uma chave de API não: uma chave é emitida contra uma participação e fica restrita a ela, então listar as outras anunciaria organizações que essa credencial não alcança.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaGetMeResponse
Códigos de status200 400 401 403 404 429
Limite de requisições120 por minuto

DELETE /account

Exclui a organização e tudo o que há nela. Nenhuma constante de permissão protege esta, porque a checagem é a titularidade: ela é recusada para quem não for proprietário.

Isto não é reversível e não é uma pausa. Use com intenção.

Parâmetros e respostas

Sem parâmetros nem campos de corpo declarados.

RespostaAccountDeletedResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

POST /billing/apple/verify

Confirma uma compra dentro do nosso próprio aplicativo móvel. Requer billing:manage.

Documentado por completude e não para uso: só é chamável com um recibo que a Apple emitiu para o nosso aplicativo, então não há nada que uma integração de terceiros possa fazer com ele. Está listado aqui porque uma rota que existe e não é descrita em lugar nenhum é indistinguível de uma que alguém esqueceu.

Parâmetros e respostas
NomeLocalTipo
transactionIdbodystring
RespostaAppleVerifyResponse
Códigos de status200 400 401 403 404 429
Limite de requisições30 por minuto

GET /

O índice. Lista as rotas que esta implantação serve, que é a versão legível por máquina desta página e está sempre atual — ela é gerada a partir do que está de fato montado.

Feed de incidentes (RSS e Atom)

Todos os incidentes da sua conta como feed, para um leitor e não para uma biblioteca cliente. Crie a URL no painel, em Configurações → Notificações:

https://vitrinaengine.com/feeds/incidents/vtf_…/feed.xml
https://vitrinaengine.com/feeds/incidents/vtf_…/atom.xml

A URL é a credencial. Não há cabeçalho a enviar: quem tiver o link pode ler todos os incidentes da conta, em todos os espaços de trabalho. Ela é mostrada no painel sempre que você precisar dela de novo, porque vive num leitor de feeds que alguém ainda vai reinstalar — e pode ser substituída ou revogada, com efeito na requisição seguinte e não quando algum cache expirar.

Leva apenas fatos do incidente: o nome do monitor, a causa, a severidade, o estado, quando abriu e fechou, e as atualizações marcadas como públicas. Nunca um post-mortem, nunca a configuração do monitor e nunca de onde uma verificação foi feita. A maioria dos leitores sincroniza pelos servidores de terceiros, então o documento é escrito como se saísse do seu prédio, porque sai.

Consultar uma vez por minuto é o esperado. Acima de sessenta requisições por minuto para uma URL ela responde 429, e uma URL que nunca foi válida, que foi substituída ou revogada responde 404 — a mesma resposta para os três casos, para que não sirva para descobrir quais tokens já foram reais.

O que esta API deliberadamente não devolve

  • O config de um monitor. Ele pode conter credenciais.
  • De qual região uma verificação foi executada. Onde verificamos é decisão nossa e podemos mudá-la conforme colocamos e movemos sondas. Seria uma promessa sobre a nossa infraestrutura a respeito da qual você não poderia fazer nada, e também não é mostrada em nenhuma outra parte do produto.

Exporting your data

Two routes hand back a file rather than a message, so that taking your data out does not mean paging through a collection endpoint a thousand times. Both are on every plan, the free one included — what a plan changes is how much history there is to export, not whether you may.

GET /export/{entity}

Um tipo de linhas, em CSV ou JSON. entity é um de monitors, hosts, status-pages, notification-channels, members, incidents, incident-events, postmortems, audit-log, error-issues, uptime-daily, uptime-hourly ou analytics-hourly. Qualquer outro responde 404.

format é csv (predefinido) ou json. from e to são marcas temporais RFC 3339. bomacrescenta uma marca de ordem de bytes UTF-8 ao CSV: o Excel precisa dela para nomes não ASCII, e a maioria das linguagens de script lê-a como parte do primeiro cabeçalho de coluna — por isso está desligada salvo pedido.

Parâmetros e respostas
NomeLocalTipo
entity obrigatóriopathstring
bomqueryboolean
formatquerystring
fromquerystring
toquerystring
Códigos de status200 400 401 403 404 429
Limite de requisições6 por hora

GET /export

Tudo o que a chave pode ler, num zip: um ficheiro por entidade mais manifest.json, que diz o que o arquivo contém, quantas linhas tem cada ficheiro e que entidades faltam. O que o papel da chave não pode ler fica de fora em vez de recusar o pedido inteiro, e o manifesto impede que isso aconteça em silêncio.

Parâmetros e respostas
NomeLocalTipo
bomqueryboolean
formatquerystring
fromquerystring
toquerystring
Códigos de status200 400 401 403 404 429
Limite de requisições6 por hora

What an export does not contain

Uma exportação não contém nada que autentique: nem configuração de canais, nem tokens de heartbeat, nem hashes de palavras-passe. A configuração de um monitor vai incluída, sem nada com forma de credencial — corpo do pedido, cabeçalhos, comunidade SNMP, credenciais de caixa de correio. Os resultados de verificação em bruto também não: a retenção elimina-os, por isso a disponibilidade vem dos agregados.

Size, and the one refusal you may meet

As séries horárias estão limitadas a 92 dias por pedido; uma janela maior é recusada com export_window_too_wide em vez de ser encurtada em silêncio. Limite próprio: 6 exportações por hora por organização.

Versionamento

A versão vai no caminho. Campos serão acrescentados às respostas — trate os desconhecidos como algo a ignorar e não como um erro — mas nada será removido da v1 nem mudará de significado dentro dela.

Falta alguma coisa?

A superfície é deliberadamente pequena: cobre um painel de parede, um resumo em um chat e um script de deploy que silencia um monitor durante uma publicação. Se você está construindo algo que ela não alcança, escreva para support@vitrinaengine.com — saber o que as pessoas realmente querem é como se escolhe o próximo endpoint.

Preços · Termos