Sign inGet started

Monitoring WhatsApp channel health

Bird runs periodic health checks against your WhatsApp channel configuration and updates the channel's status whenever something changes. You can react to those changes in two ways:
  • Webhooks — receive a channel.updated event pushed to your endpoint as soon as the status changes
  • Check API — poll or trigger a check on demand and get structured diagnostic results including per-assertion detail
Common use cases:
  • Alert your team when a channel transitions to warning or inactive
  • Surface health details in an operations dashboard
  • Diagnose the root cause of a status change (quality score, token expiry, etc.)

Prerequisites

To subscribe to webhooks you need a workspace access key with the webhooks:write permission. See Authentication for details.
The Check API uses the connector ID, not the channel ID. You can find the connector ID on your channel's detail page or in the connectorId field of any channel webhook payload.

Channel health webhooks

Bird runs a health check on each WhatsApp channel on a regular schedule. When the result differs from the current status, the channel is updated and a channel.updated webhook fires.
Przykład kodu
Health check runs
  → assertions evaluated against Meta Graph API
  → channel status updated if changed
    → channel.updated webhook delivered to all matching subscriptions
The webhook carries the current channel object. It does not include the previous status or the individual assertion results that caused the transition — use the Check API to retrieve those.

Subscribing

Subscribe once per workspace. Use the channelStatus event filter to limit delivery to specific status values.
Przykład kodu
curl -X POST https://api.bird.com/workspaces/{workspaceId}/webhooks \
  -H "Authorization: AccessKey {accessKey}" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "channels",
    "event": "channel.updated",
    "url": "{{webhook_url}}",
    "signingKey": "{{signing_key}}",
    "eventFilters": [
      { "key": "platformId", "value": "whatsapp" }
    ]
  }'
You can create multiple subscriptions with different channelStatus filters to route degradation and recovery alerts to different endpoints.

Webhook payload

Przykład kodu
{
  "service": "channels",
  "event": "channel.updated",
  "payload": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "warning",
    "platformId": "whatsapp",
    "name": "My WhatsApp Channel",
    "connectorId": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
    "identifier": "+15551234567",
    "transactional": false,
    "preferences": {
      "disableProfileFetching": false,
      "explicitMarketingOptOut": false,
      "trackAdInitiatedThreads": false,
      "ignoreSuppressionChecks": false,
      "isPrivate": false,
      "disallowMmLite": false
    },
    "connectionParams": [],
    "settings": [],
    "capabilities": {},
    "createdAt": "2026-01-15T09:00:00Z",
    "updatedAt": "2026-05-26T14:32:00Z"
  }
}

Payload fields

FieldTypeDescription
servicestringAlways "channels"
eventstringAlways "channel.updated"
payload.idUUIDChannel ID
payload.statusstringNew channel status — see Status values
payload.platformIdstringAlways "whatsapp"
payload.connectorIdUUIDUse this with the Check API
payload.identifierstringPhone number in E.164 format
payload.updatedAtISO 8601Timestamp of this status change

Status values

StatusMeaningAction
activeAll health checks passingNo action needed
warningOne or more checks failingInspect via the Check API
inactiveWhatsApp subscription cancelledRe-subscribe or delete the channel
setting-upProvisioning in progressWait — another webhook fires on completion
failedProvisioning failedCheck connector configuration
The webhook does not include the previous status or which check failed. Compare payload.status against your own last-known state, or call the Check API, to determine whether this is a degradation or a recovery.

What triggers a warning

A single failing assertion is enough to change the channel status to warning.
Access
ConditionDetail
System user token invalid or expiredMeta returns 401 on WABA fetch
WABA not found or permissions removedWABA ID invalid or app removed from Business Manager
Unexpected Meta API errorIncludes non-timeout network failures
App not subscribed to WABABird app unsubscribed from WABA webhooks
Phone number not found in WABAPhone removed from WABA or permissions revoked
Phone number not accessiblePhone exists in WABA but cannot be fetched
Phone number
ConditionDetail
Phone status BANNEDNumber banned by WhatsApp
Phone status DELETEDNumber deleted from WhatsApp Business Manager
Phone status MIGRATEDNumber moved to a different WABA
Phone status DISCONNECTEDNumber cannot be registered
Phone status UNVERIFIEDNumber not verified
Phone status UNKNOWNStatus indeterminate from Meta
Phone status RATE_LIMITEDNumber is rate limited
Phone status PENDINGRegistration pending
Code verification EXPIRED or NOT_VERIFIEDVerification code expired or not completed
Display name DECLINED, PENDING_REVIEW, or EXPIREDName review in a non-approved state
Display name NON_EXISTSNo display name set
Quality score YELLOWModerate user feedback signals
Quality score REDPoor user feedback — messaging limits may apply
Business verification rejected or revokedMeta Business Account verification failed
Business unverified + messaging tier ≤ TIER_250Scaling path not completed
Business verification pending_need_more_infoMore information required from Meta
What does NOT trigger a warning
ConditionWhy
Meta API timeout on phone fetchResolves to indeterminate — check skipped, status unchanged
Business verification pendingResolves to indeterminate — check skipped, status unchanged
Account review status unknownResolves to indeterminate — check skipped, status unchanged
WABA inaccessible — dependent assertionsDownstream assertions become indeterminate; only wabaAccess itself triggers warning

Check API

