For the complete documentation index, see llms.txt. This page is also available as Markdown.

Can I send webhook events to multiple URLs?

Yes. Bead supports two layers of webhook delivery, and you can combine them to fan-out each event to several destinations:

Layer
How to set it
Scope
Typical use-cases

Terminal webhook

PUT /Terminals/{terminalId}/webhook

All payments created by the terminal

Core order-management system, accounting queue

Per-payment overrides

webhookUrls array in POST /payments/crypto

Only the payment being created

A/B testing, partner-specific listener, analytics hook

When you include a webhookUrls array, Bead POSTs the same JSON payload to all of these endpoints:

  1. The terminal's default webhook URL

  2. Every URL listed in webhookUrls

No extra configuration is needed—just add the array to your create-payment request:

{
    "...": "...other fields...",
    "webhookUrls": [
        "https://orders.example.com/bead/events",
        "https://analytics.example.com/hooks/bead"
    ]
}

Delivery behavior

  • Fan-out: events are sent to every destination in parallel.

  • Success criteria: each URL must return HTTP 2xx; any non-2xx triggers retries for that endpoint only (exponential back-off, 24 h window).

  • Same body, different signature per delivery: the JSON body is identical for every recipient, so your parsing logic doesn't need to branch by destination. The x-webhook-signature header, however, is generated fresh for each individual delivery (a new timestamp each time), so the signature value differs across recipients even though the body and the underlying secret are the same. Your verification code should recompute the signature per delivery rather than comparing signature values against each other.

Tips & best practices

  • Idempotency – process webhooks idempotently (e.g., by trackingId + statusCode) in case one URL retries while another succeeds.

  • Environment isolation – point sandbox terminals to test URLs, then add production URLs in webhookUrls only when you go live.

  • Signing secrets – the HMAC uses the terminal's signingSecret, for both the terminal's own webhook and every URL in webhookUrls. Share that secret securely with every service that needs to verify events.

  • Set a terminal webhook first, even if webhookUrls is your primary path – a terminal only has a signingSecret once you've called PUT /Terminals/{terminalId}/webhook on it at least once. If you only ever use webhookUrls and never set a terminal-level default, that terminal has no signing secret, and its webhookUrls deliveries are sent without an x-webhook-signature header — silently, with no error or warning. Set the terminal-level webhook first to establish the secret, then rely on webhookUrls for additional routing.

  • Performance – acknowledge quickly (under 1 s) and offload heavy work to background jobs.

Testing multiple endpoints

  1. Sandbox first – set a sandbox webhook URL on the terminal (this also establishes the signingSecret).

  2. Include a second test URL in webhookUrls.

  3. Create a payment in sandbox and complete it with a test wallet.

  4. Confirm both endpoints receive the same event body, each with a valid (but distinct) x-webhook-signature, and that retries stop after 2xx.

Last updated