Docs: Watch and refresh
API reference

Watch and refresh

POST /v1/watch: save a query, refresh it weekly and get back only the new and changed records.

A watch is a saved query whose reruns answer with what changed. The first run keys every record of the result on its own identity (a posting's URL, a profile's LinkedIn URL, an award's id, a USAJOBS control number) and stores a fingerprint per key. A refresh reruns the same query, bills like any run, and returns only the new and changed records, plus the keys that disappeared. Records are never copied: they stay on the run, and the changes are rebuilt from the last run's result when you ask.

Use it for the weekly loop behind monitoring: one watch per office, contractor, keyword or search, one refresh per week, and your pipeline reads the delta instead of the whole list.

Create a watch

POST /v1/watch

Same body as run plus a name. A capability with its input, or provider + endpoint with the provider's request for a raw endpoint.

curl -X POST https://api.routergrowth.com/v1/watch \
  -H "Authorization: Bearer $ROUTERGROWTH_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "Booz Allen Navy postings", "capability": "company.jobs",
       "input": {"company": "Booz Allen Hamilton", "query": "Navy", "posted_within": "month", "limit": 20},
       "routing": {"max_cost": "0.10"}}'

Answers 201 with the watch, the run receipt and the changes. On the first run every record is new.

{
  "watch": {"watch_id": "wch_...", "name": "Booz Allen Navy postings", "kind": "capability",
            "capability": "company.jobs", "key_field": "url", "records": 14, "runs": 1,
            "last_changes": {"status": "succeeded", "new": 14, "changed": 0, "removed": 0, "unchanged": 0}},
  "run": {"run_id": "run_...", "status": "succeeded", "billing": {"quoted": "0.03", "charged": "0.021"}},
  "changes": {"counts": {"records": 14, "new": 14, "changed": 0, "removed": 0, "unchanged": 0},
              "new": [{"title": "Capture Manager, Navy", "url": "https://...", "posted_at": "2026-09-15"}],
              "changed": [], "removed": []}
}

The request waits up to wait_seconds (default 30) for the run. A slow provider answers 202 with changes: null and a pending_run_id; fetch the watch with wait to collect the result.

Refresh

POST /v1/watch/{watch_id}/refresh?wait=60

Reruns the query. changes.new holds records whose key was not there last time, changes.changed the records whose content moved (ranking fields such as position are ignored), changes.removed the keys no longer returned. A refresh whose run fails changes nothing: the fingerprints stay, the next refresh diffs against them, and last_changes.error says what happened. A refresh while one is still executing answers 409.

Read and list

GET /v1/watch                 every watch with counts and the last refresh summary, no records
GET /v1/watch/{watch_id}      the watch, the last run receipt, the last changes with records; ?wait=60 holds while a refresh runs
DELETE /v1/watch/{watch_id}

How records are keyed

Result Key
company.jobs, web.search, news.search, seo.serp the record's url
people.search, linkedin.search linkedin_url
social.* the post or comment id
USAJOBS /search PositionURI; /historicjoa: usajobsControlNumber
USAspending award search generated_internal_id
any other list of records the first of url, link, id, email; else a hash of the record
a single-record answer (one enrichment, one page) nothing to diff; the watch reports zero records

key_field on the watch tells you which one was used. Two providers can name the same person differently; a watch diffs one query on one route, it does not merge identities across providers.

Cost

A watch costs nothing to keep. Each refresh is one run at the capability's quoted price, so the weekly cost of a watch is the price of its query, and the delta is free. Cheap signal queries (postings, news, USAJOBS, awards) are the ones to refresh often; people lists are page-priced, so refresh them on a longer cadence.

Over MCP the same loop is the watch tool (create, or refresh with watch_id) and watches (list, read, delete).

Reading this as an agent? This page as markdown: /docs/api/watch.md · every page: /docs/llms.txt