Monitoring API · v1.0.0

Managing and cancelling monitors

A monitor has two states and one lifecycle call. This guide covers listing, inspecting, retiring and what each answer means for your records and your bill.

What you’ll build

The housekeeping side of monitoring: a job that lists what your account is watching, matches each mon_ id to the person or place it is for, retires watches that are no longer needed before the next invoice, and keeps the alert history of retired monitors readable. There is no update call — a monitor’s criteria and channels are fixed at creation — so "change" means create a replacement and cancel the old one.

Before you start

  • Four calls: GET /v1/monitors (list, newest first, active only unless includeCanceled=true), GET /v1/monitors/{monitorId} (one monitor with recentAlerts), DELETE /v1/monitors/{monitorId} (cancel), GET /v1/monitors/{monitorId}/alerts (history, also for canceled monitors).
  • A monitor’s status is active or canceled; canceledAt is null until you cancel.
  • The list has no pagination and no filter other than includeCanceled; use label to carry your own reference.
What cancel means, precisely. Evaluation stops now. The monitor is not charged on any invoice prepared after the cancel — including the invoice for the month you cancel in — and there is no proration for the time it was active in that cycle. The monitor and every alert it filed stay readable.

Step by step

  1. List what you are paying for. GET /v1/monitors returns every active monitor. Each is one charge at the next invoice ($3 person, $10 location).
  2. Match each monitor to your record. Use label (set it to your own id at creation) and person / location to find the subject. Anything you cannot match is a candidate for cancelling.
  3. Cancel. DELETE /v1/monitors/{monitorId}. A 200 with status: "canceled" confirms it; cancelling again is harmless (another 200).
  4. Keep the history. The alerts of a canceled monitor remain at GET /v1/monitors/{monitorId}/alerts; GET /v1/monitors?includeCanceled=true lists the monitor itself with canceledAt set.

List active monitors

curl "https://sandbox.offendersearch.app/v1/monitors" \
  -H "X-API-Key: $OFFENDERSEARCH_TEST_KEY"
200 — newest first, active only
{
  "monitors": [
    {
      "id": "mon_4f2a9c7e1b8d6035",
      "product": "sex-offender",
      "type": "location",
      "minConfidence": null,
      "label": "Sampleville campus — 1 mi",
      "status": "active",
      "channels": { "emails": [], "webhookUrl": "https://your-app.example.com/hooks/offendersearch?token=…" },
      "createdAt": "2026-10-25T15:20:40.771302+00:00",
      "canceledAt": null,
      "location": { "address": "100 Sample St, Sampleville, OH 00000", "lat": 39.9612, "lng": -82.9988, "radiusMiles": 1 }
    },
    {
      "id": "mon_b8f40d7afb9dc0d8",
      "product": "sex-offender",
      "type": "person",
      "minConfidence": null,
      "label": "roster-00412",
      "status": "active",
      "channels": { "emails": ["alerts@your-app.example.com"] },
      "createdAt": "2026-10-25T14:02:11.418223+00:00",
      "canceledAt": null,
      "person": { "firstName": "Exact", "lastName": "Match", "dob": "1980-01-01" }
    }
  ],
  "sandbox": true
}

Cancel one

curl -X DELETE https://sandbox.offendersearch.app/v1/monitors/mon_b8f40d7afb9dc0d8 \
  -H "X-API-Key: $OFFENDERSEARCH_TEST_KEY"
200 — canceled
{
  "status": "canceled",
  "id": "mon_b8f40d7afb9dc0d8",
  "note": "Evaluation stops now. The monitor is not charged on any invoice prepared after this cancel; its alerts stay readable.",
  "sandbox": true
}
409 — a personal alert
{
  "detail": {
    "code": "personal_alert",
    "message": "This alert is billed by its own subscription. Cancel it from Alerts in your personal dashboard."
  }
}

See it afterwards

curl "https://sandbox.offendersearch.app/v1/monitors?includeCanceled=true" \
  -H "X-API-Key: $OFFENDERSEARCH_TEST_KEY"
# … "status": "canceled", "canceledAt": "2026-10-25T16:03:19.511270+00:00" …

curl "https://sandbox.offendersearch.app/v1/monitors/mon_b8f40d7afb9dc0d8/alerts" \
  -H "X-API-Key: $OFFENDERSEARCH_TEST_KEY"
# the alert history is unchanged

Reading the result

AnswerValuesWhat it means
GET /v1/monitors → monitors[].statusactiveBeing evaluated daily and will be charged at the next invoice.
?includeCanceled=true → status, canceledAtcanceled, date-timeNot evaluated, not charged on invoices prepared after canceledAt; readable.
DELETE → 200{status: "canceled", id, note}Done. note is a fixed sentence restating the semantics.
DELETE → 409detail.code: "personal_alert"The monitor belongs to a personal subscription on the same account; it is canceled from the personal dashboard, not the API.
DELETE / GET → 404{"detail": "Monitor not found."}Unknown id, or another account’s monitor — the API never distinguishes.
401 / 402string detailBad key, or no active subscription and no active trial.

Edge cases and pitfalls

  • There is no PATCH. To change a radius, a dob, a channel or a label, create a new monitor and cancel the old one. Its history stays on the old id; link the two in your own store.
  • Cancelling twice returns `200` again and overwrites canceledAt. Harmless, but do not use canceledAt as "first cancelled at" if your job may re-run.
  • The list is everything, unpaginated. With thousands of monitors, cache it and work from label; there is no server-side search.
  • Personal alerts appear in the list when a personal subscription shares the account; they are excluded from your invoice and answer 409 on DELETE.
  • Cancel before the invoice is prepared to avoid the charge for that cycle; a monitor active at invoice time is charged in full. The cancel itself is instant.
  • A canceled monitor never becomes active again. Re-watching the same person is a new monitor and a new id.

Production checklist

  • Set label to your own reference at creation; it is the only filter you will have.
  • Run a reconciliation that lists active monitors and cancels anything unmatched before each billing cycle.
  • Handle 409 personal_alert and 404 without retrying.
  • Keep canceled mon_ ids: their alert history is part of your audit trail.

Product overview