Skip to content

New Official SDKs for TypeScript, Python and Go

SerpKite
Get API key
Docs menu / Monitors

Monitors

Saved /v1/search or /v1/news requests that run hourly, daily or weekly and report only results they haven't seen before, or /v1/webpage URLs reported when their content changes: in the run history, and to a signed monitor.results webhook when one is set.

POST https://api.serpkite.com/v1/monitors Credits: 1 per run, priced like the search or page fetch it makes (1 per 10 results, num=100 is 7); empty and failed runs are free
View as Markdown

A monitor saves a /v1/search or /v1/news request and runs it on a schedule (interval: hourly, daily or weekly, or interval_seconds from 1 hour to 30 days). Each run reports only the results among the top num it hasn't seen before. With endpoint: "webpage" and a url, it checks that page instead and reports it (change: new|changed, with its Markdown) whenever the content changes.

New results are always kept in the monitor's run history (GET /v1/monitors/{id}/runs, results for 24 hours) and, when the monitor has a webhook_url, posted as a signed monitor.results event. The first run is due right away and reports everything it finds (first_run: true).

Each run is billed like the request it makes (1 credit per 10 results, num: 100 is 7; empty and failed runs are free) on the monitor's API key: the key that created it, or last changed or ran it, under that key's limits and the account's spend cap. A monitor pauses itself after 10 failed runs in a row or when its key is revoked; PATCH it with active: true to resume.

A monitor keeps only the fields listed below; any other search field (tbs, start_date, include_content…) is a 400.

Request body

ParameterTypeDefaultDescription
qstringThe query, for search and news monitors.
urlstringThe page to watch, for endpoint: "webpage".
endpointstringsearchWhat to run. One of: search, news, webpage.
intervalstringdailyHow often to run. One of: hourly, daily, weekly.
interval_secondsintegerExact interval, 3,600–2,592,000 seconds. Overrides interval.
webhook_urlstringReceives signed monitor.results events. Without one, read new results from the run history.
namestringYour label, up to 200 characters.
activebooleantruefalse creates the monitor paused.
metadataobjectYour own JSON object (up to 2 KB), echoed on the monitor and in its webhooks.
countrystringusCountry to search from, as a two-letter ISO code (us, gb, de, in…). Defaults to the country a location ends in.
languagestringenInterface language, as a language code with an optional region (en, de, pt-BR, zh-TW…).
locationstringCanonical location for local results, e.g. "Austin, Texas, United States". Ending in a country name also sets country.
timestringRestrict to recent results. Shorthand for tbs=qdr:*. One of: hour, day, week, month, year.
numintegerWatch only the top num results (1–100).
devicestringdesktopWhich SERP layout to fetch. One of: desktop, mobile.
safestringoffSafeSearch filtering. One of: off, active.
include_domainsstring[]Only results from these sources, up to 20: a domain (example.com, subdomains match), a path prefix (github.com/org) or a TLD (.gov). Compiled to site: operators and enforced on the results. Search, news, images, videos.
exclude_domainsstring[]Drop results from these sources, up to 20, same formats as include_domains. Search, news, images, videos.
enginestring or arraygoogleWhich search providers may answer. google is Google only (SerpKite still fails over across its own proxy pools); auto falls back to other providers when Google is blocked or times out; consensus (search only) asks several independent indexes in parallel, merges the results by URL, ranks them by agreement and lists each result's sources, at the sum of one page per provider that returned results; a provider name or a list (e.g. google,brave) restricts the request to those. meta.engine names the provider that answered. One of: google, auto, consensus, brave, bing, yahoo, duckduckgo, mojeek, wikipedia.

Example request

Authenticate with Authorization: Bearer $SERPKITE_API_KEY (GET requests may pass ?api_key= instead). The official SDKs read SERPKITE_API_KEY for you. See Authentication.

curl https://api.serpkite.com/v1/monitors \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"ai agents funding","endpoint":"news","interval":"daily","webhook_url":"https://example.com/hooks/serpkite"}'

Response fields

FieldTypeDescription
idstringThe monitor's ID, for GET, PATCH, DELETE /v1/monitors/{id}, POST /v1/monitors/{id}/run (run at the next poll, within about 30 seconds) and GET /v1/monitors/{id}/runs.
requestobjectThe saved search (q and options) or watched url.
interval_seconds / next_run_at / last_run_atmixedThe schedule.
last_status / last_error / last_new_resultsmixedThe last run: ok, error, webhook_failed or paused, and how many new results it found.
runs / consecutive_failures / credits_usednumberTotals over all runs; the failure streak pauses the monitor at 10.

Every billed response also carries credit and latency headers (X-Credits-Used, X-Credits-Remaining, X-Request-Id…).

Example response

200 OK · illustrative
{
  "id": "01926a3e-9d1f-7a2b-8c3d-4e5f6a7b8c9d",
  "name": "",
  "endpoint": "news",
  "request": {
    "q": "ai agents funding"
  },
  "metadata": null,
  "interval_seconds": 86400,
  "webhook_url": "https://example.com/hooks/serpkite",
  "active": true,
  "next_run_at": "2026-10-04T12:00:00Z",
  "last_run_at": "2026-10-03T12:00:05Z",
  "last_status": "ok",
  "last_error": null,
  "last_new_results": 10,
  "runs": 1,
  "consecutive_failures": 0,
  "credits_used": 1,
  "created_at": "2026-10-03T12:00:00Z"
}

Errors

Errors use one shape: {"error":{"code","message","request_id"}}. Errors are never billed. Full list in Errors.

StatusCodeMeaning
400invalid_requestA parameter is missing or invalid.
401unauthorizedThe API key is missing, invalid or revoked.
402insufficient_creditsYour balance is too low. Buy a pack or wait for the monthly free grant.
429rate_limitedToo many requests per second for your plan. Retry after the Retry-After header.
503upstream_errorGoogle could not be fetched or parsed. Not billed; retry after Retry-After.

Notes

  • At most 100 monitors per account (403 forbidden beyond that).
  • Run now (POST /v1/monitors/{id}/run) requires an active monitor. A paused monitor returns 409 invalid_request; resume it with PATCH {"active": true}, which also schedules an immediate run.
  • Changing the saved search with PATCH starts a new baseline: the next run reports every result as new.
  • To spot new results a monitor keeps only hashes of the links it has reported; the new results themselves stay in the run history for 24 hours. See Privacy and data retention.