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.
{
"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
| Method | Path | Description |
|---|
| GET | /webhooks | List all registered webhooks |
| POST | /webhooks | Register a new webhook |
| PATCH | /webhooks/:id | Update URL, events, or active status |
| DELETE | /webhooks/:id | Remove a webhook |