Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.simplefunctions.dev/llms.txt

Use this file to discover all available pages before exploring further.

A research monitor is a long-running, natural-language research loop. You describe what you want watched (e.g. “semiconductor sanctions affecting Taiwan markets”) and SimpleFunctions runs the research on a cadence, posts results to your delivery channels, and stores history. This is different from a watch + alert rule, which fires on a structured condition (price threshold, econ release, …). Research monitors are open-ended LLM runs over a topic.

CLI

sf monitor list                                  # list your monitors
sf monitor create "<intent>"                     # create + run once immediately
sf monitor show <id>                             # detail
sf monitor run <id>                              # run now
sf monitor run <id> --dry-run                    # plan only, no delivery
sf monitor delete <id>                           # delete
sf monitor create returns the new monitor and the first run result inline.

API

All routes require Authorization: Bearer sf_live_... or browser session.
MethodPathPurpose
GET/api/research-monitorsList your monitors.
POST/api/research-monitorsCreate a monitor (and optionally run it immediately).
GET/api/research-monitors/{id}Detail.
PATCH/api/research-monitors/{id}Update fields.
DELETE/api/research-monitors/{id}Delete.
POST/api/research-monitors/{id}/runRun now. Optional ?dryRun=true or { dryRun: true }.

POST /api/research-monitors

Body
FieldTypeRequiredDefaultNotes
intent (or query, text)stringyesNatural-language description of what to watch.
namestringoptionalfirst 96 chars of intentDisplay label.
topics (or topic)string | string[]optionalderived from intentTopic tags for filtering and dedupe.
cadenceMinutes (or cadence)numberoptional360Run cadence in minutes.
webhookEndpointId (or webhook)stringoptionalnoneExisting webhook endpoint id.
telegramChatIdstringoptionalnoneTelegram chat to deliver into.
deliveryChannelsarrayoptionalinferredOverride the default channel list.
statusstringoptionalactiveactive, paused, or archived.
runImmediatelybooleanoptionaltrueSkip the first immediate run by sending false.
metadataobjectoptionalFree-form metadata.
Response 201
{
  "ok": true,
  "monitor": {
    "id": "rm_01J0...",
    "name": "Taiwan semiconductor sanctions",
    "intent": "semiconductor sanctions affecting Taiwan markets",
    "topics": ["geo", "semiconductor"],
    "cadenceMinutes": 360,
    "status": "active",
    "webhookEndpointId": null,
    "telegramChatId": null,
    "deliveryChannels": ["dashboard"],
    "nextRunAt": "2026-05-05T20:11:00.000Z",
    "createdAt": "2026-05-05T20:11:00.000Z"
  },
  "meta": { "fetchedAt": "2026-05-05T20:11:00.000Z" }
}

PATCH /api/research-monitors/

All fields are optional. Pass only the fields you want to change.
FieldNotes
nameUp to 160 chars.
intentEmpty string returns INVALID_INTENT. Causes topics to be re-derived.
topics / topicOverride topic list.
cadence / cadenceMinutesNew cadence.
statusactive, paused, archived. Other values return INVALID_STATUS.
webhookEndpointId / webhookPass null to detach.
telegramChatIdPass "" or null to detach.
deliveryChannelsReplace the channel list.
metadataReplace metadata.

POST /api/research-monitors//run

curl -X POST -H "Authorization: Bearer $SF_API_KEY" \
  "https://simplefunctions.dev/api/research-monitors/rm_01J0.../run"

# dry run — compute the plan without delivering
curl -X POST -H "Authorization: Bearer $SF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dryRun": true}' \
  "https://simplefunctions.dev/api/research-monitors/rm_01J0.../run"
Returns { ok: <bool>, result: <runResult>, meta: { fetchedAt } }. Failures bubble up as 500 with ok: false so a webhook receiver can retry on transient errors.

Errors

StatusCodeCause
400INTENT_REQUIREDMissing intent.
400INVALID_INTENTEmpty intent on update.
400INVALID_STATUSStatus not in active, paused, archived.
401unauthorizedNo / invalid auth.
404NOT_FOUNDMonitor doesn’t exist or isn’t yours.

Patterns

Watch a topic, post to Telegram

sf monitor create "Taiwan semiconductor sanctions" --telegram-chat -100123 --cadence 240

Programmatic create with webhook

curl -X POST -H "Authorization: Bearer $SF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "intent": "Fed-cut speculation in OIS and Kalshi",
    "cadenceMinutes": 360,
    "webhookEndpointId": "we_01J0...",
    "deliveryChannels": ["webhook", "dashboard"]
  }' \
  "https://simplefunctions.dev/api/research-monitors"

Run on demand from a CI job

curl -X POST -H "Authorization: Bearer $SF_API_KEY" \
  "https://simplefunctions.dev/api/research-monitors/rm_01J0.../run"

See also

Watchlist + alerts

Structured price / econ / gov alerts.

Webhooks

Signed delivery and replay.

Telegram bot

Bridge the CLI to a chat surface.

Direct API access

Auth, base URLs, language examples.