//
Monitory

API Documentation

The complete Monitory workflow — query, create a monitor, get alerted — available through the web app or programmatically via the API. Pro required for API access

The Monitory workflow

Every monitor in Monitory follows the same four steps, whether you set it up in the dashboard or build it entirely through the API:

  1. 1Query — run an ad-hoc query (POST /api/query) to see the structured data you'd be monitoring, or skip straight to step 2 if you already know what you want.
  2. 2Create a monitorPOST /api/monitors with a schema (generic / seo_rank / ai_visibility), a check frequency, an alert condition, and where to deliver alerts.
  3. 3Monitory checks it automatically — a background worker re-runs the monitor on schedule (every 5 min for generic, 30 min for seo_rank, 60 min for ai_visibility) and evaluates your alert condition.
  4. 4You get alerted — Slack, email, or webhook, only when the condition actually fires. GET /api/monitors/:id anytime to pull the full run/alert history.

1. Get an API key

API access is a Pro feature. Generate a key below (you must be signed in) — the plaintext key is shown exactly once, so copy it immediately.

2. Authenticate

Send your key as a Bearer token on every request. Keys are Pro-only and rate-limited to 60 requests per minute per key.

shell
curl https://monitory.app/api/monitors \
  -H "Authorization: Bearer mnty_xxxxxxxxxxxxxxxxxxxxxxxx"

3. Endpoints

POST/api/query

Run an ad-hoc query and get structured JSON back. Public — no API key required. Good for previewing what a monitor would return before creating it.

shell
curl -X POST https://monitory.app/api/query \
  -H "Content-Type: application/json" \
  -d '{"query": "Bitcoin price right now", "schema": "crypto"}'
GET/api/monitors

List every monitor on your account.

shell
curl https://monitory.app/api/monitors \
  -H "Authorization: Bearer mnty_..."
POST/api/monitors

Create a monitor. schema determines which fields condition needs:

Generic monitor (e.g. price tracking)

shell
curl -X POST https://monitory.app/api/monitors \
  -H "Authorization: Bearer mnty_..." \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Bitcoin price right now",
    "schema": "crypto",
    "frequency": "hourly",
    "delivery": "webhook",
    "webhookUrl": "https://your-endpoint.com/hook",
    "condition": {
      "type": "threshold",
      "field": "prices[].amount",
      "operator": "<",
      "threshold": 50000
    }
  }'

SEO rank monitor

shell
curl -X POST https://monitory.app/api/monitors \
  -H "Authorization: Bearer mnty_..." \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Rank tracker: \"best crm software\"",
    "schema": "seo_rank",
    "frequency": "daily",
    "delivery": "slack",
    "webhookUrl": "https://hooks.slack.com/services/...",
    "condition": {
      "type": "rank_drop",
      "keyword": "best crm software",
      "targetUrl": "https://example.com/crm",
      "locationCode": "2840",
      "dropThreshold": 3
    }
  }'

condition.type can also be position_moved, position_up, position_down, or serp_changed — only rank_drop triggers the AI why-analysis.

AI visibility monitor

shell
curl -X POST https://monitory.app/api/monitors \
  -H "Authorization: Bearer mnty_..." \
  -H "Content-Type: application/json" \
  -d '{
    "query": "AI Visibility: \"Acme\" for \"best CRM for small teams\"",
    "schema": "ai_visibility",
    "frequency": "weekly",
    "delivery": "slack",
    "webhookUrl": "https://hooks.slack.com/services/...",
    "condition": {
      "type": "mention_changed",
      "prompt": "What is the best CRM for a small team?",
      "entity": "Acme",
      "engines": ["chatgpt", "gemini", "claude", "perplexity"]
    }
  }'
GET/api/monitors/:id

Get a monitor plus its run history, fired alerts, and — for seo_rank monitors — its full position-over-time snapshot history.

shell
curl https://monitory.app/api/monitors/<id> \
  -H "Authorization: Bearer mnty_..."
PATCH/api/monitors/:id

Update a monitor, or pause/resume it.

shell
curl -X PATCH https://monitory.app/api/monitors/<id> \
  -H "Authorization: Bearer mnty_..." \
  -H "Content-Type: application/json" \
  -d '{"action": "toggle_pause"}'
DELETE/api/monitors/:id

Delete a monitor and its history permanently.

shell
curl -X DELETE https://monitory.app/api/monitors/<id> \
  -H "Authorization: Bearer mnty_..."

4. Slack & webhook alerts

Every monitor schema (generic, seo_rank, ai_visibility) can deliver to Slack or to your own webhook endpoint — set delivery and webhookUrlthe same way in the dashboard's "Deliver to" step or via the API.

Set up Slack (Incoming Webhook)

  1. 1Go to api.slack.com/apps Create New AppFrom scratch— name it (e.g. "Monitory") and pick the workspace to post into.
  2. 2In the app settings, open Incoming Webhooks in the left sidebar and switch it On.
  3. 3Click Add New Webhook to Workspace, choose the channel Monitory should post alerts to, and authorize it.
  4. 4Copy the generated URL — it looks like https://hooks.slack.com/services/… — and paste it as the webhook URL when you pick Slackdelivery for a monitor. That's the entire setup; no bot install or extra scopes needed.

Set up a generic webhook

Pick Webhook delivery instead of Slack and point it at any HTTPS endpoint you control (a Zapier/Make catch hook, your own backend, etc). Monitory POSTs plain JSON — no Slack-specific formatting — every time the monitor's alert condition fires:

POST https://your-endpoint.com/hook
{
  "source": "monitory-alert",
  "alertId": "9f2c...",
  "monitorName": "Rank tracker: \"best crm software\" — https://example.com/crm",
  "alertType": "rank_drop",
  "value": {
    "keyword": "best crm software",
    "targetUrl": "https://example.com/crm",
    "previousPosition": 4,
    "currentPosition": 11,
    "analysis": { "issueType": "competitor_surge", "confidenceScore": 0.82, "recommendedAction": "..." }
  },
  "timestamp": "2026-08-16T09:00:00.000Z"
}

The exact shape of value depends on the schema and alert condition — generic monitors send the diffed field(s), ai_visibility sends which engines mentioned the entity. Your endpoint should return a 2xx within 10 seconds; Monitory does not currently retry failed deliveries.

5. Errors & rate limits

StatusMeaning
401Missing or invalid API key
402Free-tier monitor limit reached — upgrade to Pro
403API access requires a Pro subscription
404Monitor not found (or not yours)
429Rate limit exceeded — 60 requests/minute per key