Platform API: Errors

Stable error codes returned by the Dualhook Platform API and what each one means for your integration.

The Dualhook Platform API returns stable, typed error codes with a consistent JSON shape. Every error includes a code (a stable machine-readable string), a human-readable message, and a type you can group on. Codes like waba_webhook_conflict and idempotency_key_collision are the ones you'll most often need to handle explicitly.

Error shape

{
  "error": {
    "code": "invalid_redirect_url",
    "message": "successRedirectUrl must match allowed_redirect_urls in partner settings",
    "type": "invalid_request"
  }
}

Error codes

CodeWhen
unauthorizedMissing or invalid bearer token
forbiddenAPI key not bound to a Platform-tier subscription
subscription_inactiveSubscription is unpaid/canceled
invalid_requestBody validation failed
invalid_redirect_urlURL not in your allowed_redirect_urls whitelist
invalid_webhook_urlWebhook URL did not pass SSRF validation (must point to a public address)
idempotency_key_collisionSame Idempotency-Key, different body, within 1h
webhook_preflight_failedSession creation only: the simulated hub.challenge GET against your webhookOverrideUrl failed. The error includes preflight.category (the errorCategory taxonomy from onboarding.failed, plus two preflight-only values: endpoint_unreachable for DNS/TLS/connection failures and endpoint_http_error for unexpected non-2xx statuses), preflight.httpStatus, and a receivedPreview of the body. Pass skipWebhookPreflight: true if your endpoint allowlists Meta's IPs/user-agent
waba_webhook_conflictA connection on the same WABA belonging to a different tenant has a different webhook URL and/or verify token (same-tenant re-onboarding replaces the config instead — see onboarding sessions). The error context includes mismatch (url | verify_token | both) and the existing URL on file
webhook_subscribe_failedMeta rejected the new webhook URL on PATCH
meta_token_expiredThe stored Cloud API access token has been revoked or expired and must be reconnected
meta_errorMeta returned an error we couldn't map to a more specific code; check metaErrorCode / metaTraceId if present
connection_suspendedConnection is currently not eligible for secret reveal
event_not_redeliverablePOST /events/:id/redeliver on an event that is pending (still retrying) or already delivered
not_foundConnection / session / tenant not found
rate_limitedPer-scope limit exceeded — see Rate limits
internal_errorServer-side issue — safe to retry with the same Idempotency-Key

Error type buckets

The type field is a coarser bucket the code belongs to. Useful for client-side error handling that doesn't need to switch on every code:

TypeWhen
authenticationunauthorized (401)
authorizationforbidden, subscription_inactive (402/403)
invalid_requestAll 4xx except auth + rate limits
rate_limitrate_limited (429)
serverinternal_error, meta_error (5xx)

Related

  • Platform API (Multi-Tenant Onboarding)Build embedded WhatsApp onboarding into your SaaS. Programmatic connection creation, per-tenant webhook routing, HMAC-signed event webhooks.
  • Platform API: Onboarding sessionsCreate and look up co-branded onboarding sessions. Idempotency, redirect URL whitelisting, expiry, and the 1-hour session window.
  • Platform API: Event webhooksReceive HMAC-SHA256 signed lifecycle events: onboarding, connection.mode_resolved, disconnect, and coexistence heartbeat events.
Browse more docsStart Free Trial