Referência · REST e MCP

API do Tá Rodando v1

Monitores e canais de alerta via REST ou MCP — feita pra agentes de IA e humanos.

Basehttps://tarodando.com.br/api/v1

Introdução

Monitoramento de serviços HTTP com status page em português. Esta referência é escrita pra um agente de IA (ou um humano com pressa) ler e agir.

Formato: JSON. Erros voltam { "error": "<codigo>", "message": "<o que houve e o que fazer>" }.

Autenticação

Toda chamada leva o header Authorization: Bearer trd_live_....

Como obter a chave: painel em https://tarodando.com.br/app/plano, seção "Chaves de API" (login por email ou GitHub em https://tarodando.com.br/entrar, grátis, sem cartão). Se você é um agente, não precisa de chave: conecte o servidor MCP (seção "Agente? Conecte o MCP") e o usuário autoriza com um clique, conta nova inclusa.

Planos e limites

Grátis: 10 monitores ativos, checagem a cada 5 ou 15 min.

Pro (R$79/mês): 30 monitores, checagem a cada 1 min.

Monitor acima do teto fica pausado (não checa). A conta guarda até 3× o teto em monitores, contando os pausados.

Servidor MCP (Claude, ChatGPT, Codex, Cursor)

O Tá Rodando tem um servidor MCP remoto em https://tarodando.com.br/mcp (Streamable HTTP, sem sessão). Seu agente cria e gerencia monitores e canais de alerta direto da conversa, com o mesmo teto de plano e as mesmas validações da API REST.

Hosts web (Claude.ai, ChatGPT) conectam por OAuth: o usuário faz login por email ou GitHub, vê o nome do app que pede acesso e clica em Permitir. Sem conta ainda? O Permitir cria a conta na hora, sem cartão. Pra cortar o acesso: painel → Plano → Apps conectados → Desconectar.

Clientes locais (Claude Code, Codex, Cursor e qualquer agente com terminal) entram pelo login no navegador (device flow, OAuth 2.0 RFC 8628): o agente abre a página com um código, o usuário confere e clica em Permitir, e o agente segue na mesma sessão. Pra script ou CI, sem agente, a chave de API no header Authorization: Bearer trd_live_... também vale.

Limite: 60 chamadas por minuto por credencial. Acima disso a resposta é HTTP 429 com Retry-After e um erro JSON-RPC (code -32000, data.error = "rate_limited"). É um freio anti-loop: espere o Retry-After e continue.

Claude Code

Recomendado: plugin

/plugin marketplace add tarodando/tarodando-agent
/plugin install tarodando@tarodando

Sem plugin

  1. Rode o comando abaixo no terminal (fora do Claude Code).
  2. Depois reinicia o Claude Code (ou roda /mcp na sessão), escolhe tarodando → Authenticate, faz login no Tá Rodando e clica em Permitir.
claude mcp add --transport http tarodando https://tarodando.com.br/mcp

Codex

  1. Rode o comando abaixo no terminal. O Codex detecta o OAuth e abre o navegador: faça login no Tá Rodando e clique em Permitir.
  2. Não abriu o navegador? Rode codex mcp login tarodando. Depois abra uma sessão nova do Codex.
codex mcp add tarodando --url https://tarodando.com.br/mcp

Claude.ai

  1. Customize → Connectors → + → Add custom connector.
  2. URL: https://tarodando.com.br/mcp. Deixe OAuth Client ID e Secret (Advanced settings) em branco.
  3. Clique em Add e depois em Connect, faça login no Tá Rodando e clique em Permitir.

ChatGPT

  1. Precisa de plano pago (Plus, Pro, Business…); em Business e Enterprise o admin do workspace precisa liberar o Developer mode antes. Settings → Apps → Advanced settings → ative o Developer mode.
  2. Clique em Create e use a URL do servidor MCP: https://tarodando.com.br/mcp. A autenticação é OAuth, descoberta sozinha.
  3. Faça login no Tá Rodando e clique em Permitir. A OpenAI muda o nome desses menus com frequência: se não achar, procure por Developer mode nas Settings.

Cursor

  1. Em ~/.cursor/mcp.json (o Cursor abre o OAuth no primeiro uso):
{
  "mcpServers": {
    "tarodando": { "url": "https://tarodando.com.br/mcp" }
  }
}

