User Guide

Everything you need to wire jobs into Did It Work and get alerted when they go quiet. Machine-readable version: docs.md.

Core concepts

Signing in is passwordless: enter your email and click the magic link we send you.

Job types

Simple — one ping, “it ran”

Use when you only need to know that the job ran. One HTTP call at the end of the job is the entire integration — right for most cron jobs: backups, certificate renewals, cleanup scripts. The optional JSON body ({"status", "message", "labels"}) is just extra context; an empty POST is a valid heartbeat.

# at the end of your job — or chained in the crontab entry itself:
curl -fsS -X POST "https://diw.run/ping/YOUR_JOB_ID" \
  -H "Authorization: Bearer $DIW_INGEST_KEY"

# crontab example — ping only if the job succeeded
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -X POST "https://diw.run/ping/YOUR_JOB_ID" -H "Authorization: Bearer $DIW_INGEST_KEY"

Advanced — full run lifecycle

Use when you care about how the job ran: duration, success vs failure, exit codes, and progress messages. Advanced jobs report an explicit start and end, so you also catch a job that starts and then hangs — something a single end-of-job ping can never tell you.

POST /ping/{job-id}/start               → {"status":"accepted","run_id":"..."}
POST /ping/{job-id}/{run-id}/message    {"message":"...", "labels":{...}}
POST /ping/{job-id}/{run-id}/end        {"status":"success|failure", "exit_code":N, ...}

/start returns a run_id; pass it to every later call. Messages are optional, appear on the run timeline, and can drive message-based alerting.

BASE="https://diw.run/ping/YOUR_JOB_ID"
AUTH="Authorization: Bearer $DIW_INGEST_KEY"

RUN_ID=$(curl -fsS -X POST "$BASE/start" -H "$AUTH" | jq -r .run_id)

curl -fsS -X POST "$BASE/$RUN_ID/message" -H "$AUTH" \
  -H "Content-Type: application/json" \
  -d '{"message":"extract finished, 1200 rows","labels":{"stage":"extract"}}'

./run-the-job
EXIT=$?
STATUS=$([ "$EXIT" -eq 0 ] && echo success || echo failure)

curl -fsS -X POST "$BASE/$RUN_ID/end" -H "$AUTH" \
  -H "Content-Type: application/json" \
  -d "{\"status\":\"$STATUS\",\"exit_code\":$EXIT}"

Choosing a type

You want to knowUse
“Did my cron job run today?”Simple
“Did it run, how long did it take, did it fail, and why?”Advanced

Any event can carry labels. They show up in the UI and can be matched by alert conditions (e.g. alert only when labels.severity equals critical).

Triggers and alerts

Alerting is configured per job in the Alerts panel. A rule reads like a sentence: When this happens · And only if · Wait for · Then do this · Resolve when.

Trigger eventFires whenJob types
job.heartbeata simple ping arrivessimple
job.heartbeat.misseda heartbeat did not arrive within the expected windowsimple
job.starteda run startsadvanced
job.messagea message event arrivesadvanced
job.completeda run ends (status: success | failure)advanced
job.timed_outa run started but did not end within timeout + graceadvanced

Conditions narrow the trigger (match all or any): completion status, exit code, message contains "…", and labels.<key> eq <value>.

Common recipes:

Contact points (email or webhook with your URL/method/headers) are managed org-wide, with a test button for sample deliveries. A firing rule opens an incident; repeat notifications can re-notify at an interval with an optional maximum. Incidents resolve automatically on the rule's resolve event or manually from the UI. Every job shows an alert badge, and the org view lists all firing incidents. Time fields accept durations like 30s, 5m, 4h, 7d, 1M.

Users and roles

Under Settings → Users (owners only): invite by email — the invitee gets a magic link, no passwords — change roles, or remove users at any time.

RoleCan do
ownerEverything: users, org settings, billing, plus all of the below
job_maintainerCreate/edit/delete jobs, labels, ingest keys, and alert rules
memberRead-only: view jobs, runs, logs, and alerting

All configuration changes (and any support access by our staff) are recorded in a read-only audit log for owners under Settings → Audit log, searchable by action and time.

Ingest keys and permissions

Under Settings → Ingestion (owners and job maintainers):

Labels are the permission system: a key can only ping a job it shares at least one label with (a key with no labels can ping nothing). Typical setup: one label per team or environment (payments, staging), attached to the relevant jobs, with each team/host issued a key carrying only its label — a leaked key exposes one slice of your jobs, and revocation is one click.

Organization settings

Billing and payments

Under Settings → Billing (owners only). Payments are processed by Paddle, our Merchant of Record — card details never touch our servers, and Paddle handles invoicing and sales tax/VAT.