Skip to content

for developers

Report every job runwith one HTTP call.

The public API is the telemetry endpoint your cron jobs and workers call when they start, finish or fail. It is the same contract the SDKs and the dashboard snippets use.

Quick start

  1. Create a job monitor

    In the dashboard, add a cron job monitor with its schedule and grace period. Note its monitor key.

  2. Create an API key

    In Settings → API, create a key with the telemetry scope. It is shown once and stored only as a hash, so keep it in a server-side secret.

  3. Report each run

    Send RUN when the job starts, then COMPLETE or FAIL when it ends. FastMonitor opens an issue if a run fails, runs too long or never arrives.

shell
curl -X POST "$API_BASE_URL/e/execution-events" \
  -H "Authorization: Bearer $MAKI_MONITOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"monitorKey": "daily-report", "state": "RUN"}'
$API_BASE_URL is the API address shown with the telemetry snippet on each job monitor's page in the dashboard.

The endpoint

POST /e/execution-events

FieldNotes
monitorKeyrequiredThe key of a job monitor.
staterequiredRUN, COMPLETE or FAIL.
timestampISO 8601, UTC. Defaults to the time the request arrives.
durationRun time in milliseconds, usually sent with COMPLETE.
errorMessageFree text, usually sent with FAIL.
metadataAny JSON object you want stored with the event.
idempotencyKeyA stable key per logical event. Accepted and echoed back; not yet used to drop duplicates.
request body
{
  "monitorKey": "daily-report",
  "state": "COMPLETE",
  "timestamp": "2026-06-13T10:00:00.000Z",
  "duration": 1234,
  "metadata": { "deployment": "prod" },
  "idempotencyKey": "daily-report:2026-06-13T10:00:00Z:COMPLETE"
}
201 response
HTTP/1.1 201 Created

{
  "ok": true,
  "monitorId": "mon_123",
  "monitorKey": "daily-report",
  "state": "COMPLETE",
  "acceptedAt": "2026-06-13T10:00:00.000Z",
  "currentState": "HEALTHY"
}

Authentication

Bearer API key

Send Authorization: Bearer <api-key>. The older X-Api-Key header still works for existing integrations. The key needs the monitor:telemetry or monitor:write scope and can only report for monitors in its own account.

Keep it on the server

Keys are stored as hashes and shown once, when you create them. Never put a key in browser code or in a NEXT_PUBLIC_* variable. If you lose one, create a new key.

Errors and retries

Errors return ok: false with a stable code. Retry 429, 5xx and network errors with exponential backoff, and send the same idempotencyKey on each retry. The SDKs do this for you (two retries, 10 second timeout).

HTTPcodeMeaning
401UNAUTHENTICATEDNo API key on the request.
401INVALID_API_KEYThe key is unknown or expired, or its user is inactive.
403INSUFFICIENT_SCOPEThe key has no telemetry scope (monitor:telemetry or monitor:write).
404MONITOR_NOT_FOUNDNo monitor with this key belongs to the key's account.
400INVALID_STATEstate is not RUN, COMPLETE or FAIL.
400VALIDATION_ERRORmonitorKey or state is missing, or idempotencyKey is malformed.
400MONITOR_TYPE_UNSUPPORTEDThe monitor is not a job monitor.
429RATE_LIMITEDToo many requests. Retry with backoff.
500INTERNAL_ERRORSomething failed on our side. Retry with backoff.
error response
HTTP/1.1 404 Not Found

{
  "ok": false,
  "code": "MONITOR_NOT_FOUND",
  "message": "No monitor exists for this key."
}

SDKs

The SDKs are not on npm, PyPI or Packagist yet, so the install commands below will not work until they are published. Until then, use the HTTP call above: the SDKs send exactly that request.

JavaScript / TypeScript

install
npm install @maki/monitor
nightly-import.ts
import { MakiMonitor } from "@maki/monitor";

const monitor = new MakiMonitor({
  apiKey: process.env.MAKI_MONITOR_API_KEY!, // server-side secret
});

// Sends RUN, then COMPLETE with the duration, or FAIL if it throws.
await monitor.runJob("nightly-import", async () => {
  await importRows();
});

Python

install
pip install makimonitor
daily_report.py
import os
from makimonitor import MonitorClient

client = MonitorClient(api_key=os.environ["MAKI_MONITOR_API_KEY"])

# RUN on enter, COMPLETE on success, FAIL on exception (re-raised).
with client.job("daily-report"):
    run_daily_report()

PHP

install
composer require maki/monitor-php
weekly-report.php
use Maki\Monitor\TelemetryClient;

$client = new TelemetryClient(getenv('MAKI_MONITOR_API_KEY'));

// RUN before, COMPLETE on success, FAIL on throw (re-thrown).
$client->job('weekly-report', function () {
    (new WeeklyReportJob())->run();
});

The JavaScript SDK also has a Next.js helper, monitorJob from @maki/monitor/next, for route handlers and server actions. Every SDK runs server-side only and never logs your key.

What the API does not do yet

There is no public API for creating or changing monitors, alert settings or billing: you set those up in the dashboard. There is no automation screen in the dashboard yet: our team sets up your automation rules and handles run approvals with you, on request. Uptime, SSL, DNS and broken-link checks run from FastMonitor's side and need no API calls at all. Questions? Get in touch or read the FAQs.

Expecting something faster than FastMonitor?

Come on, give it a go. You won't be disappointed.