Watchlist
A watchlist is your list of operators you care about, plus the automation layer that fires events when any of them changes. Add an operator once, get alerted whenever its licence status flips, a regulatory action lands, or an expiry date approaches — without writing polling loops against every endpoint we offer.
1. Overview
Section titled “1. Overview”Plan limits (also in pricing):
| Tier | Watchlist cap | Webhooks | Polling |
|---|---|---|---|
| Starter | 25 operators | 1 endpoint | 10 / hour |
| Pro | 250 operators | 5 endpoints | 60 / hour |
| Business | unlimited | 20 endpoints | 600 / hour |
| Enterprise | unlimited | unlimited | unlimited |
Webhooks are the primary alert channel. Polling exists for agents that can’t accept inbound HTTP (corporate networks, air-gapped analytics, local dev) and as a backfill mechanism during webhook outages.
2. Managing the watchlist
Section titled “2. Managing the watchlist”Dashboard
Section titled “Dashboard”Sign in and open app.igregulator.io/watchlist. Type an operator name — we typeahead against every operator slug we know about. Click to add. Click remove to drop.
Same surface via bearer token:
# Current watchlist + count + plan capcurl -H "Authorization: Bearer igk_..." \ https://api.igregulator.io/v1/watchlist
# Add an operator by slug (lowercase, hyphens)curl -X POST -H "Authorization: Bearer igk_..." \ -H "Content-Type: application/json" \ -d '{"operator_slug":"888-uk-limited"}' \ https://api.igregulator.io/v1/watchlist/operators
# Remove (idempotent)curl -X DELETE -H "Authorization: Bearer igk_..." \ https://api.igregulator.io/v1/watchlist/operators/888-uk-limited
# Paginated listing with current licence status per operatorcurl -H "Authorization: Bearer igk_..." \ "https://api.igregulator.io/v1/watchlist/operators?limit=50&offset=0"Discover slugs with GET /v1/operators/search?q=<name>.
3. Receiving events
Section titled “3. Receiving events”Webhook push (primary)
Section titled “Webhook push (primary)”Create an endpoint with the watchlist_only: true flag (default).
Deliveries fire for operators in your watchlist only — no
firehose, no noise. Events covered:
license.status_changedlicense.expiring_30d/_60d/_90dlicense.expiredlicense.issued(only if you were watching the operator when the new licence was detected)regulatory_action.added
See /docs/webhooks for the signing + retry protocol. Quickstart in 2 minutes: /docs/webhooks/quickstart.
Polling (fallback)
Section titled “Polling (fallback)”GET /v1/watchlist/events returns the same envelope events,
pulled. Cursor-paginated so you don’t re-process events between
runs. Rate-limited per plan (see §1). Every response carries
X-Poll-RateLimit-Limit, -Remaining, -Reset, -Window, and a
X-Poll-Recommended-Interval hint in seconds.
# Bootstrap: 30-day window (matches event retention)curl -H "Authorization: Bearer igk_..." \ "https://api.igregulator.io/v1/watchlist/events?since=2026-04-01T00:00:00Z&limit=100"
# Steady state: use the next_cursor from the previous responsecurl -H "Authorization: Bearer igk_..." \ "https://api.igregulator.io/v1/watchlist/events?cursor=eyJ0cy...&limit=100"Response:
{ "events": [ { "event": "license.status_changed", "event_id": "evt_...", "api_version": "2026-04-20", "timestamp": "...", "livemode": true, "data": { ... } } ], "next_cursor": "eyJ0c...", "has_more": true}events payloads are identical to the webhook envelope
(minus the signature — polling authenticates via your API key,
not per-delivery HMAC). Dedupe on event_id whether you’re
receiving via webhook or poll; you’ll use the same key for both.
Polling best practices
Section titled “Polling best practices”- Persist the cursor. Save
next_cursorafter each successful batch to your own DB / disk. On restart, resume from it. - Dedupe on
event_id. Crash windows can cause you to re-process the last batch; same dedupe path you’d use for webhooks covers this. - Respect
X-Poll-Recommended-Interval. It’sceil(3600 / limit)— sleeping that long between polls guarantees you never hit the hour ceiling. Starter = 360 s, Pro = 60 s, Business = 6 s. - On 429, wait until
reset_at. Don’t exponential-backoff — the window resets deterministically on the hour boundary. See /docs/rate-limits. - Hybrid webhooks + polling is the resilient pattern. Webhooks
for low latency, polling for the few-hour windows where your
receiver was down and deliveries abandoned. Both ship the same
event_id, so dedupe makes double-processing a no-op. Example in /docs/webhooks § Pattern C.
since= is capped at 30 days
Section titled “since= is capped at 30 days”That matches our event retention. Older values fail with
400 since_exceeds_retention_window. Rare in practice — the
first call uses since, every subsequent call uses the cursor.
4. Plan limits in detail
Section titled “4. Plan limits in detail”If you exceed your watchlist cap mid-month, the next POST /v1/watchlist/operators returns 403 watchlist_quota_exceeded
with the current count + cap. Remove an operator or upgrade.
Polling ceiling hits return 429 watchlist_events_poll_limit with
a concrete reset_at timestamp — not exponential backoff,
deterministic hour-boundary reset. Webhooks do not count against
this limit.
5. What events don’t fire for watched operators
Section titled “5. What events don’t fire for watched operators”coverage.degraded/coverage.restored— these are jurisdiction-level, not operator-level. They’re emitted regardless of watchlist membership; anyone subscribed to the event type gets them.webhook.endpoint_degraded— self-notification about your own endpoints. Ignores watchlist.
6. Troubleshooting
Section titled “6. Troubleshooting”- No events arriving — your watchlist may be empty, or the
operators you track haven’t had any changes this month. Run
GET /v1/watchlist/events?since=2026-04-01T00:00:00Zto confirm what would have fired over a month. - Too many events — too-broad subscription. Each of the three expiry windows fires separately; narrow to the one(s) you act on.
- Events for operators I don’t watch — your webhook might
have
watchlist_only: false. CheckPATCH /v1/webhooks/:idwith{ "watchlist_only": true }.
Related: /docs/webhooks, /docs/rate-limits.