Tools

  • ver_contamonitors:readplano, teto de monitores, intervalos permitidos, status page (identityChosen: false = nome e endereço ainda são os automáticos; incidentesAbertos = incidentes públicos em andamento) e onboarding (primeiros passos, cada um com label e url)
  • listar_monitoresmonitors:readtodos os monitores da conta, com state, channels (avisar em) e section/statusPage na página (statusPage null = privado)
  • ver_monitormonitors:readum monitor + última checagem + motivo da falha (lastFailure) + ocorrência aberta (ocorrenciaAberta, ou null)
  • testar_urlmonitors:readroda um check agora (de um monitor pelo id, ou de uma URL) sem gravar nada: ok, status HTTP, latência e motivo da falha; 10 por minuto por conta
  • listar_checksmonitors:readchecks anteriores (paginados) + % de disponibilidade, falhas e latência de 24h, 7d, 30d ou 90d
  • listar_ocorrenciasmonitors:readocorrências (quedas privadas, só o time vê) dos últimos 90 dias: início, fim, duração, motivo, quem foi avisado por canal e o incidente publicado (ou null). Filtros: monitor, abertas
  • ver_ocorrenciamonitors:readuma ocorrência + linha do tempo com os mesmos textos do painel (falhas, avisos por canal, volta)
  • criar_monitormonitors:writetesta a URL, cria o monitor (privado; com section, aparece na status page) e grava o 1º check. keyword opcional: resposta sem o texto conta como falha. URL falhando só com confirmar: true
  • atualizar_monitormonitors:writemuda nome, URL, intervalo, seção ou keyword (URL ou keyword nova passa pelo mesmo teste)
  • pausar_monitormonitors:writepara de checar e avisar sem apagar o histórico; libera a vaga do plano e a página mostra Pausado
  • retomar_monitormonitors:writevolta a checar no próximo ciclo (até 30 min); sem vaga no plano, devolve plan_limit e segue pausado
  • remover_monitormonitors:writeremove o monitor (destrutiva)
  • listar_canaischannels:readcanais de alerta e monitores vinculados (webhook mascarado)
  • criar_canalchannels:writeemail, Slack, Discord, Google Chat, webhook ou Telegram (volta um connectUrl pro usuário abrir); até 20 por conta
  • vincular_canalchannels:writeliga o canal a monitores (lista de ids ou "all")
  • testar_canalchannels:writemanda a mensagem de teste; 1 por minuto por canal (senão rate_limited, espere 60 s)
  • remover_canalchannels:writeapaga o canal e os vínculos (destrutiva)
  • configurar_status_pagepage:writecria a status page (nome, endereço e monitores públicos — ids ou "all" — escolhidos, sem valor padrão) ou muda nome, endereço (subdomínio), descrição, links, logo e favicon
  • estruturar_paginapage:writeo lugar de pôr monitor em seção: salva a estrutura inteira da página; quem fica fora volta a privado
  • publicar_ocorrenciapage:writesem confirmar, devolve o rascunho do incidente público (título, serviço, início, severidade, status, mensagem); com confirmar: true, publica na status page e avisa os assinantes. Uma ocorrência gera no máximo um incidente
  • atualizar_incidentepage:writeposta um update no incidente público (investigando, identificado, monitorando ou resolvido) e avisa os assinantes; resolved encerra o incidente

Criar monitor

POST/monitors

Cria um monitor HTTP e roda o primeiro check na hora — o corpo do 201 já reflete o resultado.

Corpo

  • urlstringobrigatório

    endereço público a monitorar — IPs privados são recusados

  • namestring

    derivado da URL se omitido

  • intervalMinint

    padrão 5; grátis aceita 5 ou 15, Pro também 1

  • sectionstring

    nome do agrupamento na página — casa com seção existente ou cria. Sem section, o monitor nasce privado (não aparece na status page). Só vale se a conta tem status page

  • keywordstring

    texto que a resposta precisa conter (até 200 caracteres, diferencia maiúsculas). Resposta 2xx sem ele conta como falha — pega a página em branco que responde 200. Só o 1º MB do corpo é lido, e nada é guardado

  • confirmFailingboolean

    true grava mesmo com a URL falhando agora (senão: 422 url_failing com o motivo)

Antes de gravar, a URL é testada: a sua própria status page e endereços do Tá Rodando que não existem são recusados; URL falhando dá 422 url_failing, a não ser que venha confirmFailing: true. Criada com confirmFailing, ela vem com state: "failing" e lastStatus: "fail" — último check falhando nunca aparece como operational em state. status (o que a página pública mostra) muda no próximo check do monitor: se falhar de novo, vira major_outage e o time é avisado. lastStatus: null só acontece se o check não pôde nem rodar (erro interno raro) — nesse caso, consulte GET /monitors/{id}. A status page pública fica em statusPage (null se a conta não tem página: o monitor só checa e avisa).

