Webhooks
Webhooks deliver real-time event data to your server via HTTP POST.
How Webhooks Work
Event occurs (install, purchase, etc.)
↓
System checks for matching webhook subscriptions
↓
POST request sent to your URL with event payload
↓
Includes X-Signature header for HMAC verificationEvents
| Event | Trigger | Description |
|---|---|---|
install | App install attributed | New install with attribution data |
event | In-app event tracked | Custom events, purchases, etc. |
re-engagement | Returning user attributed | User returns via a new ad click |
Setup
- Go to Dashboard → Settings → Webhooks
- Click Add Webhook
- Enter your HTTPS endpoint URL
- Select which events to receive
- Save — copy the secret key immediately (shown only once)
Payload Format
Install Webhook
{
"event_type": "install",
"timestamp": 1700000000000,
"data": {
"app_id": "770e8400-...",
"device_id": "A1B2C3D4-...",
"platform": "android",
"media_source": "facebook",
"campaign_id": "summer_campaign",
"match_type": "device_id",
"confidence": 100,
"is_organic": false
}
}Event Webhook
{
"event_type": "event",
"timestamp": 1700000000000,
"data": {
"app_id": "770e8400-...",
"device_id": "A1B2C3D4-...",
"event_name": "purchase",
"properties": {
"amount": 5000,
"currency": "NGN",
"product_id": "premium_plan"
}
}
}Signature Verification
Every webhook request includes an X-Signature header:
X-Signature: sha256=abc123def456...Always verify the signature to ensure the request came from AttributeHQ and wasn’t tampered with.
Node.js
const crypto = require('crypto')
function verifySignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}Use constant-time comparison (timingSafeEqual, compare_digest, secure_compare) to prevent timing attacks.
Retry Policy
| Attempt | Delay |
|---|---|
| 1st retry | ~1 minute |
| 2nd retry | ~5 minutes |
| 3rd retry | ~30 minutes |
After 3 failed attempts, the delivery is marked as failed in the logs. You can view all delivery attempts in Dashboard → Settings → Webhooks → Logs.
Best Practices
- Always verify signatures — Don’t trust webhook payloads without verification
- Respond quickly — Return
200 OKwithin 10 seconds. Process asynchronously if needed - Handle duplicates — In rare cases, a webhook may be delivered more than once. Use the
timestamp+device_idas an idempotency key - Use HTTPS — Webhook URLs must use HTTPS for security