Skip to main content
Use tapace.webhooks.constructEvent() to verify TapAce webhook signatures before processing an event. Keep the original request body bytes; parsing and reserializing JSON can invalidate a signature. In the dashboard, select the intended organization and test or live mode, then open Developers → Webhooks → Add endpoint. Use a public HTTPS URL and select pass.installed, pass.removed or All events. Open the endpoint’s Settings → Reveal secret and store it as TAPACE_WEBHOOK_SECRET in your receiver’s environment. The signing secret is separate from your API key. See the webhook guide.

Verify an incoming request

The SDK accepts a string, Buffer or Uint8Array body and either a Headers object or a header record. It supports both Standard Webhooks names (webhook-id, webhook-timestamp, webhook-signature) and the corresponding svix-* names.
If you already have a TapAce client, use tapace.webhooks.constructEvent(rawBody, headers, secret) instead. Standalone WebhooksResource does not require an API key.

Express verification example

Express is your application’s dependency, not a dependency of the SDK. This example verifies and prints events; replace the console output with durable acceptance before using it for business processing.
Expose the handler through your own public HTTPS endpoint when testing TapAce deliveries. A local port alone is not reachable by the service.

Timestamp and signature checks

Default timestamp tolerance is 300 seconds. An older timestamp or one more than 300 seconds in the future is rejected. The optional fourth argument overrides the tolerance in seconds; keep your server clock synchronized rather than widening it to hide clock errors. Timestamps must be decimal integer Unix seconds within JavaScript’s safe integer range. Signatures and signing secrets must contain valid base64; malformed encodings and extra padding are rejected. Signing secrets may use the whsec_ prefix and URL-safe base64. The SDK accepts multiple version-1 signatures and verifies if one matches the configured secret, which supports deliveries signed during secret rotation. Update the receiver to the new signing secret when you rotate it. Missing headers, invalid signatures, out-of-window timestamps and invalid JSON raise TapAceWebhookSignatureError.

Process events durably

After verification, persist or enqueue the event durably before returning a success response. If accepting it fails, return an error so delivery can retry. Perform longer work in a worker. The verifier accepts repeated valid deliveries; it does not remember processed events. Use event.id to deduplicate deliveries in your own persistent storage. Coordinate the unique event record and business changes transactionally, or make each side effect independently idempotent. The current event types are pass.installed and pass.removed. Fetch details with tapace.passes.retrieve(event.data.pass.id) when needed; event data contains no holder details. Webhook payload properties such as created_at and data.pass.template_id use their documented names. Verification does not convert them to camelCase or perform full runtime schema validation. See Webhooks for platform reliability, delivery retries and presence snapshots.

Test real lifecycle delivery

  1. Create an endpoint in your test organization and configure its secret in the receiver. A local receiver needs a temporary HTTPS tunnel or another publicly reachable host.
  2. Issue a dedicated test pass and install it on a phone. Verify the received pass.installed event, its data.pass.id, livemode: false and presence snapshot.
  3. Remove that same pass from the wallet. Verify pass.removed. On Apple, the active device count decreases; it reaches zero when its last registered device removes it.
  4. Reinstall the pass. Verify a new pass.installed event with a new event.id. Reinstallation is a new lifecycle event, not a duplicate of the first installation.
  5. In the endpoint’s Deliveries, open a delivery and select Resend. The repeated event must pass signature verification and be recognized using the existing event.id, without repeating your business change.
  6. Send an unsigned request or change the body without updating its signature. Your receiver must reject it.
  7. Disable or delete a temporary endpoint before stopping its tunnel, so TapAce does not keep retrying an offline URL.
Apple events report individual device registration changes. Google lifecycle events are best effort. Use the current pass’s presence when you need to reconcile installation state; do not infer it from a notification’s delivery status.