---
title: "Get a monitor"
method: GET
path: "/monitors/{id}"
tags: ["monitors"]
---

# Get a monitor

`GET /monitors/{id}`

## Request

- Base URL: `https://www.socialcrawl.dev/v1`
- URL: `https://www.socialcrawl.dev/v1/monitors/{id}`
- Auth: API key in header `x-api-key`

Returns one monitor. A monitor owned by another account returns 404, never 403, so the response cannot be used to probe for existence. The signing secret is never returned here.

## Path parameters

- `id` string, required

## Response `200`

The monitor

- object
  - `alert_rules` MonitorAlertRule[]: The alert rules evaluated after each run.
    - `metric` string, required: Dot path to a numeric key in the recipe's own result, for example `coverage` or `summary.total`. On a numbers-only monitor (created with `track`) the metric must be one of `track.metrics`, and an `items[].<path>` metric is evaluated once per row: a fired alert then carries `row_id`. The special metric `rows_new` (numbers-only monitors only; it needs an `items[].` metric in `track.metrics` and is not itself tracked) counts the list rows this run has that the previous run did not: `{"metric":"rows_new","op":"gt","value":0}` alerts on any new post or video. It accepts only `gt` and `gte`, and is skipped on the first run. "New" means absent from the previous successful run's stored rows (capped at `max_rows`, default 100), so a row that drops off and returns later counts as new again. An empty-page run is refunded and is not a baseline, so on a sparse feed the first run that holds rows has no baseline and stays silent: the first new post after a quiet period may not alert. Use a daily cadence or leave `max_rows` headroom.
    - `op` 'gt' | 'lt' | 'gte' | 'lte' | 'abs_change_gt' | 'pct_change_gt' | 'pct_change_lt', required
    - `value` number, required
    - `window` '1d' | '1w': Accepted and stored, but ignored: a change op always compares against the immediately preceding comparable run, whatever the value.
  - `cadence` unknown
  - `created_at` string, date-time
  - `credits_spent` integer: Credits this monitor has spent across every run so far.
  - `estimated_cost_per_run` integer: The recipe's own credit cost plus 1 credit for orchestration. A run that fails outright is refunded in full.
  - `estimated_monthly_cost` integer: `estimated_cost_per_run` multiplied by the runs the cadence produces in a month.
  - `id` string
  - `name` string
  - `next_run_at` string, date-time
  - `output_schema` object, nullable
  - `params` object: The recipe parameters frozen at create time. They are replayed verbatim on every run.
  - `recipe` string: The endpoint path this monitor re-runs, without the `/v1/`.
  - `runs_total` integer
  - `status` 'active' | 'paused'
  - `suppress_webhook_unless_alert` boolean
  - `track` object, nullable: Set on a numbers-only monitor (created with `track`): the tracked paths, the row id path, and the row cap. Null on a monitor that stores full results.
    - `max_rows` integer
    - `metrics` string[]
    - `row_key` string, nullable
  - `updated_at` string, date-time
  - `webhook_format` 'full' | 'rows': The webhook body: `full` (the default) or `rows` (flat rows, numbers-only monitors).
  - `webhook` object, nullable: The webhook. Null in list responses and on a download-only monitor (created with `track` and no `webhook_url`).
    - `failure_count` integer: Consecutive delivery failures. The webhook auto-pauses at 10.
    - `last_delivery_at` string, date-time, nullable
    - `signing_secret_hint` string: A non-reversible hint at the signing secret. The secret itself is returned exactly once, by `POST /v1/monitors`.
    - `status` 'active' | 'paused'
    - `url` string

## Other responses

- `400`: Invalid request - missing or malformed parameters
- `401`: Unauthorized - missing or invalid API key
- `404`: Not found - the endpoint does not exist, or the requested resource was not found upstream
- `429`: Rate or concurrency limit exceeded. `RATE_LIMITED`: more than 600 requests in a 1-minute sliding window on this API key (headers `X-RateLimit-Limit`/`Remaining`/`Reset`; `Retry-After` is seconds until the window resets). `CONCURRENCY_LIMIT`: more than 50 simultaneous in-flight requests (headers `X-Concurrency-Limit`/`Remaining`; short static `Retry-After`). Both are unbilled. Honor `Retry-After`, then back off with jitter. See /docs/rate-limits.
- `500`: Internal server error - an immediate refund is attempted; credits_used reports the committed net charge and exact compensation is queued if that refund cannot commit

---

[API](https://skmtc.dev/socialcrawl/apis/socialcrawl-api.md) · [All operations](https://skmtc.dev/socialcrawl/apis/socialcrawl-api/llms.txt) · [OpenAPI document](https://skmtc.dev/socialcrawl/apis/socialcrawl-api/revisions/a0ad2511004a?raw)
