Skip to main content

Webhooks

Detour webhooks let you receive your analytics data on a recurring schedule, delivered automatically to an HTTPS endpoint you control. Instead of polling the dashboard or exporting manually, you register an endpoint once and Detour sends a signed JSON payload on each scheduled run.

Each webhook is tied to a specific app and a specific export type. You manage all of an organization's webhooks from the Webhooks section in the sidebar.


Availability

Webhooks are a paid feature. The number of active webhooks you can run depends on your plan:

PlanActive webhooks
Free0 (unavailable)
Starter3
Scale10
EnterpriseCustom

For full plan details, see Billing & Payments.

  • If you try to create a webhook beyond your active limit, it is saved but created paused (inactive) — activate it later after freeing up a slot.
  • If you downgrade to a plan with a lower limit, the oldest active webhooks are automatically paused to fit the new limit.

Creating a webhook

When creating a webhook you configure:

  • App — which app's data to export.
  • Endpoint URL — where the payload is delivered. Must be a public HTTPS URL on the default port (443). Endpoints that resolve to private/internal addresses are rejected.
  • Export type — the dataset to send:
    • Overview — aggregated performance (link stats, organic vs non-organic installs, retention, top events).
    • Links — link-level breakdown (paths and query parameters).
    • Events — SDK event activity.
  • ScheduleDaily, Weekly, or Monthly.
  • Platformall, ios, or android.
  • Filters — optional, to narrow the exported data.

When the webhook is created, a signing secret is shown once. Store it securely — it cannot be retrieved again later (you can rotate it if lost, see Managing webhooks).


Delivery schedule

Deliveries run on a fixed daily cycle (around 08:00 UTC). Each delivery covers the period that just closed:

ScheduleRuns onPeriod covered
DailyEvery dayThe previous day
WeeklyMondaysThe previous 7 days
MonthlyThe 1st of each monthThe previous calendar month

All period boundaries are in UTC.


Payload format

Each delivery is an HTTP POST with a JSON body:

{
"webhook_id": "<your webhook id>",
"type": "overview | links | events",
"app_id": "<your app id>",
"period": {
"start": "2026-05-01T00:00:00.000Z",
"end": "2026-06-01T00:00:00.000Z"
},
"delivered_at": "2026-06-01T08:00:00.000Z",
"data": [ /* rows for the selected export type */ ]
}

The shape of each row in data matches the chosen export type (the same rows you get from a manual export of that view).


Verifying the signature

Every request includes an X-Webhook-Signature header so you can confirm the payload came from Detour and wasn't tampered with:

X-Webhook-Signature: sha256=<hex digest>

The digest is an HMAC-SHA256 of the raw request body, keyed with your webhook's signing secret. Compute the same HMAC on your side and compare:

import { createHmac, timingSafeEqual } from "crypto";

function isValidSignature(rawBody, header, signingSecret) {
const expected = createHmac("sha256", signingSecret)
.update(rawBody)
.digest("hex");
const received = (header ?? "").replace(/^sha256=/, "");
const a = Buffer.from(expected);
const b = Buffer.from(received);
return a.length === b.length && timingSafeEqual(a, b);
}

Always compute the HMAC over the raw, unparsed request body. Re-serializing the JSON can change bytes (key order, whitespace) and break the comparison.


Delivery behavior

  • Detour only follows the configured URL — redirects are not followed.
  • The endpoint must respond with a 2xx status within 10 seconds for the delivery to count as successful.
  • Failed deliveries are not retried within the same cycle. The next attempt is the next scheduled run. Make sure your endpoint is reachable at delivery time.
  • The dashboard shows the last successful delivery time for each webhook.

Managing webhooks

From the Webhooks section you can:

  • Pause / resume a webhook. Resuming is subject to your plan's active-webhook limit — pause another webhook first if you're at the limit.
  • Rotate the signing secret. A new secret is shown once and the previous one stops being valid immediately, so update your endpoint before rotating.
  • Delete a webhook.

There is no in-place edit for a webhook's URL, schedule, export type, or platform — to change those, delete the webhook and create a new one.