Skip to Content

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:

FieldTypeRequiredDescription
app_idstringYesApp UUID
urlstringYesHTTPS webhook endpoint URL
eventsstring[]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

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)