---
title: "Check account health"
method: GET
path: "/v1/accounts/{accountId}/health"
tags: ["Accounts"]
---

# Check account health

`GET /v1/accounts/{accountId}/health`

Returns detailed health info for a specific account including token status, permissions, and recommendations.

For WhatsApp accounts the response also includes `platformConnection`, a live probe of the
Meta link behind the channel (the same read as `GET /v1/whatsapp/number-info`). The OAuth
token can be perfectly valid while Meta refuses to serve the phone-number object (for
example after a phone-side coexistence disconnect), so `tokenStatus` alone is not a
liveness signal for WhatsApp. When the Meta link is dead, `platformConnection.status` is
`disconnected` and the overall `status` is `error`. When Meta reports that the number's
inbound message webhook does not reach Zernio, `platformConnection.inboundWebhookSubscribed`
is `false`, an entry is added to `issues`, and the overall `status` is at least `warning`.

## Path parameters

- `accountId` string, required

## Response `200`

Account health details

- object
  - `accountId` string
  - `platform` string
  - `integrationLane` 'business' | 'developer' — TikTok only. The TikTok integration the account is connected through: business (TikTok for Business, Accounts API) or developer (the original integration). Absent on other platforms.
  - `username` string
  - `displayName` string
  - `status` 'healthy' | 'warning' | 'error' — Overall health status
  - `tokenStatus` object
    - `valid` boolean — Whether the token is valid
    - `expiresAt` string, date-time
    - `expiresIn` string — Human-readable time until expiry
    - `needsRefresh` boolean — Whether token expires within 24 hours
  - `permissions` object
    - `posting` object[]
      - `scope` string
      - `granted` boolean
      - `required` boolean
    - `analytics` object[]
      - `scope` string
      - `granted` boolean
      - `required` boolean
    - `optional` object[]
      - `scope` string
      - `granted` boolean
      - `required` boolean
    - `canPost` boolean
    - `canFetchAnalytics` boolean
    - `missingRequired` string[]
  - `issues` string[] — List of issues found
  - `recommendations` string[] — Actionable recommendations to fix issues
  - `messagingRestriction` object, nullable — Observed from Meta's own error subcodes on our own sends (2534122, 1893063, 2534029), not a live probe. Set on the first refused send and cleared when a later send succeeds, so it lags reality by one send in each direction.
    - `subcode` integer
    - `message` string
    - `firstSeenAt` string, date-time
    - `lastSeenAt` string, date-time
  - `platformConnection` object — WhatsApp accounts only. Live probe of the Meta link behind the channel, performed at request time (the same read as GET /v1/whatsapp/number-info).
    - `status` 'connected' | 'disconnected' | 'unknown' — `connected` = Meta served the channel object. `disconnected` = Meta refused to serve it (Graph error 100, subcode 33), which is how a phone-side coexistence disconnect surfaces. `unknown` = the live read failed for another reason (timeout, transient Meta error), not evidence either way.
    - `checkedAt` string, date-time — When this live probe ran (always the current request; never cached)
    - `phoneStatus` string, nullable — Meta's own `status` field from the phone-number node (for example CONNECTED), when the object was readable
    - `metaError` object, nullable — Set only when status is `disconnected`
      - `code` integer — Meta Graph error code (100)
      - `subcode` integer — Meta Graph error subcode (33)
      - `message` string
    - `inboundWebhookSubscribed` boolean, nullable — From the phone number's Meta health_status. `false` = Meta says Zernio is not subscribed to the message webhook for this number, so inbound messages are not delivered even though the number is CONNECTED and can still send. Fix by re-subscribing (reconnect the number); if it stays `false`, the number is routed to a different WhatsApp Business Account (typically after linking it to a Facebook Page). `true` = Meta reports no such problem. `null` = Meta did not report it (read failed or no health_status), not evidence either way.

## Other responses

- `400` — Invalid request
- `401` — Unauthorized
- `404` — Resource not found

## Changes

- **2026-09-25** `2c04683ce694` — 4 info
  - added the optional property `details/adAccountId` to the response with the `400` status
  - added the optional property `details/createdObjects` to the response with the `400` status
  - added the optional property `details/stage` to the response with the `400` status
  - added the optional property `details/unconfirmedWrite` to the response with the `400` status
- **2026-09-25** `a0d8f21b5abe` — 1 info
  - added the optional property `platformConnection/inboundWebhookSubscribed` to the response with the `200` status
- **2026-09-18** `eded32b62823` — 1 info
  - added the optional property `integrationLane` to the response with the `200` status
- **2026-09-16** `3e6ddf2a99ea` — 1 info
  - added the optional property `details/budgetScope` to the response with the `400` status
- **2026-09-15** `0dba7d004d75` — 2 info
  - added the optional property `details/quotaExhausted` to the response with the `400` status
  - added the optional property `details/quotaScope` to the response with the `400` status

[Full history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/accounts/:accountId/health/get.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/b2325332041a?raw)
