---
title: Push monitors
description: Heartbeat monitoring for cron jobs, backups and batch pipelines — alert when something fails to check in.
sidebar:
  label: Push (heartbeats)
---

{/* Source of truth: packages/api/src/monitors/push.controller.ts,
    packages/shared/src/routes.ts (push.receive, regeneratePushToken),
    packages/shared/src/monitors.ts (pushConfigSchema, grace-period bounds),
    packages/shared/src/http.ts (GlowoHeaders.IDEMPOTENCY_KEY). */}

Every other monitor type reaches out and checks something. A **push monitor**
works the other way round: your job calls Glowo, and Glowo alerts you when the
call does not arrive.

Use it for work that has no endpoint to poll — nightly backups, cron jobs,
queue workers, ETL runs.

## How it works

1. Create a push monitor. Glowo gives you a URL containing a secret token.
2. Your job requests that URL when it finishes successfully.
3. If no request arrives within the **grace period**, the monitor goes `DOWN`
   and your alerts fire.

## The endpoint

```http
POST https://api.glowo.dev/push/<your-token>
```

Returns `202 Accepted` with `{"ok": true}`. Rate limited to **60 requests per
minute** per token.

Add it to the end of your job:

<Snippet id="push.from-backup-job" />

In a crontab:

```txt
15 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 -X POST https://api.glowo.dev/push/<your-token>
```

:::caution
Put the call **after** the work and chain it with `&&`. A heartbeat that fires
regardless of the exit code reports success while the job is failing — which is
worse than no monitor at all, because it looks green.
:::

## Reporting a failure

A job that knows it failed can say so instead of going silent, which turns a
grace-period wait into an immediate alert:

<Snippet id="push.report-failure" />

| Parameter | Values | Notes |
| --- | --- | --- |
| `status` | `up`, `down` | Case-insensitive — `DOWN` and `Down` both work. |
| `message` | text | Shown on the heartbeat. |
| `msg` | text | Alias for `message`. If both are sent, `message` wins. |

Unknown query parameters are ignored rather than rejected, so a tracking
parameter appended by something in the middle will not break your heartbeat.

## Grace period

The grace period is how long Glowo waits after the expected check-in before
declaring the monitor `DOWN`.

| | Value |
| --- | --- |
| Default | 60 seconds |
| Minimum | 0 seconds |
| Maximum | 31,622,400 seconds (366 days) |

Set it to your job's normal runtime plus comfortable slack. A backup that
usually takes 20 minutes and runs hourly wants a grace period well over 20
minutes, or a slow night will page you.

## Retries without duplicate heartbeats

If your job retries the HTTP call, send an `Idempotency-Key` header so the
retries collapse into a single heartbeat:

<Snippet id="push.idempotency-key" />

The key must be printable ASCII, up to 200 characters. A malformed value is
ignored rather than rejected — a bad header will never cost you a heartbeat.

## Rotating the token

The push URL is a bearer secret: anyone holding it can report your job healthy.
If it leaks, rotate it.

```http
POST /monitors/<monitor-id>/regenerate-push-token
```

:::caution
The new token is returned **once** and is never readable again — Glowo stores
only a hash, and reading a monitor never returns its token. The old token stops
working **immediately**, so update every pusher before you rotate, not after.
:::

## Choosing between push and HTTP

If the thing you want to watch has a URL you can call, use an
[HTTP monitor](/monitors/http) — it tells you the service is up right now. Use a
push monitor when the only evidence that something worked is that it *ran*.
