Sign inGet Started

List WhatsApp Business Accounts

GET
/v1/whatsapp/business-accounts
for await (const account of bird.whatsapp.businessAccounts.list()) {
  console.log(account.id, account.name, account.status);
}
Response200
{
  "data": [
    {
      "id": "waa_01krdgeqcxet5s7t44vh8rt9mg",
      "waba": "102290129340398",
      "name": "Acme Inc",
      "status": "active",
      "account_review_status": "approved",
      "business_verification_status": "verified",
      "marketing_messages_onboarding_status": "onboarded",
      "portfolio": {
        "meta_id": "178563218361309",
        "name": "Acme Holdings",
        "marketing_messages_onboarding_status": "not_started"
      },
      "ban": {
        "state": "disabled",
        "occurred_at": "2026-04-10T09:12:00Z",
        "appeal_url": "https://business.facebook.com/business-support-home/178563218361309/102290129340398"
      },
      "meta_health_status": {
        "can_send_message": "blocked",
        "entities": [
          {
            "entity_type": "waba",
            "meta_id": "1028574859896003",
            "can_send_message": "blocked",
            "errors": [
              {
                "error_code": 141006,
                "error_description": "There is an error with the payment method. This will block business initiated conversations.",
                "possible_solution": "There was an error with your payment method. Please add a new payment method to the account."
              }
            ]
          },
          {
            "entity_type": "business",
            "meta_id": "4392746181043198",
            "can_send_message": "limited",
            "errors": [
              {
                "error_code": 141010,
                "error_description": "The Business has not passed business verification.",
                "possible_solution": "Visit business settings and start or resolve the business verification request."
              }
            ]
          },
          {
            "entity_type": "app",
            "meta_id": "497937228432800",
            "can_send_message": "available"
          }
        ]
      }
    }
  ],
  "next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
Returns a paginated list of the WhatsApp Business Accounts your workspace has connected, so you can choose which one a template belongs to. Only accounts whose setup finished are listed: an account appears once WhatsApp has reported its name and at least one of its phone numbers has finished connecting. Page through the full set with the cursors the response returns.
Each account also carries the state WhatsApp last reported for it. That covers its own status, how far WhatsApp's review of it has got, whether Meta has verified the business behind it, the Meta business portfolio that owns it, and ban on an account WhatsApp has banned. These are the same fields Get a WhatsApp Business Account returns, and that operation documents them.
Query Parameters
sort
string
Field to sort by.
Possible values: created_at
order
string
Sort direction. Defaults to desc, which sorts from newest to oldest or largest to smallest, depending on the selected sort field.
Possible values: asc, desc
limit
integer
Maximum number of items to return per page.
starting_after
string
Cursor from the next_cursor field of a previous list response. Returns items immediately after the cursor position in the current sort order.
ending_before
string
Cursor from the prev_cursor or refresh_cursor field of a previous list response. Returns items immediately before the cursor position in the current sort order. prev_cursor returns the preceding page. refresh_cursor anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since.
Response Payload
data
array of object
required
The WhatsApp Business Accounts your workspace has connected.
Show child attributes
data.id
string
required
Unique identifier for the WhatsApp Business Account.
data.waba
string
required
Meta's own identifier for this WhatsApp Business Account. This is the value to send when creating a template on the account.
data.name
string
required
The account's name, as WhatsApp reports it.
data.status
string
required
WhatsApp's own state for this account as of meta_synced_at. The status is active until WhatsApp reports otherwise. WhatsApp already considers an account usable if Bird could connect a number under it. The absence of a reading is therefore not evidence of another state.
data.account_review_status
string
How far WhatsApp's review of this account had got as of meta_synced_at. Absent until WhatsApp has reported it.
data.business_verification_status
string
Whether Meta had verified the business behind this account as of meta_synced_at. Absent until Meta has reported it.
data.marketing_messages_onboarding_status
string
Whether this account can use WhatsApp's Marketing Messages API, as of meta_synced_at. Absent until WhatsApp has reported it. Distinct from the owning portfolio's marketing_messages_onboarding_status (portfolio.marketing_messages_onboarding_status), which Meta gives the same field name but a different vocabulary: this one is the account's own eligibility, that one is the portfolio's Terms-of-Service progress.
data.portfolio
object
The Meta business portfolio that owns this account. Absent until Meta has reported it. The portfolio is where a messaging limit is set, so every account it owns shares one.
Show child attributes
data.portfolio.meta_id
string
required
Meta's identifier for the portfolio. Treat it as an opaque string.
data.portfolio.name
string
The portfolio's name, as Meta reports it. Absent when Meta returned none.
data.portfolio.marketing_messages_onboarding_status
string
How far this portfolio has got through Meta's Marketing Messages terms of service. Absent until Meta has reported it. Distinct from the account's own marketing_messages_onboarding_status, which Meta gives the same field name but a different vocabulary: that one is the account's own eligibility, this one is the portfolio's Terms-of-Service progress.
data.ban
object
WhatsApp's ban on this account, absent unless Bird was told of one. status is what the account said when Bird last read it; this is what WhatsApp announced, which arrives only on the webhook that announces it and is never re-read.
Show child attributes
data.ban.state
string
required
data.ban.occurred_at
string
required
When WhatsApp reported the ban, by WhatsApp's own clock. Bird can learn of a ban later than this, so it is not when Bird recorded it.
data.ban.appeal_url
string
Where to appeal WhatsApp's decision with Meta Business Support, because neither Bird nor this API can lift one. Absent when Bird does not know the account's Meta business portfolio, since there is no support-home path to build without one.
data.meta_health_status
object
Meta's own messaging health for this account as of meta_synced_at. Absent until Bird has read it, and absent again when the stored reading did not parse at all. An entity whose verdict falls outside this vocabulary is dropped on its own and the rest of the report still ships, so entities can be shorter than Meta's. A blocked verdict on the waba entity is why template sends fail with Meta's #200 even though the number reads active: for example error_code 141006 names a payment method Meta rejected on the account.
Show child attributes
data.meta_health_status.can_send_message
string
required
data.meta_health_status.entities
array of object
required
One entry per node Meta evaluated. Order is Meta's.
Show child attributes
data.meta_health_status.entities.entity_type
string
required
data.meta_health_status.entities.meta_id
string
required
Meta's identifier for the node. Treat it as an opaque string.
data.meta_health_status.entities.can_send_message
string
required
Whether this node lets messages through.
data.meta_health_status.entities.can_receive_call_sip
string
Whether this node can receive a WhatsApp call over SIP, which Meta reports on phone_number and app entities. Absent on an account read: Meta reports it only when a phone number or template is the node asked about.
data.meta_health_status.entities.additional_info
array of string
Meta's own notes on a limited verdict. Absent on an account read: Meta reports it only when a phone number or template is the node asked about.
data.meta_health_status.entities.errors
array of object
Why this node is not available. Absent when Meta gave no reason.
Show child attributes
data.meta_health_status.entities.errors.error_code
integer
required
Meta's numeric health error code, for example 141006 (payment method error), 141010 (business not verified), 141014 (account banned).
data.meta_health_status.entities.errors.error_description
string
required
Meta's own sentence describing the block.
data.meta_health_status.entities.errors.possible_solution
string
Meta's own suggested remedy. Absent when Meta gave none.
data.meta_synced_at
string
When Bird last read this account's state from WhatsApp. status, account_review_status, business_verification_status, marketing_messages_onboarding_status, portfolio and meta_health_status are all that reading rather than live values; Bird re-reads roughly hourly. Absent for an account Bird has never read back.
data.created_at
string
required
When this account was connected.
data.updated_at
string
required
When this account was last changed.
next_cursor
nullable string
required
Cursor for the next page. Pass back as starting_after to advance forward. null when no next page exists.
prev_cursor
nullable string
required
Cursor for the previous page. Pass back as ending_before to step backward. null when no previous page exists.
refresh_cursor
nullable string
required
Refresh anchor, the first row of this response. Pass back as ending_before to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-null whenever data is non-empty; null only on an empty page. Distinct from prev_cursor.