# Scheduled job check-ins

> Each run of a job pings Pagerless. If a run is late, missed or fails, you hear about it, at the level you choose.

URL: https://pagerless.dev/docs/check-ins
Updated: 2026-10-22

## From your code

```js
import { monitor } from "pagerless";

await monitor("nightly-backup", { cron: "30 3 * * *", tz: "America/New_York" }, () => backup());
```

```go
err := pagerless.Monitor(ctx, "nightly-backup", pagerless.Schedule{Cron: "30 3 * * *"}, func(ctx context.Context) error {
	return backup(ctx)
})
```

```bash
curl -X POST https://events.pagerless.dev/v1/checkins/nightly-backup -H "Authorization: Bearer $PAGERLESS_KEY"
```

`monitor` reports ok with the duration, or failed with the error message and rethrows. An empty POST counts as ok; send `{"status":"failed","message":"..."}` for a failure.

## Schedules

| Field | Meaning |
| --- | --- |
| `cron` | 5 fields (`30 3 * * *`), ranges, steps, lists, names, or `@hourly` `@daily` `@weekly` `@monthly` `@yearly`. Daylight-saving aware. |
| `expectEverySeconds` | Instead of cron: an interval from 60 seconds to 400 days. |
| `tz` | IANA zone, such as `Europe/Berlin`. Default: your account's zone, else UTC. |
| `graceSeconds` | How late a run may be. Default: a tenth of the gap, between 5 minutes and 1 hour. |
| `level` | `tell` (default) or `wake`. Never log: a job nobody hears about isn't watched. |

Job names are 1 to 64 lowercase letters, digits, dots, dashes or underscores. Up to 200 per app. A job is watched from its first ping; editing it in the app overrides what the code sends.

Converting an AWS `cron(...)` or `rate(...)` expression? Use the [cron to check-in tool](https://pagerless.dev/tools/cron-check-in).
