Webhooks

Get notified when jobs complete instead of polling. Webhooks are signed, retried automatically, and tracked with health states so you know when delivery fails.

Setting up webhooks

Go to Dashboard → Webhooks to add an endpoint. By default, endpoints subscribe to job.completed and job.failed events.

job.completed

Fired when a scan or classify job finishes successfully.

job.failed

Fired when a job fails after all retry attempts are exhausted.

billing.topup_succeeded

Auto-topup payment was processed successfully.

billing.topup_failed

Auto-topup payment failed.

Testing your endpoint

Use POST /v1/webhooks/test to send a test delivery before going live:

curl -X POST https://api.on-page.ai/v1/webhooks/test \
  -H "Authorization: Bearer op_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example/webhooks/onpage",
    "event": "job.completed"
  }'

The response includes a signing_secret so you can verify the test delivery signature matches.

Verifying signatures

Every delivery includes these headers:

OnPage-Signature: <hmac-sha256(timestamp.body)>
OnPage-Timestamp: <unix-seconds>
OnPage-Delivery-Id: <delivery-id>
OnPage-Event: <event-name>
User-Agent: OnPage-Webhooks/1.0

The signature is computed as HMAC-SHA256(signing_secret, timestamp + "." + raw_body). Verify by recomputing the HMAC with your stored signing secret and comparing the result.

Node.js verification example

import crypto from "crypto";

function verifyWebhook(body, headers, secret) {
  const timestamp = headers["onpage-timestamp"];
  const signature = headers["onpage-signature"];
  const expected = crypto
    .createHmac("sha256", secret)
    .update(timestamp + "." + body)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Retries and endpoint health

Automatic retries

Failed deliveries retry with exponential backoff — up to 8 attempts over roughly 48 hours. Your endpoint should return a 2xx response quickly to avoid retries.

Endpoint health states

Endpoints move through active, degraded, and paused states as failures accumulate. After 20 consecutive failures, the endpoint is paused. Check the dashboard to re-enable it.

Best practices

Respond quickly

Return a 200 immediately, then process the payload async. Slow responses count as failures and trigger retries.

Always verify signatures

Don't process unverified payloads. An attacker could send fake completions to your endpoint.

Handle duplicates

Network issues can cause duplicate deliveries. Use the delivery_id to deduplicate on your end.

Monitor the dashboard

If your endpoint goes to "paused" state, you'll stop receiving events. Check the dashboard and fix the issue before re-enabling.