Webhooks
Configure webhooks to receive real-time event notifications via HTTP POST.
GET /api/v1/webhooks
List webhooks for an app.
Authentication: JWT required
curl "https://api.attributehq.com/v1/webhooks?app_id=YOUR_APP_ID" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response (200 OK):
{
"success": true,
"data": {
"webhooks": [
{
"id": "wh_abc123",
"url": "https://api.yourcompany.com/attributehq-webhook",
"events": ["install", "event"],
"active": true,
"created_at": "2025-01-15T10:30:00Z"
}
]
}
}POST /api/v1/webhooks
Create a new webhook.
Authentication: JWT required
curl -X POST https://api.attributehq.com/v1/webhooks \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"app_id": "YOUR_APP_ID",
"url": "https://api.yourcompany.com/attributehq-webhook",
"events": ["install", "event"]
}'Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
app_id | string | Yes | App UUID |
url | string | Yes | HTTPS webhook endpoint URL |
events | string[] | Yes | "install", "event", "re-engagement" |
Response (201 Created):
{
"success": true,
"data": {
"webhook": {
"id": "wh_abc123",
"url": "https://api.yourcompany.com/attributehq-webhook",
"events": ["install", "event"],
"active": true,
"created_at": "2025-01-15T10:30:00Z"
},
"secret": "whsec_abc123def456...",
"message": "Save this secret - it will not be shown again."
}
}Save the secret immediately! It’s used for HMAC signature verification and shown only once.
PUT /api/v1/webhooks/:id
Update a webhook.
DELETE /api/v1/webhooks/:id
Delete a webhook.
POST /api/v1/webhooks/:id/test
Send a test webhook with sample payload.
GET /api/v1/webhooks/logs
View webhook delivery logs.
curl "https://api.attributehq.com/v1/webhooks/logs?app_id=YOUR_APP_ID&limit=50" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Webhook Payload
All webhook requests are HTTP POST with JSON body:
Install Event
{
"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
}
}In-App Event
{
"event_type": "event",
"timestamp": 1700000000000,
"data": {
"app_id": "770e8400-...",
"device_id": "A1B2C3D4-...",
"event_name": "purchase",
"properties": {
"amount": 5000,
"currency": "NGN"
}
}
}Signature Verification
Every webhook includes an X-Signature header for HMAC SHA-256 verification:
X-Signature: sha256=abc123def456...Verification Examples
Node.js
const crypto = require('crypto')
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}
// Express middleware
app.post('/webhook', (req, res) => {
const signature = req.headers['x-signature']
const payload = JSON.stringify(req.body)
if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature')
}
// Process webhook...
res.status(200).send('OK')
})Retry Policy
- Failed deliveries (non-2xx response or timeout) are retried 3 times
- Exponential backoff between retries
- 10-second timeout per request
- All delivery attempts are logged (viewable via
GET /webhooks/logs)