コンテンツにスキップ

Generic Webhook Channel

このコンテンツはまだ日本語訳がありません。

Rolling out The generic webhook channel is actively shipping. The behavior documented here is the launch contract and may change before general availability.

The generic webhook channel POSTs reminder and escalation notification events to an HTTPS endpoint your organization controls — useful for routing nudges into an internal tool, a ticketing system, or a messenger Pidgr doesn’t integrate with natively. Like every channel, it is notification-only: the payload identifies who has which pending campaign and carries a deeplink — campaign content never leaves Pidgr.

Pidgr sends a JSON POST per notification event:

{
"user_id": "user-uuid",
"campaign_id": "campaign-uuid",
"deeplink_url": "https://links.pidgr.com/c/abc123",
"occurred_at": "2026-06-12T14:00:00Z"
}

There is no per-user opt-in. An organization admin configures the endpoint URL and receives a shared signing secret; routing notifications onward (and any per-user preferences) is your system’s responsibility.

Endpoint requirements:

  • HTTPS only — plain http:// URLs are rejected.
  • Publicly resolvable — private, loopback, and link-local addresses are rejected (the same SSRF protections as workflow webhooks).
  • Fast 2xx — respond within the 5-second default timeout; process asynchronously if needed.

Every request carries an X-Pidgr-Signature header: the lowercase hex HMAC SHA-256 of the raw request body, keyed with your organization’s shared secret. Reject any request whose signature doesn’t match.

// Node.js — verify X-Pidgr-Signature
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyPidgrSignature(rawBody, signatureHeader, secret) {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(signatureHeader ?? "", "hex");
return a.length === b.length && timingSafeEqual(a, b);
}

Tips:

  • Compute the HMAC over the raw bytes of the body, before any JSON parsing or re-serialization.
  • Use a constant-time comparison (as above) to avoid timing side channels.
  • Rotate the shared secret from the admin dashboard if it is ever exposed; rotation takes effect on the next send.
  • Timeout — 5 seconds per request by default (configurable).
  • Retries — failed deliveries are retried up to 3 times with exponential backoff (1s, 5s, 30s).
  • Idempotency — retries re-send the same payload; deduplicate on (user_id, campaign_id, occurred_at).
  1. Open the admin dashboard → IntegrationsWebhook.
  2. Set the endpoint URL and copy the generated signing secret into your receiving service.
  3. In the workflow editor, add Webhook to the notification options of any reminder or escalation step.
  4. Send a test event from the dashboard and confirm your endpoint verifies the signature and returns 2xx.