Documentação
O CronObserver monitora jobs agendados por meio de check-ins. Você envia um POST quando o job termina, e nós te avisamos se algo atrasar ou falhar.
Referência HTTP completa: referência da API (OpenAPI).
Visão geral
- Crie um monitor e copie o token dele.
- Quando o job terminar, envie um check-in para a URL do monitor.
- Se o check-in não chegar no horário, você recebe alertas.
Endpoint de check-in
Use o token do monitor ou um token de integração. Check-ins aceitos retornam 204. GET e HEAD também funcionam, então qualquer ferramenta de ping HTTP consegue fazer check-in.
401quando o token de integração expirou.404quando o token não existe.4xxpara payloads JSON inválidos.
curl -i -X POST https://cronobserver.com/checkin/<token> # or simply curl -fsS https://cronobserver.com/checkin/<token>
Início, sucesso e falha
Reporte cada etapa de uma execução. Os três aceitam POST, GET e HEAD.
/checkin/<token>/start: a execução começou. Não muda o estado do monitor./checkin/<token>: a execução deu certo. Se vier depois de um start, a duração é registrada./checkin/<token>/fail: a execução falhou. Você recebe um alerta na hora, comexitCodeemessage, sem esperar o intervalo e a tolerância.
Envie o mesmo runId (no corpo ou como ?rid=) no início e no fim para ligar os dois quando as execuções se sobrepõem. Sem ele, o fim fecha a execução aberta mais recente.
Defina a Duração máxima no monitor (maxRuntimeSeconds na API): uma execução que começou e não deu certo nem falhou dentro desse tempo gera um alerta de travada, uma única vez.
URL=https://cronobserver.com/checkin/<token> RID=$(date +%s) curl -fsS "$URL/start?rid=$RID" if run-job; then curl -fsS "$URL?rid=$RID" else curl -fsS "$URL/fail?rid=$RID&exitCode=$?" fi
Payload opcional
Você pode enviar um payload JSON com detalhes da execução. Ele fica guardado com o check-in e ajuda a analisar falhas. "status": "failed" no check-in simples conta como /fail, então este é um relato de falha:
curl -X POST https://cronobserver.com/checkin/<token> \
-H "Content-Type: application/json" \
-d '{
"status": "failed",
"exitCode": 1,
"message": "Timeout calling the payments API",
"metadata": { "host": "worker-01" }
}'runId, exitCode e message ligam a execução e explicam uma falha. Para agentes de IA e jobs de LLM:
| Chave | Exemplo | Significado |
|---|---|---|
model | "claude-opus-5-5" | Modelo usado na execução |
tokens_in / tokens_out | 18234 / 2100 | Tokens consumidos |
cost_usd | 0.42 | Custo da execução |
items_processed | 37 | O que a execução produziu (linhas, tickets, e-mails) |
eval_score | 0.91 | Sua própria nota de qualidade, de 0 a 1 |
Todas as chaves são opcionais e ficam guardadas com a execução. Sozinhas, elas não disparam alertas.
curl -X POST https://cronobserver.com/checkin/<token> \
-H "Content-Type: application/json" \
-d '{"runId":"nightly-42","model":"claude-sonnet","tokens_in":18200,"tokens_out":2400,"cost_usd":0.09,"items_processed":120,"eval_score":0.94}'API REST (v1)
Gerencie monitores pelo código, pelo CI ou por um agente de IA. Crie uma chave de API em Configurações → Chaves de API. Cada chave pertence a uma organização e tem escopos: read, write e checkin. A chave aparece uma única vez; guardamos só o hash.
# list monitors
curl -s https://cronobserver.com/api/v1/monitors \
-H "Authorization: Bearer $CRONOBSERVER_API_KEY"
# create a monitor that expects a run every day at 21:00 in São Paulo, with 30 minutes of grace
curl -s -X POST https://cronobserver.com/api/v1/monitors \
-H "Authorization: Bearer $CRONOBSERVER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "nightly-summary-agent", "interval": {"type": "cron", "cronExpression": "0 21 * * ? *", "timezone": "America/Sao_Paulo"}, "graceMinutes": 30, "maxRuntimeSeconds": 1800}'| Endpoint | Escopo | O que faz |
|---|---|---|
GET /v1/monitors · GET /v1/monitors/{id} | read | Lista ou lê monitores |
POST /v1/monitors · PATCH · DELETE /v1/monitors/{id} | write | Cria, atualiza, apaga |
GET /v1/monitors/{id}/events | read | Check-ins, falhas e alertas, paginados |
GET /v1/monitors/{id}/explain | read | Por que o monitor está no estado atual |
POST /v1/monitors/{id}/pause · /resume | write | Pausa e retoma |
POST /v1/monitors/{id}/mute · /unmute | write | Silencia alertas (opcionalmente até uma data) |
POST /v1/monitors/{id}/checkin · /checkin/start · /checkin/fail | checkin | Reporta uma execução pelo id: sucesso, início ou falha |
GET /v1/incidents · POST /v1/incidents/{id}/ack | read · write | Incidentes abertos e confirmação |
Referência completa: OpenAPI 3.1 · documentação interativa. Os limites do plano valem na API exatamente como no painel.
Alertas no Telegram
- Telegram: abra o @CronObserverBot (
t.me/CronObserverBot) no Telegram e envie/start(num grupo, adicione o bot antes e envie/startlá). O bot responde com o ID do chat. Cole em ID do chat do Telegram no monitor (telegramChatIdna API). Para um canal, adicione o bot como administrador e cole o@usuariodo canal; guardamos o ID numérico dele. - Ele recebe os mesmos alertas do Slack e do Teams: atraso, execução com falha ou travada e recuperação. Também pode ser passo de uma política de escalonamento. Não conta na cota diária de e-mail. Plano Orbital.
Agendamentos cron e fusos horários
Monitores cron usam a sintaxe de cron da AWS e seguem o fuso horário do monitor (UTC por padrão). Na API, defina interval.timezone com um nome IANA: {"type":"cron","cronExpression":"0 9 * * ?","timezone":"America/Sao_Paulo"} espera o job às 09:00 em São Paulo. Um monitor novo passa a ser esperado no momento em que é criado: se o job nunca fizer check-in, você recebe um alerta depois da primeira janela mais a tolerância.
Exemplos rápidos
JavaScript (Node.js)
await fetch("https://cronobserver.com/checkin/<token>", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: "success", message: "Job finished" })
});TypeScript
type CheckinPayload = {
status: "success" | "failed";
message: string;
metadata?: Record<string, string | number | boolean>;
};
const payload: CheckinPayload = {
status: "success",
message: "Report generated",
metadata: { reportId: 42 }
};
await fetch("https://cronobserver.com/checkin/<token>", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});Go
payload := []byte(`{"status":"success","message":"Job completed"}`)
req, _ := http.NewRequest("POST", "https://cronobserver.com/checkin/<token>", bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
client.Do(req)Rails
require "net/http"
require "json"
uri = URI("https://cronobserver.com/checkin/<token>")
Net::HTTP.post(uri, { status: "success", message: "Job ok" }.to_json, "Content-Type" => "application/json")Java
HttpClient client = HttpClient.newHttpClient();
String payload = "{\"status\":\"success\",\"message\":\"Job completed\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://cronobserver.com/checkin/<token>"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
client.send(request, HttpResponse.BodyHandlers.discarding());Python (requests)
import requests
requests.post(
"https://cronobserver.com/checkin/<token>",
json={"status": "success", "message": "Job executed"}
)Integrações
GitHub Actions
Agende o workflow e envie um check-in no fim do job. Guarde o token em secrets.
- name: CronObserver check-in
if: success()
run: curl -fsS --retry 3 -X POST "$CRONOBSERVER_CHECKIN_URL"
env:
CRONOBSERVER_CHECKIN_URL: ${{ secrets.CRONOBSERVER_CHECKIN_URL }}GitLab CI
Use os agendamentos do GitLab e um stage final de notificação para enviar o check-in.
cronobserver:checkin:
stage: notify
image: curlimages/curl:8.11.1
script:
- curl -fsS --retry 3 -X POST "$CRONOBSERVER_CHECKIN_URL"
only:
- schedulesKubernetes CronJob
Guarde a URL em um Secret e injete no container do CronJob. O check-in acontece depois que o script termina. Sua imagem precisa ter curl (alpine: apk add --no-cache curl).
env:
- name: CRONOBSERVER_CHECKIN_URL
valueFrom:
secretKeyRef:
name: cronobserver-checkin
key: url
...
command: ["sh", "-c", "run-job && curl -fsS --retry 3 -X POST $CRONOBSERVER_CHECKIN_URL"]AWS Lambda
Use um agendamento do EventBridge para invocar a função e envie um check-in no fim.
await fetch(process.env.CRONOBSERVER_CHECKIN_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: "success", message: "Lambda ok" })
});Docker Compose
Defina a URL como variável de ambiente e rode o curl depois que o job terminar. Sua imagem precisa ter curl (alpine: apk add --no-cache curl). O $$ impede que o Compose substitua a variável antes de o container subir.
services:
job:
image: curlimages/curl:8.11.1
environment:
- CRONOBSERVER_CHECKIN_URL=https://cronobserver.com/checkin/<token>
command: sh -c "run-job && curl -fsS --retry 3 -X POST $$CRONOBSERVER_CHECKIN_URL"Tokens e segurança
Há dois tipos de token para check-ins:
- Token do monitor: permanente e ligado ao monitor.
- Token de integração: temporário, revogável e com validade (formato
it_*). Ideal para CI/CD e ambientes compartilhados.
Guarde os tokens em secrets ou variáveis de ambiente e evite comitá-los em repositórios.
Checks sintéticos
Disponível no Orbital (US$ 1,90/mês). No plano Free, os alertas são só por e-mail.
Checks sintéticos são sondas ativas executadas pelo CronObserver. Em vez de esperar um check-in, o sistema envia requisições HTTP para uma URL configurada e valida se a resposta é a esperada.
- Tipos suportados:
httpGetehttpPost. - Validação pelo status esperado (por exemplo, 200). Se o status for diferente, o check falha.
- Controle de timeout e medição do tempo de resposta.
- Proteção contra SSRF: bloqueia IPs privados e localhost (allowlist opcional).
Quando um check sintético falha, o monitor registra o erro e envia alertas. Quando ele se recupera, um evento de recuperação também é enviado.
Envie alertas para Datadog, Dynatrace, New Relic e Sentry
Configure as integrações por monitor. Os segredos são só de escrita, ficam criptografados e nunca são devolvidos pela API.
Disponível no Orbital (US$ 1,90/mês). No plano Free, os alertas são só por e-mail.
Obrigatório quando ativado
- Datadog:
apiKey - Dynatrace:
baseUrl+apiToken - New Relic:
apiKey(região opcional) - Sentry:
dsn
Detalhes do payload
- Tipo de alerta: atraso, escalada ou limite.
- Só metadados do monitor (sem payloads nem tokens).
- Os eventos incluem horários e o contexto do alerta.