Webhooks

WEBHOOKjobCompleted
Job finished or failed

Sent to the job's callback_url (or your account webhook) when a job ends. Signed: Scrapely-Signature: t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<raw body>"> with your webhook signing secret. Respond 2xx within 10 seconds. Failed deliveries retry after 10 s, 1 m, 5 m, 30 m and 2 h. Scrapely-Delivery is stable across retries.

Parameters
Scrapely-Signaturestringheaderrequired
Scrapely-Eventstringheaderrequired
job.finished | job.failed
Scrapely-Deliverystringheaderrequired
Scrapely-Attemptintegerheaderrequired
Payload application/json

The body of every webhook. Verify Scrapely-Signature before trusting it.

idstring
Stable across retries: dedupe on it.
typestring
job.finished | job.failed
created_atstring
dataobject
Show child parameters
idstring
object
statusstring
queued | running | finished | failed | cancelled
urlstring
batch_idstring
optionsobject
Options shared by sync scrapes, jobs and batches.
Show child parameters
renderboolean
Load the page in a headless browser and execute its JavaScript before returning the DOM. Cost: 10 credits.
= false
premiumboolean
Route through the residential proxy pool. Use for sites that block datacenter IPs. Cost: 10 credits (25 with render).
= false
ultra_premiumboolean
Our hardest-target pipeline: premium residential IPs, browser fingerprinting and CAPTCHA handling. Includes rendering. Cannot be combined with premium. Cost: 30 credits.
= false
country_codestring
Geotarget the request from this country (lowercase ISO 3166-1 alpha-2, e.g. us, de, jp).
us | ca | mx | br | ar | cl | co | pe | gb | ie | fr | de | nl | be | lu | ch | at | es | pt | it | gr | se | no | dk | fi | is | pl | cz | sk | hu | ro | bg | hr | si | ee | lv | lt | ua | tr | il | ae | sa | eg | za | ng | ke | ma | in | pk | bd
device_typestring
Send a desktop or mobile user agent and viewport.
desktop | mobile = desktop
session_numberinteger
Reuse the same proxy IP across requests that share this number (sticky session, ~15 minutes idle timeout).
keep_headersboolean
Forward the headers you send us (Cookie, Accept-Language, User-Agent, …) to the target instead of ours. Your API key, Host and proxy headers are never forwarded. Sync endpoint only.
= false
output_formatstring
Return the page as raw HTML, cleaned Markdown, plain text, or JSON (title, meta, links, text).
html | json | markdown | text = html
autoparseboolean
For supported domains, return structured JSON parsed from the page instead of HTML.
= false
wait_for_selectorstring
With render=true: wait until this CSS selector appears before capturing the page.
creditsinteger
Reserved while queued/running; charged when finished; 0 when failed or cancelled.
status_codeinteger
duration_msinteger
errorstring
callback_urlstring
created_atstring
finished_atstring
status_urlstring
Poll this.
responseobject
Present once the job is finished (or failed with a target answer). Kept for 72 hours.
Show child parameters
status_codeinteger
content_typestring
final_urlstring
headersobject
contentstring | object
expires_atstring
{
  "id": "evt_1a2b3c4d5e6f7a8b9c0d",
  "type": "job.finished",
  "created_at": "2024-01-01T00:00:00Z",
  "data": {
    "id": "job_5f0c8a1b2d3e4f56",
    "object": {},
    "status": "queued",
    "url": "string",
    "batch_id": "string",
    "options": {
      "render": false,
      "premium": false,
      "ultra_premium": false,
      "country_code": "us",
      "device_type": "desktop",
      "session_number": 0,
      "keep_headers": false,
      "output_format": "html",
      "autoparse": false,
      "wait_for_selector": "string"
    },
    "credits": 0,
    "status_code": 0,
    "duration_ms": 0,
    "error": "string",
    "callback_url": "string",
    "created_at": "2024-01-01T00:00:00Z",
    "finished_at": "2024-01-01T00:00:00Z",
    "status_url": "string",
    "response": {
      "status_code": 0,
      "content_type": "string",
      "final_url": "string",
      "headers": {},
      "content": "string",
      "expires_at": "2024-01-01T00:00:00Z"
    }
  }
}
Responses
200 Acknowledged. Any 2xx works.
WEBHOOKwatchlistProductChanged
Watchlist products changed

Tracked fields moved on one or more items in a run (on Amazon confirmed at standard or full: a pulse alone never sends this). Each entry carries id (plus asin on Amazon lists). At most 500 products per delivery; part/parts number them. Same envelope ({ id, type, created_at, data }), signature and retries as job webhooks. Sent to the list's webhook_url, else your account webhook.

