Pulses are scheduled HTTP with stored results. Tunnels bring traffic to your machine and webhooks catch it while you are away. Pulses act on a schedule. Every run is stored as history (status, headers, and body), failures alert you when the state changes, and it all runs on OtterKit's servers, with no daemon, deploy, or process on your machine.
Scheduled runs#
A pulse calls a public URL on an interval and keeps the results:
# Call your cron endpoint every 10 minutes; responses are stored as run history
npx otterkit pulse 10m https://api.your-app.com/cron
# POST with a body and a header, hourly, stop after 3 days
npx otterkit pulse 1h https://api.your-app.com/digest --method POST \
--data '{"kind":"hourly"}' -H 'Authorization: Bearer …' --ttl 3dWrite intervals with s, m, h, or d, such as 30s, 10m, or 1d. The minimum is 30 seconds. Targets must be public http or https URLs; localhost and private addresses are refused. Each run times out after 10 seconds. Runs land in the same history as webhook captures, so you can browse them with otterkit requests <name>, the console's Pulses page↗, the Mac app, or the history API. When runs start failing you get one email, and one more when they recover, never a flood.
Dead-man's switch (--expect)#
--expect flips the direction. You get a URL that something must call within the window: a backup job, a nightly script, a data pipeline. If the window passes with no check-in, you get an alert email, and the next check-in sends the all-clear.
npx otterkit pulse --expect 15m
# → check in with: curl -X POST https://pulse-a1b2c3d4.otterkit.appCheck-ins are captured like webhook requests, body included, so "did the backup run?" and "what did it report?" have the same answer.
Options#
otterkit pulse <interval> <url> # active mode
otterkit pulse --expect <window> # dead-man's switch
--method <method> HTTP method for active runs (default GET)
-H, --header <h> Request header "Name: value" (repeatable)
--data <body> Request body for active runs
--ttl <duration> Auto-stop, e.g. 4h or 3d (default never)
--subdomain <name> Stable name: <name>.otterkit.app
--edit <name> Change a live pulse instead of creating one
--json Machine-readable outputEdit a live pulse#
Change a pulse in place with --edit. Pass only what changes: the interval, URL, --method, --data, or --expect. The history, URL, and billing window stay, and the next run is counted from the edit.
npx otterkit pulse --edit pulse-a1b2c3d4 5m
npx otterkit pulse --edit nightly-backup --expect 26hPulses aren't local daemons, so otterkit stop doesn't apply to them. Stop a pulse from the console's Pulses page, or with the stopToken that --json returns.
Pricing#
A pulse costs 1 credit per 100 runs, where a run is a scheduled call or a check-in. The first credit is charged at creation, and the same cap applies as everywhere else: never more than 300 credits ($3) per rolling 30 days. A nightly cron costs about a penny every three months; a monitor that runs every 10 minutes costs about 43 cents a month. Pulses default to --ttl never because they are meant to be set and forgotten, and the cap limits the bill.