Skip to main content

Overview

Webhooks allow you to receive real-time HTTP notifications when events occur in your AppDNA application. When a subscribed event fires, AppDNA sends a POST request to your configured endpoint with a JSON payload describing the event.

Supported Event Types

AppDNA supports 16 webhook event types:
Event TypeTrigger
onboarding.startedUser begins an onboarding flow
onboarding.completedUser completes an onboarding flow
survey.completedUser submits a survey response
payment.completedPurchase transaction succeeds
payment.failedPurchase transaction fails
subscription.canceledUser cancels a subscription
push.deliveredPush notification delivered to device
push.openedUser taps a push notification
email.openedUser opens an email
email.clickedUser clicks a link in an email
message.clickedUser interacts with an in-app message
journey.completedUser completes a journey/lifecycle flow
journey.exitedUser exits a journey before completion
experiment.exposureUser is exposed to an experiment variant
user.identifiedAnonymous user is linked to a known user ID
webhook.testTest event sent from the dashboard

Payload Format

Every webhook delivery sends a JSON payload with the following structure:
{
  "id": "evt-550e8400-e29b-41d4-a716-446655440000",
  "type": "payment.completed",
  "created_at": "2026-02-19T10:00:00Z",
  "data": {
    "user_id": "user-123",
    "product_id": "premium_monthly",
    "transaction_id": "txn-456",
    "price": 9.99,
    "currency": "USD",
    "platform": "ios"
  }
}
FieldTypeDescription
idstring (uuid)Unique event identifier
typestringOne of the 16 supported event types
created_atstring (datetime)ISO 8601 timestamp of when the event occurred
dataobjectEvent-specific payload (varies by event type)

Request Headers

Every webhook request includes the following headers:
HeaderDescription
Content-Typeapplication/json
X-AppDNA-SignatureHMAC-SHA256 signature for verification
X-AppDNA-EventEvent type (e.g., payment.completed)
X-AppDNA-Delivery-IdUnique delivery identifier for deduplication
X-AppDNA-TimestampUnix timestamp of when the request was sent
User-AgentAppDNA-Webhooks/1.0

Signature Verification

Every webhook request is signed with your endpoint secret using HMAC-SHA256. Always verify the signature before processing the payload. The signature is sent in the X-AppDNA-Signature header in the format:
X-AppDNA-Signature: sha256=<hex-encoded-signature>
The signing input is the raw JSON stringified request body.
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  const providedSignature = signature.replace('sha256=', '');

  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(providedSignature, 'hex')
  );
}

// Express.js example
app.post('/webhooks/appdna', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-appdna-signature'];
  const payload = req.body.toString();

  if (!verifyWebhookSignature(payload, signature, process.env.APPDNA_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(payload);
  console.log(`Received ${event.type}:`, event.data);

  res.status(200).send('OK');
});
Always use constant-time comparison (e.g., crypto.timingSafeEqual in Node.js or hmac.compare_digest in Python) when verifying signatures. Simple string comparison is vulnerable to timing attacks.

Retry Policy

If your endpoint returns a non-2xx response or times out, AppDNA retries the delivery with exponential backoff:
RetryDelay
1st30 seconds
2nd2 minutes
3rd10 minutes
4th1 hour
5th4 hours
Maximum retries: 5 attempts total (1 initial + 5 retries = 6 total attempts). Delivery timeout: 30 seconds. If your server does not respond within 30 seconds, the delivery is marked as failed and scheduled for retry. Maximum response body logged: 10 KB. Response bodies exceeding this limit are truncated in delivery logs.
After 50 consecutive delivery failures, the webhook endpoint is automatically disabled. You can re-enable it from the dashboard or via the API.

Management API

All management endpoints require Customer JWT authentication (Authorization: Bearer header).

List Endpoints

GET /api/v1/webhooks/endpoints
Returns all configured webhook endpoints for the current application.

Create Endpoint

POST /api/v1/webhooks/endpoints
Request body:
{
  "name": "Production Backend",
  "url": "https://api.example.com/webhooks/appdna",
  "events": ["payment.completed", "payment.failed", "subscription.canceled"],
  "description": "Handles payment lifecycle events",
  "headers": {
    "X-Custom-Header": "custom-value"
  }
}
FieldTypeRequiredDescription
namestringYesHuman-readable endpoint name
urlstringYesDestination URL (HTTPS required)
eventsstring[]YesArray of event types to subscribe to
descriptionstringNoOptional description
headersobjectNoCustom headers to include in deliveries
Webhook URLs must use HTTPS. HTTP endpoints are rejected.

Update Endpoint

PATCH /api/v1/webhooks/endpoints/{id}
Update any field on an existing endpoint. Partial updates are supported.

Delete Endpoint

DELETE /api/v1/webhooks/endpoints/{id}
Permanently deletes the endpoint and all associated delivery history.

Test Endpoint

POST /api/v1/webhooks/endpoints/{id}/test
Sends a webhook.test event to the endpoint. Use this to verify your endpoint is reachable and correctly verifying signatures.

Rotate Signing Secret

POST /api/v1/webhooks/endpoints/{id}/rotate-secret
Generates a new signing secret for the endpoint. The previous secret is immediately invalidated.
After rotating a secret, update your server’s verification code with the new secret before the next delivery attempt.

Disable Endpoint

POST /api/v1/webhooks/endpoints/{id}/disable
Temporarily disables the endpoint. No deliveries are attempted while disabled. Events that occur during this period are not queued.

Enable Endpoint

POST /api/v1/webhooks/endpoints/{id}/enable
Re-enables a previously disabled endpoint.

List Deliveries

GET /api/v1/webhooks/endpoints/{id}/deliveries
Returns a paginated list of delivery attempts for the endpoint, including status, response code, and timestamps.

Delivery Detail

GET /api/v1/webhooks/deliveries/{id}
Returns full details for a specific delivery attempt, including request/response headers and body.

Retry Failed Delivery

POST /api/v1/webhooks/deliveries/{id}/retry
Manually retries a failed delivery. The retry is attempted immediately, independent of the automatic retry schedule.

Event Catalog

GET /api/v1/webhooks/events
Returns the full list of supported webhook event types with descriptions.
Your webhook integration is working correctly when you receive a webhook.test event at your endpoint and can successfully verify the signature.