Parameters
Scrapely-Signaturestringheaderrequired
Scrapely-Eventstringheaderrequired
watchlist.product.changed
Scrapely-Deliverystringheaderrequired
Scrapely-Attemptintegerheaderrequired
Payload application/json
idstring
Stable across retries: dedupe on it.
type
created_atstring
dataobject
Show child parameters
watchlist_idstring
watchlist_namestring
platformstring
marketplacestring
currencystring
The currency of every price in this payload.
run_idstring
run_numberinteger
partinteger
1-based; a run with many changes sends several deliveries.
partsinteger
changesWatchlistChange[]
Show child parameters
idstring
The item's id on the list's platform: an ASIN on Amazon, an item id on Walmart, a TCIN on Target, a SKU on Best Buy.
asinstringdeprecated
Amazon lists only: the same value as id, kept for clients written before platforms. Absent on every other platform.
changed_atstring
tierstring
The tier that fetched it (Amazon: standard or full; one-tier platforms: their one tier).
changesobject
Only the fields that moved, of: price, inStock, availabilityType, isFba, offerListingId, merchant, condition, newCount, newMinPrice, usedCount, usedMinPrice. merchant is compared by id.
snapshotobject
The tracked fields from the last detail fetch, named as in /v1/products results (each platform tracks its own; these are Amazon's). null = the retailer did not say.
{
  "id": "evt_1a2b3c4d5e6f7a8b9c0d",
  "type": {},
  "created_at": "2024-01-01T00:00:00Z",
  "data": {
    "watchlist_id": "string",
    "watchlist_name": "string",
    "platform": "amazon",
    "marketplace": "us",
    "currency": "USD",
    "run_id": "string",
    "run_number": 0,
    "part": 0,
    "parts": 0,
    "changes": [
      {
        "id": null,
        "asin": null,
        "changed_at": null,
        "tier": null,
        "changes": null,
        "snapshot": null
      }
    ]
  }
}
Responses
200 Acknowledged. Any 2xx works.
WEBHOOKwatchlistProductDelisted
Watchlist products delisted

The retailer answered not_found for these items. They stay on the list as delisted and are not fetched again. partial/unavailable never delist. Each entry carries id (plus asin on Amazon lists). Same envelope ({ id, type, created_at, data }), signature and retries as job webhooks. Sent to the list's webhook_url, else your account webhook.

Parameters
Scrapely-Signaturestringheaderrequired
Scrapely-Eventstringheaderrequired
watchlist.product.delisted
Scrapely-Deliverystringheaderrequired
Scrapely-Attemptintegerheaderrequired
Payload application/json
idstring
Stable across retries: dedupe on it.
type
created_atstring
dataobject
Show child parameters
watchlist_idstring
watchlist_namestring
platformstring
marketplacestring
currencystring
The currency of every price in this payload.
run_idstring
run_numberinteger
partinteger
partsinteger
productsobject[]
Show child parameters
idstring
The item's id on the list's platform: an ASIN on Amazon, an item id on Walmart, a TCIN on Target, a SKU on Best Buy.
asinstringdeprecated
Amazon lists only: the same value as id, kept for clients written before platforms. Absent on every other platform.
delisted_atstring
detected_bystring
pulse | standard | full
last_snapshotWatchlistSnapshot
{
  "id": "evt_1a2b3c4d5e6f7a8b9c0d",
  "type": {},
  "created_at": "2024-01-01T00:00:00Z",
  "data": {
    "watchlist_id": "string",
    "watchlist_name": "string",
    "platform": "amazon",
    "marketplace": "us",
    "currency": "USD",
    "run_id": "string",
    "run_number": 0,
    "part": 0,
    "parts": 0,
    "products": [
      {
        "id": null,
        "asin": null,
        "delisted_at": null,
        "detected_by": null,
        "last_snapshot": null
      }
    ]
  }
}
Responses
200 Acknowledged. Any 2xx works.
WEBHOOKwatchlistRunCompleted
Watchlist run completed

Every run that ends: completed, insufficient_credits (nothing fetched or charged; watchlist.status shows an auto-pause) or failed. Same envelope ({ id, type, created_at, data }), signature and retries as job webhooks. Sent to the list's webhook_url, else your account webhook.

Parameters
Scrapely-Signaturestringheaderrequired
Scrapely-Eventstringheaderrequired
watchlist.run.completed
Scrapely-Deliverystringheaderrequired
Scrapely-Attemptintegerheaderrequired
Payload application/json
idstring
Stable across retries: dedupe on it.
type
created_atstring
dataWatchlistRun & object
Show child parameters
idstring
object
watchlist_idstring
run_numberinteger
triggerstring
schedule | manual
kindstring
pulse | refresh
statusstring
running | completed | insufficient_credits | failed
creditsinteger
Charged, after refunds.
statsobject
Show child parameters
trackedinteger
sweep_tierstring
pulse | standard
callsobject
escalatedobject
deferredinteger
Escalations postponed to the next run: the balance could not cover them.
changedinteger
delistedinteger
retry_next_runinteger
partial + unavailable items (free, retried next run, never a change).
credits_neededinteger
On insufficient_credits: what the run needed up front.
errorstring
started_atstring
finished_atstring
watchlistobject
Show child parameters
idstring
namestring
platformstring
marketplacestring
statusstring
active | paused
paused_reasonstring
next_run_atstring
{
  "id": "evt_1a2b3c4d5e6f7a8b9c0d",
  "type": {},
  "created_at": "2024-01-01T00:00:00Z",
  "data": {
    "id": "wlrun_5f0c8a1b2d3e4f56",
    "object": {},
    "watchlist_id": "string",
    "run_number": 0,
    "trigger": "schedule",
    "kind": "pulse",
    "status": "running",
    "credits": 0,
    "stats": null,
    "error": null,
    "started_at": "2024-01-01T00:00:00Z",
    "finished_at": null,
    "watchlist": {
      "id": null,
      "name": null,
      "platform": null,
      "marketplace": null,
      "status": null,
      "paused_reason": null,
      "next_run_at": null
    }
  }
}
Responses
200 Acknowledged. Any 2xx works.
Updated