API Reference

API: Heartbeats

Heartbeat monitors work by receiving periodic pings from your services. If a ping does not arrive within the expected window, Beacon treats the service as down and creates an incident. This page documents the heartbeat endpoint and shows how to integrate it with common schedulers and languages.

Endpoint

POST /api/v1/heartbeat/{token}

The {token} is the unique identifier for your heartbeat monitor. You can find it in the monitor's settings page in the dashboard.

Authentication

No authentication header is required. The token embedded in the URL serves as the authentication mechanism. Each token is a cryptographically random string that uniquely identifies a single heartbeat monitor.

Treat heartbeat tokens as secrets. Anyone with the token can send pings to your monitor, which would reset its failure detection timer. Do not commit tokens to public repositories or expose them in client-side code.

Rate limiting

The heartbeat endpoint is rate limited to 60 requests per minute per IP address. Under normal operation -- where you send one ping per monitor interval -- you will never approach this limit. If you exceed the rate limit, the server responds with 429 Too Many Requests.

Request

No request body is required. Send an empty POST request to the endpoint. Headers such as Content-Type are not required either -- the server ignores the request body entirely.

Response

Success

HTTP/1.1 200 OK
Content-Type: application/json

{
    "ok": true
}

Invalid or disabled token

HTTP/1.1 404 Not Found
Content-Type: application/json

{
    "message": "Not Found"
}

A 404 is returned if the token does not match any active heartbeat monitor, or if the monitor has been disabled.

What happens on ping

When Beacon receives a valid heartbeat ping, the following actions occur:

  • next_check_at is reset to the current time plus the monitor's configured interval.
  • consecutive_failures is reset to 0.
  • The monitor's state is set to up.
  • If the monitor was previously down with an active auto-created incident, that incident is automatically resolved.

Quick example

curl -X POST https://usebeacon.pro/api/v1/heartbeat/abc123def456

Replace abc123def456 with your monitor's actual heartbeat token.

Language examples

PHP

use Illuminate\Support\Facades\Http;

// Send a heartbeat ping after your task completes
Http::post('https://usebeacon.pro/api/v1/heartbeat/abc123def456');

Node.js

// Send a heartbeat ping after your task completes
await fetch('https://usebeacon.pro/api/v1/heartbeat/abc123def456', {
    method: 'POST',
});

Ruby

require 'net/http'

# Send a heartbeat ping after your task completes
Net::HTTP.post(URI('https://usebeacon.pro/api/v1/heartbeat/abc123def456'), '')

Python

import requests

# Send a heartbeat ping after your task completes
requests.post('https://usebeacon.pro/api/v1/heartbeat/abc123def456')

Bash / cron

#!/usr/bin/env bash
# Run your task, then send a heartbeat on success
/usr/local/bin/my-backup-script.sh && \
    curl -fsS -X POST 'https://usebeacon.pro/api/v1/heartbeat/abc123def456'

The -fsS flags tell curl to fail silently on HTTP errors (-f), suppress the progress bar (-s), but still show errors (-S). The && ensures the ping is only sent if your script exits successfully.

Integrating with schedulers

The most common pattern is to send a heartbeat ping at the end of a scheduled task. If the task fails or hangs, the ping never fires, and Beacon detects the missed heartbeat.

Laravel Scheduler

// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
    $schedule->command('invoices:generate')
        ->daily()
        ->after(function () {
            Http::post('https://usebeacon.pro/api/v1/heartbeat/abc123def456');
        });
}

Node cron

import cron from 'node-cron';

cron.schedule('0 * * * *', async () => {
    await processHourlyReport();

    // Ping heartbeat on success
    await fetch('https://usebeacon.pro/api/v1/heartbeat/abc123def456', {
        method: 'POST',
    });
});

Sidekiq

class DailyReportWorker
    include Sidekiq::Worker

    def perform
        generate_daily_report

        # Ping heartbeat after successful execution
        Net::HTTP.post(URI('https://usebeacon.pro/api/v1/heartbeat/abc123def456'), '')
    end
end

crontab

# Run backup every day at 2:00 AM, ping heartbeat on success
0 2 * * * /usr/local/bin/backup.sh && curl -fsS -X POST 'https://usebeacon.pro/api/v1/heartbeat/abc123def456'

Failure detection

Beacon runs a monitors:check command every minute. During each run, it checks whether any heartbeat monitor has passed its next_check_at timestamp without receiving a ping.

If a heartbeat is overdue:

  • The monitor's consecutive_failures counter is incremented.
  • If consecutive_failures reaches the configured threshold (the same threshold setting used by HTTP monitors), the monitor is marked as down.
  • When a monitor transitions to down, Beacon sets the linked component's status to reflect the outage and creates an incident on the linked status page.

When the next ping arrives, the monitor returns to up, the component status is restored, and the auto-created incident is resolved -- all automatically.

Set your heartbeat interval to match the schedule of the task you are monitoring. For example, if your cron job runs every hour, configure the heartbeat monitor with a 60-minute interval. Beacon will expect a ping at least once every 60 minutes.