POST/monitors
curl -X POST https://tarodando.com.br/api/v1/monitors \
  -H "Authorization: Bearer trd_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.exemplo.com.br/healthcheck",
    "name": "API",
    "intervalMin": 5,
    "section": "Backend"
  }'
Resposta 201
{
  "monitor": {
    "id": "cm9x1a2b3c4d5e6f7g8h9i0j1",
    "name": "API",
    "url": "https://app.exemplo.com.br/healthcheck",
    "intervalMin": 5,
    "keyword": null,
    "certExpiresAt": "2026-12-10T12:05:04.000Z",
    "status": "operational",
    "state": "operational",
    "lastStatus": "ok",
    "lastCheckedAt": "2026-07-16T12:00:00.000Z",
    "section": "Backend",
    "paused": false,
    "pausedManually": false,
    "createdAt": "2026-07-16T12:00:00.000Z",
    "statusPage": "https://exemplo.tarodando.com.br"
  }
}

Listar monitores

GET/monitors

Lista todos os monitores da conta, no mesmo shape do criar e com channels: os canais que o monitor avisa.

state = o que mostrar ao usuário (operational, degraded, partial_outage, major_outage, failing, paused, awaiting); status = o que a página pública mostra. failing = o último check falhou mas o monitor ainda não marcou fora do ar (acontece com o check feito na criação; o próximo check do monitor decide). Uma falha num check do monitor agenda uma re-checagem ~30 s depois; a 2ª falha seguida vira major_outage e avisa o time. paused: true = não está sendo checado (pausado pelo usuário ou além do teto do plano); pausedManually: true = pausado com pausar_monitor. keyword = texto que a resposta precisa conter (null = só o status HTTP decide). certExpiresAt = validade do certificado TLS visto no último check (null = ainda não visto); a 14 e a 3 dias do vencimento os canais do monitor recebem um aviso, uma vez por certificado, sem marcar fora do ar. channels = quem é avisado quando o monitor cai e volta (label como o painel mostra; URL de webhook nunca aparece); lista vazia = não avisa ninguém. statusPage null = monitor privado (checa e avisa, sem aparecer na página); section = seção onde ele aparece. url pode ser null em componentes legados criados manualmente (sem monitoramento) — trate como opcional.

GET/monitors
curl -X GET https://tarodando.com.br/api/v1/monitors \
  -H "Authorization: Bearer trd_live_..."
Resposta 200
{
  "monitors": [
    {
      "id": "cm9x1a2b3c4d5e6f7g8h9i0j1",
      "name": "API",
      "url": "https://app.exemplo.com.br/healthcheck",
      "intervalMin": 5,
      "keyword": null,
      "certExpiresAt": "2026-12-10T12:05:04.000Z",
      "status": "operational",
      "state": "operational",
      "lastStatus": "ok",
      "lastCheckedAt": "2026-07-16T12:00:00.000Z",
      "section": "Backend",
      "paused": false,
      "pausedManually": false,
      "createdAt": "2026-07-16T12:00:00.000Z",
      "statusPage": "https://exemplo.tarodando.com.br",
      "channels": [
        { "label": "voce@exemplo.com.br (você)", "kind": "email" },
        { "label": "Discord · discord.com", "kind": "discord" }
      ]
    }
  ]
}

Detalhe de um monitor

GET/monitors/{id}

Um monitor + resultado da última checagem.

Parâmetros

  • idstringobrigatório

    id do monitor

lastCheck: null = nunca checado. lastFailure só vem preenchido enquanto o monitor está falhando: { reason, httpStatus, message, checkedAt }, com reason em dns_not_found / timeout / connection_refused / tls / redirect / http_4xx / http_5xx / blocked_destination / unknown e message em português.

GET/monitors/{id}
curl -X GET https://tarodando.com.br/api/v1/monitors/cm9x1a2b3c4d5e6f7g8h9i0j1 \
  -H "Authorization: Bearer trd_live_..."
Resposta 200
{
  "monitor": {
    "id": "cm9x1a2b3c4d5e6f7g8h9i0j1",
    "name": "API",
    "url": "https://app.exemplo.com.br/healthcheck",
    "intervalMin": 5,
    "keyword": null,
    "certExpiresAt": "2026-12-10T12:05:04.000Z",
    "status": "operational",
    "state": "operational",
    "lastStatus": "ok",
    "lastCheckedAt": "2026-07-16T12:00:00.000Z",
    "section": "Backend",
    "paused": false,
    "pausedManually": false,
    "createdAt": "2026-07-16T12:00:00.000Z",
    "statusPage": "https://exemplo.tarodando.com.br"
  },
  "lastCheck": {
    "ok": true,
    "latencyMs": 123,
    "error": null,
    "checkedAt": "2026-07-16T12:00:00.000Z"
  },
  "lastFailure": null
}

