Connection-Scoped Keys
Each dh_live_... key is bound to exactly one Dualhook connection and phone-number ID. It cannot be used for another connection or as an arbitrary Meta Graph API credential.
Create and Store a Key
An organization admin creates the key from Connection → Overview → Outbound API key. Plaintext is displayed once. Dualhook stores only its SHA-256 hash.
Store the key in a server-side secret manager. Never put it in browser code, mobile applications, public automation exports, logs, screenshots, or support messages. Do not share, resell, sublicense, or reuse it for another customer.
Rotation
Rotation creates a new primary key and offers three choices for the old key:
- revoke immediately
- keep a one-hour grace overlap
- keep a 24-hour grace overlap
Use an overlap only long enough to deploy the new key. Disconnecting the connection, clearing its webhook configuration, or revoking API access invalidates its Dualhook keys immediately.
Request Controls
Use Authorization: Bearer dh_live_.... The runtime enforces connection binding, exact route allowlisting, and per-connection rate limits. It does not retry sends automatically. Keep the X-Dualhook-Request-Id response header with your own content-free request log.
The default limits are 80 message operations per second, 20 media uploads or deletions per minute, and 120 media metadata or download requests per minute, all per connection. After 30 consecutive message requests rejected by Meta, sending for that connection pauses for five minutes. Any successful Meta send resets that failure count. A throttled response uses HTTP 429 and includes Retry-After.
Privacy Model
Inbound message-path webhooks remain direct from Meta to your endpoint. Outbound payloads and requested media stream through Dualhook's Cloudflare Worker to Meta without body persistence or caching. Operational logs exclude message content, recipient numbers, media content, authorization headers, and Meta download URLs.