The Check API returns structured diagnostic results with individual assertion names, statuses, and messages. Use it to determine the root cause after receiving a channel.updated webhook.
Bird runs two distinct sets of checks against a WhatsApp channel:
  • Channel checks — run by the Bird platform on a schedule against the Meta Graph API. These drive the channel status field and fire channel.updated webhooks.
  • Connector config checks — run on demand via POST /status/checks to validate the connector configuration.
Both appear in checks.results[].

Endpoints

Get current status
Przykład kodu
GET /workspaces/{workspaceId}/connectors/{connectorId}/status
Przykład kodu
curl https://api.bird.com/workspaces/{workspaceId}/connectors/{connectorId}/status \
  -H "Authorization: AccessKey {accessKey}"
Run a check now
Triggers an immediate check and returns results.
Przykład kodu
POST /workspaces/{workspaceId}/connectors/{connectorId}/status/checks
Przykład kodu
curl -X POST https://api.bird.com/workspaces/{workspaceId}/connectors/{connectorId}/status/checks \
  -H "Authorization: AccessKey {accessKey}"
Get check history
Przykład kodu
GET /workspaces/{workspaceId}/connectors/{connectorId}/status/checks
Returns a paginated list of past check runs.

Example response

Przykład kodu
{
  "channel": {
    "channelId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "platformName": "WhatsApp",
    "status": "error",
    "stage": "active"
  },
  "checks": {
    "runAt": "2026-05-26T14:30:00Z",
    "results": [
      {
        "name": "access",
        "displayName": "Check MessageBird has the required access",
        "status": "error",
        "assertions": [
          {
            "name": "wabaAccess",
            "status": "error",
            "message": "Access to WhatsApp Business Account has been revoked"
          },
          {
            "name": "appSubscribed",
            "status": "indeterminate",
            "message": "Unable to verify app subscription because the WhatsApp Business Account is not accessible"
          },
          {
            "name": "accountReviewStatus",
            "status": "indeterminate",
            "message": "Unable to check account review status because the WhatsApp Business Account is not accessible"
          },
          {
            "name": "businessVerificationStatus",
            "status": "indeterminate",
            "message": "Unable to check business verification status because the WhatsApp Business Account is not accessible"
          },
          {
            "name": "phoneAccess",
            "status": "indeterminate",
            "message": "Unable to check phone number access because the WhatsApp Business Account is not accessible"
          }
        ]
      },
      {
        "name": "phoneHealth",
        "displayName": "Check phone number health",
        "status": "ok",
        "assertions": [
          {
            "name": "phoneNumberStatus",
            "status": "ok",
            "message": "The phone number is connected in WhatsApp Business Manager."
          },
          {
            "name": "phoneQualityScore",
            "status": "ok",
            "message": "The phone number quality score is high."
          }
        ]
      }
    ]
  }
}

Response fields

FieldDescription
checks.runAtISO 8601 timestamp of when the check ran
checks.results[].nameCheck identifier — see reference below
checks.results[].displayNameHuman-readable check name
checks.results[].statusHighest severity across all assertions in this check
checks.results[].assertions[].nameAssertion identifier
checks.results[].assertions[].statusok, warning, error, or indeterminate
checks.results[].assertions[].messageHuman-readable explanation

Assertion status meanings

StatusChannel effectMeaning
okContributes to activeAssertion passed
warningChannel → warningIssue detected, messaging may be affected
errorChannel → warningIssue detected, messaging likely affected
indeterminateNo changeCould not run — a dependency assertion failed
Both warning and error assertion statuses produce a channel status of warning. The difference is only visible in the assertion detail — use message to understand severity.

Assertion reference

Channel checks

These run on a schedule and drive the channel status field.
Check: access — "Check MessageBird has the required access"
wabaAccess — Access to WABA
Fetches the WhatsApp Business Account from Meta. All other assertions in this check become indeterminate if this fails.
StatusCause
okWABA is accessible
errorInvalid or expired system user token
errorWABA not found or permissions removed
errorUnexpected Meta API error (including network failures)
appSubscribed — App subscribed to WABA
StatusCause
okBird app is subscribed to the WABA
errorApp is not subscribed, or token is invalid
indeterminatewabaAccess failed — cannot check
accountReviewStatus — Account review status
Meta valueStatus
APPROVEDok
PENDINGerror
REJECTEDerror
unknownindeterminate
businessVerificationStatus — Business verification status
Meta valueMessaging tierStatus
verifiedanyok
not_verified> TIER_250ok
not_verified≤ TIER_250warning
pending_need_more_infoanywarning
pendinganyindeterminate
rejectedanyerror
revokedanyerror
unknownanyindeterminate
phoneAccess — Access to phone number
StatusCause
okPhone number is accessible
errorPhone not found in WABA, or not accessible
errorInvalid or expired system user token
indeterminateMeta API timed out
indeterminatewabaAccess failed — cannot check

Connector config checks

These run when you call POST /status/checks or use the Run Check button in the Bird dashboard. They do not directly change the channel status.
Check: webhooksSubscription — "Check webhooks subscription"
AssertionStatusWhen it fails
Access token validok, errorMeta returns a status other than 200 or 403
Subscribed okok, errorMeta returns 200 but success is false
A fourth check, checkNameStatus, runs only as a precondition during connector installation to verify the access token can read the phone's name status. It does not appear in ongoing check results.