Atualizar monitor

PATCH/monitors/{id}

Corpo com qualquer subconjunto dos campos abaixo. Campos ausentes não mudam.

Parâmetros

  • idstringobrigatório

    id do monitor

Corpo

  • namestring

    novo nome

  • urlstring

    nova URL (mesma validação do criar)

  • intervalMinint

    novo intervalo (limites do plano valem)

  • sectionstring | null

    nome da seção (casa com existente ou cria); null remove da seção. Num monitor privado, section publica: ele entra no fim da status page, nessa seção (conta sem status page dá 422 invalid_section)

  • keywordstring | null

    novo texto que a resposta precisa conter (testado na hora, como URL nova); null ou "" tira a checagem de texto

  • confirmFailingboolean

    true grava a URL (ou keyword) nova mesmo falhando agora

PATCH/monitors/{id}
curl -X PATCH https://tarodando.com.br/api/v1/monitors/cm9x1a2b3c4d5e6f7g8h9i0j1 \
  -H "Authorization: Bearer trd_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API pública",
    "intervalMin": 15
  }'
Resposta 200
{
  "monitor": {
    "id": "cm9x1a2b3c4d5e6f7g8h9i0j1",
    "name": "API",
    "url": "https://app.exemplo.com.br/healthcheck",
    "intervalMin": 5,
    "keyword": null,
    "certExpiresAt": "2026-12-10T12:05:04.000Z",
    "status": "operational",
    "state": "operational",
    "lastStatus": "ok",
    "lastCheckedAt": "2026-07-16T12:00:00.000Z",
    "section": "Backend",
    "paused": false,
    "pausedManually": false,
    "createdAt": "2026-07-16T12:00:00.000Z",
    "statusPage": "https://exemplo.tarodando.com.br"
  }
}

Remover monitor

DELETE/monitors/{id}

Remove o monitor e o serviço correspondente da página.

Parâmetros

  • idstringobrigatório

    id do monitor

DELETE/monitors/{id}
curl -X DELETE https://tarodando.com.br/api/v1/monitors/cm9x1a2b3c4d5e6f7g8h9i0j1 \
  -H "Authorization: Bearer trd_live_..."
Resposta 200
{ "ok": true }

Listar canais

GET/channels

Lista os canais de alerta da conta (por onde o time recebe "caiu/voltou") e os monitores vinculados a cada um.

URL de webhook é credencial: volta mascarada (só o host). Email volta inteiro. Telegram volta com target null e connected (true/false); enquanto connected for false, o canal não recebe alerta e connectUrl/connectGroupUrl trazem o link de conexão.

GET/channels
curl -X GET https://tarodando.com.br/api/v1/channels \
  -H "Authorization: Bearer trd_live_..."
Resposta 200
{
  "channels": [
    {
      "id": "ch9x1a2b3c4d5e6f7g8h9i0j1",
      "kind": "slack",
      "label": "#alertas",
      "target": "https://hooks.slack.com/…",
      "monitorIds": ["cm9x1a2b3c4d5e6f7g8h9i0j1"],
      "createdAt": "2026-07-16T12:00:00.000Z"
    }
  ]
}

Criar canal

POST/channels

Cria um canal de alerta. Ele nasce sem monitores: depois vincule com POST /channels/{id}/monitors.

Corpo

  • kindstringobrigatório

    email, slack, discord, google_chat, webhook ou telegram

  • targetstring

    email, ou URL https pública do webhook. Obrigatório, menos no telegram (ignorado)

  • labelstring

    nome do canal no painel

Máximo de 20 canais por conta (channel_limit). Telegram: mande só kind (e label, se quiser). O canal volta com connected: false, connectUrl (chat pessoal) e connectGroupUrl (grupo do time), os dois https://t.me/…; o usuário abre um deles no Telegram e toca em Começar (ou escolhe o grupo), e aí o canal passa a receber. O link vale 24 h e uma vez só; passou disso, apague o canal e crie outro. Web push é configurado no painel.

POST/channels
curl -X POST https://tarodando.com.br/api/v1/channels \
  -H "Authorization: Bearer trd_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "slack",
    "target": "https://hooks.slack.com/services/T000/B000/XXXX",
    "label": "#alertas"
  }'
Resposta 201
{
  "channel": {
    "id": "ch9x1a2b3c4d5e6f7g8h9i0j1",
    "kind": "slack",
    "label": "#alertas",
    "target": "https://hooks.slack.com/…",
    "monitorIds": [],
    "createdAt": "2026-07-16T12:00:00.000Z"
  }
}

