Snag Watcher API https://watcher-api-staging.manwhas.shop

Getting started

Quickstart

1. Get a key

Keys start with sw_test_ or sw_live_. A test key can send webhooks to http://localhost, which is handy while you build. Ask us for one, then keep it in an environment variable:

Shell
export SNAG_KEY=sw_test_...

2. Preview

Preview fetches the page once and shows what a watcher would see. Nothing is saved.

Shell
curl https://watcher-api-staging.manwhas.shop/v1/watchers/preview \
  -H "Authorization: Bearer $SNAG_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target": { "query": "https://www.sweetwater.com/store/detail/SM58--shure-sm58-cardioid-dynamic-vocal-microphone", "match": "url" },
    "conditions": { "all": [{ "field": "price", "op": "<=", "value": 100 }] },
    "where": { "sites": ["sweetwater.com"] },
    "schedule": { "every": "1h", "until": "+30d" }
  }'

Response
{
  "kind": "price",
  "schedule": { "every": "1h" },
  "clamped": [],
  "warnings": ["sweetwater.com has no extractor of its own; it's read as Any product page with schema.org data. Check the preview before relying on it."],
  "would_match": true,
  "sites": [
    {
      "site": "sweetwater.com",
      "outcome": "ok",
      "candidates": 1,
      "matched": true,
      "fields": [{ "title": "SM58 Cardioid Dynamic Vocal Microphone", "price": { "cents": 8900, "currency": "USD" }, "availability": "in_stock" }]
    }
  ]
}

3. Create it

Same body, plus where to send the webhook, to POST /v1/watchers:

Shell
curl https://watcher-api-staging.manwhas.shop/v1/watchers \
  -H "Authorization: Bearer $SNAG_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sm58-under-100" \
  -d '{
    "target": { "query": "https://www.sweetwater.com/store/detail/SM58--shure-sm58-cardioid-dynamic-vocal-microphone", "match": "url" },
    "conditions": { "all": [{ "field": "price", "op": "<=", "value": 100 }] },
    "where": { "sites": ["sweetwater.com"] },
    "schedule": { "every": "1h", "until": "+30d" },
    "notify": { "channels": ["webhook"], "webhook": { "url": "https://you.example/snag", "events": ["matched", "changed", "blocked"] } }
  }'

The response includes webhook_secret. It's shown once, so store it now. You'll use it to verify signatures.

4. Receive the webhook

The first run happens within a minute. When the price is at or under $100, we POST:

JSON
{
  "id": "evt_4m2k9q8x7c1v0b3n5z6w",
  "type": "matched",
  "created_at": "2026-11-04T19:38:44.390Z",
  "watcher_id": "wch_dhjqcvaqnhrchsnv7gtc",
  "kind": "price",
  "data": {
    "group": "site:sweetwater.com",
    "results": [{ "site": "sweetwater.com", "title": "SM58 Cardioid Dynamic Vocal Microphone", "price": { "cents": 8900, "currency": "USD" }, "availability": "in_stock" }]
  }
}

Answer with any 2xx. With repeat left at on_change, you hear again only when the result changes.