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

sortstring

Field to sort by.

Possible values: created_at

orderstring

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

limitinteger

Maximum number of items to return per page.

starting_afterstring

Cursor from the next_cursor field of a previous list response. Returns items immediately after the cursor position in the current sort order.

ending_beforestring

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.

Continue with the documentation, guides and examples for this topic.