Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.neariq.io/llms.txt

Use this file to discover all available pages before exploring further.

How webhooks work

When NearIQ detects a competitive change, it can POST a JSON payload to a URL you register. This lets you build real-time integrations — send an alert to Slack, trigger a workflow, or update your own dashboard.

Registering a webhook

curl -X POST https://app.neariq.io/api/v1/webhooks \
  -H "X-NearIQ-Key: niq_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/hooks/neariq",
    "events": ["competitor.rating_change", "competitor.review_surge"]
  }'
Webhook URLs must use HTTPS, must not include embedded credentials, and must be publicly routable; localhost, private, link-local, multicast, and reserved network hosts are rejected. NearIQ also re-checks DNS resolution before delivery and deactivates endpoints that resolve to non-public addresses. NearIQ generates and returns the signing secret once when the webhook is created. Supported events are competitor.rating_change, competitor.review_surge, competitor.hours_change, competitor.price_change, competitor.website_change, competitor.new_competitor, business.rating_change, business.review_surge, and alert.created.

Payload format

{
  "id": "0bff1ff0-98ab-4c2e-a3ee-4c0b39c090a1",
  "event": "competitor.rating_change",
  "createdAt": "2026-04-27T09:14:22Z",
  "data": {
    "alert": {
      "id": "8e0a8c1d-2a95-4d17-a96b-1ef6b47681c0",
      "type": "rating_change",
      "severity": "opportunity",
      "title": "Rival Pizza dropped from 4.6 to 4.3 stars",
      "description": "Recent reviews suggest service speed is becoming a weakness.",
      "recommendation": "Reply to your latest positive reviews and highlight fast pickup in your next post.",
      "createdAt": "2026-04-27T09:14:22Z",
      "isOwnBusiness": false,
      "metadata": null
    },
    "competitor": {
      "id": "comp_xyz",
      "name": "Rival Pizza",
      "placeId": "ChIJ..."
    }
  }
}

Verifying signatures

NearIQ signs every webhook delivery using HMAC-SHA256. Verify the signature to ensure the request came from NearIQ:
import { createHmac } from 'crypto'

function verifyWebhook(payload: string, timestamp: string, signature: string, secret: string): boolean {
  const expected = createHmac('sha256', secret)
    .update(`${timestamp}.${payload}`)
    .digest('hex')
  return signature === `sha256=${expected}`
}

// In your webhook handler:
const sig = req.headers['x-neariq-signature']
const timestamp = req.headers['x-neariq-timestamp']
const raw = req.rawBody // unparsed request body string
if (!verifyWebhook(raw, timestamp, sig, process.env.NEARIQ_WEBHOOK_SECRET)) {
  return res.status(401).send('Invalid signature')
}
Every delivery includes X-NearIQ-Delivery, X-NearIQ-Event, X-NearIQ-Timestamp, and X-NearIQ-Signature. The signature uses the exact raw request body, prefixed by the timestamp.

Retry behavior

NearIQ retries failed deliveries (non-2xx response or timeout) with exponential backoff:
  • Retry delays start at about 1 minute
  • Delays increase exponentially and cap at about 1 hour
  • Deliveries are attempted up to 8 times
After the final attempt, the delivery is marked dead. The endpoint remains registered so you can fix it without recreating the secret.

Webhook management endpoints

MethodPathDescription
GET/webhooksList all registered webhooks
POST/webhooksRegister a new webhook
PATCH/webhooks/:idUpdate URL, events, or active status
DELETE/webhooks/:idRemove a webhook