Vincular canal a monitores

POST/channels/{id}/monitors

Liga o canal a monitores: quando um deles cair ou voltar, o alerta sai por esse canal. Soma aos vínculos que já existem; repetir não duplica.

Parâmetros

  • idstringobrigatório

    id do canal

Corpo

  • monitorIdsstring[] | "all"obrigatório

    ids de monitor, ou "all" pra todos os monitores de hoje (monitor criado depois não entra sozinho)

POST/channels/{id}/monitors
curl -X POST https://tarodando.com.br/api/v1/channels/cm9x1a2b3c4d5e6f7g8h9i0j1/monitors \
  -H "Authorization: Bearer trd_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "monitorIds": "all"
  }'
Resposta 200
{
  "channelId": "ch9x1a2b3c4d5e6f7g8h9i0j1",
  "monitorIds": ["cm9x1a2b3c4d5e6f7g8h9i0j1"]
}

Testar canal

POST/channels/{id}/test

Manda a mesma mensagem de teste do botão "Testar" da tela Alertas. Depois confirme com o humano que ela chegou.

Parâmetros

  • idstringobrigatório

    id do canal

Cooldown: 1 teste por minuto por canal. Antes disso volta 429 rate_limited — espere 60 s. Se o destino recusar, volta 502 send_failed; se a falha for nossa ou do provedor, 503 provider_error (não mexa no destino, tente de novo depois).

POST/channels/{id}/test
curl -X POST https://tarodando.com.br/api/v1/channels/cm9x1a2b3c4d5e6f7g8h9i0j1/test \
  -H "Authorization: Bearer trd_live_..."
Resposta 200
{
  "sent": true,
  "channel": {
    "id": "ch9x1a2b3c4d5e6f7g8h9i0j1",
    "kind": "slack",
    "label": "#alertas",
    "target": "https://hooks.slack.com/…",
    "createdAt": "2026-07-16T12:00:00.000Z"
  }
}

Remover canal

DELETE/channels/{id}

Apaga o canal e todos os vínculos dele com monitores, inclusive os feitos no painel. Não tem volta.

Parâmetros

  • idstringobrigatório

    id do canal

DELETE/channels/{id}
curl -X DELETE https://tarodando.com.br/api/v1/channels/cm9x1a2b3c4d5e6f7g8h9i0j1 \
  -H "Authorization: Bearer trd_live_..."
Resposta 200
{ "ok": true }

Erros

  • 401unauthorizedchave ausente, inválida ou revogada
  • 400invalid_bodycorpo não é JSON
  • 413payload_too_largecorpo acima de 64 KB
  • 422invalid_url / invalid_name / invalid_interval / invalid_section / invalid_keywordvalidação — a message diz o que corrigir (section em conta sem status page dá invalid_section; nome e seção até 100 caracteres, URL até 2048, keyword até 200, até 100 seções por página)
  • 422invalid_kind / invalid_target / invalid_monitorsvalidação de canal — a message diz o que corrigir
  • 422channel_limitconta já tem 20 canais — remova um
  • 403plan_limitteto de monitores do plano atingido — pause ou remova um (no grátis, a message traz o link de upgrade); ou a conta já guarda 3× o teto em monitores, contando os pausados — remova os que não usa
  • 422own_status_page / unknown_tarodando_hosta URL é a sua própria status page ou um endereço do Tá Rodando que não existe — monitore o seu site ou a sua API
  • 422url_failinga URL está falhando agora (a message diz o motivo) — confira, ou repita com confirmFailing: true para gravar assim mesmo
  • 409duplicate_urlessa URL já é monitorada nesta conta — monitorId traz o id do existente
  • 404not_found / monitor_not_foundid inexistente nesta conta / monitor da lista não existe
  • 409not_connectedteste de canal Telegram que ainda não foi conectado — o usuário precisa abrir o connectUrl e tocar em Começar
  • 429rate_limitedteste de canal repetido em menos de 60 s — espere um minuto; ou mais de 10 URLs validadas por minuto ao criar ou editar monitor — espere o tempo da message
  • 502send_failedo destino do canal recusou a mensagem de teste (email inválido, webhook 3xx/4xx, bot do Telegram bloqueado) — confira o destino
  • 503provider_errorfalha nossa ou do provedor no teste de canal (config, cota, 5xx, timeout) — o destino não é o problema; tente de novo em alguns minutos

O que a API v1 NÃO faz

Incidentes, assinantes da status page e web push são geridos no painel: https://tarodando.com.br/app.