Standing watches on any topic. Describe what to watch in natural language; STELQ compiles it into diverse search queries, authoritative domains, a per-topic significance rubric and direct sources (feeds, JSON endpoints, high-signal pages — each confirmed by a live fetch). The first check establishes a baseline; every later check on the cadence you chose is recorded and badged minor / notable / major against it, with a summary and the new items. Price follows size: $0.05 to create per block of 12 queries, $0.01 per check per block — preview both with a free plan call before you pay.
Copy one work order and paste it into Claude Code, Cursor, or any coding agent — it finds the right place in your codebase and wires STELQ Monitors in, so your users get grounded, cited answers at runtime. Every payload references $STELQ_KEY from your environment, never a live secret.
One request to POST /v1/monitors/create. Set $STELQ_KEY in your environment and run this as-is — it is generated from the live contract, not transcribed.
# 0) (Optional, free) See the plan and the price before paying.
curl -X POST https://api.stelq.com/v1/monitors/plan \
-H "Authorization: Bearer $STELQ_KEY" -H "Content-Type: application/json" \
-d '{"query":"Anything about Regulation E: rule changes, CFPB guidance, enforcement","interval":"6h"}'
# 1) Create the monitor — charged $0.05 per block of 12 queries on 201.
curl -X POST https://api.stelq.com/v1/monitors/create \
-H "Authorization: Bearer $STELQ_KEY" -H "Content-Type: application/json" \
-d '{"query":"Anything about Regulation E: rule changes, CFPB guidance, enforcement","interval":"6h","notify_threshold":"notable"}'
# 2) Read what changed (the first event, within ~5 min, is the baseline).
curl https://api.stelq.com/v1/monitors/$MONITOR_ID/events?limit=10 \
-H "Authorization: Bearer $STELQ_KEY"Every request carries a bearer token in the Authorization header. Copied agent payloads reference the $STELQ_KEY environment variable, so set it in your agent's environment rather than pasting a live secret into a prompt or a chat log.
Authorization: Bearer $STELQ_KEY
| Field | Type | Notes |
|---|---|---|
| queryrequired | string | What to watch, in natural language — a topic, vendor, regulation, competitor set. 3–2000 chars. prompt is accepted as an alias. |
| interval | enum | Check cadence: 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 24h, 7d (default 24h). The cadence ladder is the price ladder — see pricing.est_daily_usd on the response. |
| notify_threshold | enum | all, notable, or major (default all). Gates the WEBHOOK only — every check is recorded and readable regardless. |
| webhook | url (https) | Optional. Signed monitor.baseline / monitor.change events are POSTed here — same envelope, signature and retries as Research webhooks. Must be https. |
| watch_plan | object | Optional. The watch_plan returned by POST /v1/monitors/plan, as-is or edited (trim queries to lower the price, drop a source, add a domain). Skips the compile; you pay exactly the price the plan showed. |
| max_queries | integer | Optional price ceiling, 1–120: keep at most this many compiled queries. 12 queries = one price block. |
| name | string | Optional label (≤120 chars). Defaults to the compiled name. |
{
"query": "Anything about Regulation E (electronic fund transfers): rule changes, CFPB guidance, enforcement actions",
"interval": "6h",
"notify_threshold": "notable",
"webhook": "https://example.com/hooks/stelq"
}| Route | Price | Purpose |
|---|---|---|
| POST /v1/monitors/plan | free | Compile the watch plan + price WITHOUT creating anything. Body: query, interval?, max_queries?. Returns watch_plan + pricing. Rate-limited with create. |
| POST /v1/monitors/create | $0.05 / block | Create the monitor (this page's request). Charged by size on a 201 only. |
| GET /v1/monitors | free | List your monitors with status, pricing and the latest event badge. |
| GET /v1/monitors/{id} | free | One monitor: watch plan, baseline, pricing and its recent events (?limit=, ≤100). |
| GET /v1/monitors/{id}/events | free | The event feed only — one entry per check: significance, headline, summary_md, new_items[]. |
| GET /v1/monitors/{id}/events/{event_id} | free | One check in full, plus webhook delivery status (state, attempts, last status) — the webhook's result_url. |
| PATCH /v1/monitors/{id} | free | Edit name, interval, notify_threshold, webhook (null removes) or queries (re-sizes the price). |
| POST /v1/monitors/{id}/pause | free | Stop checking (and billing) until resumed. |
| POST /v1/monitors/{id}/resume | free | Resume; the next check runs on the next sweep. |
| DELETE /v1/monitors/{id} | free | Delete the monitor and its record. |
How a monitor runs: create (or plan → create) compiles the watch plan and returns the monitor with pricing and next_check_at. Within 5 minutes the first check runs and writes the BASELINE (the state of affairs; readable as baseline_md on the detail call). Every later check on your cadence retrieves the plan's queries and direct sources, diffs against everything the monitor has already seen, gates off-topic pages, and — when something is new — writes one event with significance (none / minor / notable / major, scored against the baseline using the compiled rubric), a one-line headline, a summary_md and the new_items. Quiet checks are recorded too (significance: "none"). Each completed check bills pricing.per_check_usd; failed checks are never billed. If the balance can't cover a check it is skipped and the schedule pushed; three consecutive skips auto-pause the monitor (paused_reason: "insufficient_balance") — top up and resume. Read events back with the events routes, or take a webhook for the ones that clear your notify_threshold.
Pass a webhook (https URL) on create — or set one later with PATCH — and STELQ POSTs a signed event for the first check (monitor.baseline, always, so you can verify the integration) and for every later check whose significance clears your notify_threshold (monitor.change). Quiet checks never notify. The event is a claim-check with a routing hint: data.significance and data.headline let you route without a fetch; data.result_url returns the full check (summary, items) over the authenticated API. Same envelope, headers, secret and retries as Research webhooks — one receiver handles both.
{
"id": "evt_01JX9A4M2KQ7",
"type": "monitor.change",
"api_version": "2026-06-01",
"occurred_at": "2026-08-28T14:07:12Z",
"attempt": 1,
"data": {
"monitor_id": "a01aede0-ffb0-41a8-ae64-b92190596f59",
"monitor_name": "Regulation E watch",
"event_id": "5c1b7e2a-0d4f-4c8e-9a3b-2f6d8e1c4b7a",
"significance": "notable",
"headline": "CFPB issues proposed rule expanding Reg E error-resolution to P2P fraud",
"new_count": 3,
"result_url": "https://api.stelq.com/v1/monitors/a01aede0-ffb0-41a8-ae64-b92190596f59/events/5c1b7e2a-0d4f-4c8e-9a3b-2f6d8e1c4b7a"
}
}Signature headers: webhook-id · webhook-timestamp · webhook-signature
Verify before you trust the body: recompute HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{rawBody} with your account signing secret (whsec_…, revealed any time under API Keys in the console — the SAME secret that signs Research webhooks), then constant-time compare it against the webhook-signature header (format v1,<base64>). Reject timestamps older than ~5 minutes, and always verify against the raw request bytes.
data.event_id (+ type). One check can never produce two different events.GET …/events/{event_id} shows the delivery state for that check.monitor.baseline fires once (the first check). monitor.change fires only for checks at or above notify_threshold; a check with significance: "none" never notifies.A successful call returns JSON with the result inline.
{
"monitor": {
"id": "a01aede0-ffb0-41a8-ae64-b92190596f59",
"name": "Regulation E watch",
"status": "active",
"interval_minutes": 360,
"notify_threshold": "notable",
"webhook_url": "https://example.com/hooks/stelq",
"pricing": {
"size_blocks": 1,
"queries": 8,
"create_usd": 0.05,
"per_check_usd": 0.01,
"checks_per_day": 4,
"est_daily_usd": 0.04
},
"next_check_at": "2026-08-28T14:05:00Z",
"watch_plan": {
"queries": [
"Regulation E amendments 2026",
"CFPB Regulation E guidance",
"…"
],
"preferred_domains": [
"consumerfinance.gov",
"federalregister.gov"
],
"freshness_days": 7,
"significance_rubric": "major: a final rule or enforcement action; notable: proposed rule, official guidance; minor: commentary…",
"sources": [
{
"type": "feed",
"url": "https://www.consumerfinance.gov/about-us/newsroom/feed/",
"healthy": true
}
]
}
},
"webhook": {
"url": "https://example.com/hooks/stelq",
"signed_with": "account_signing_secret",
"events": [
"monitor.baseline",
"monitor.change"
]
},
"first_check": "within 5 minutes; the first check establishes the baseline your updates are measured against"
}| Status | Meaning |
|---|---|
| 400 | Invalid request — a field is missing or malformed (the body says which). |
| 401 | Missing or invalid API key. |
| 402 | Insufficient balance — top up credits to continue. |
| 429 | Rate limited — back off and retry after the Retry-After header. |
| 502 | Upstream temporarily unavailable — safe to retry; not charged. |
| 404 | No monitor (or event) with that id on this account. |
plan and create each compile a watch plan (one model call + live source verification), so they share a limit of 10 per minute per account; a 429 carries a Retry-After header. Reads, edits, pause/resume and delete are unmetered. Checks themselves run on our schedule and never count against your limit.