Connecting accounts
Check token status, granted permissions and sync status for every connected account, and catch disconnects before your users do.
Connected accounts break for reasons outside your control: a password change on the platform, a revoked app, an expired token, a Page role removed. Account health tells you, per account, whether Pozy can still post and read analytics, what is wrong if not, and what to do about it.
#Check every account
GET /v1/accounts/health returns a summary and one row per account. Filter with profileId, platform or status.
curl "https://api.pozy.ai/v1/accounts/health?status=error" \
-H "Authorization: Bearer $POZY_API_KEY"const res = await fetch("https://api.pozy.ai/v1/accounts/health?status=error", {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
for (const a of data.accounts) {
if (a.needsReconnect) console.log(`${a.platform} @${a.username} needs reconnecting: ${a.issues.join("; ")}`);
}resp = requests.get(
"https://api.pozy.ai/v1/accounts/health",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
params={"status": "error"},
timeout=30,
)
for a in resp.json()["accounts"]:
if a["needsReconnect"]:
print(a["platform"], a["username"], a["issues"]){
"summary": { "total": 14, "healthy": 11, "warning": 2, "error": 1, "needsReconnect": 1 },
"accounts": [
{
"accountId": "6651d3a7b2c9e4f1a0b8c7d6",
"platform": "linkedin",
"username": "acme",
"profileId": "6650c1f2a9e4b7d3c8a1f0e2",
"status": "error",
"canPost": false,
"canFetchAnalytics": false,
"tokenValid": false,
"needsReconnect": true,
"issues": ["The access token is no longer valid."],
"disconnectionType": "unintentional",
"unhealthySince": "2026-10-29T18:04:11.000Z",
"analyticsSync": { "status": "failing", "lastSyncedAt": "2026-10-28T06:00:00.000Z" }
}
]
}A profile-scoped key only sees the accounts in its profiles, and the summary counts only those.
#Check one account in detail
GET /v1/accounts/{accountId}/health adds the token details, the scope-by-scope permission list and recommendations.
| Field | What it tells you |
|---|---|
status |
healthy, warning or error. |
tokenStatus |
valid, expiresAt, expiresIn and needsRefresh. Pozy refreshes tokens on its own; this is for diagnosis. |
permissions |
Each scope in the posting, analytics and optional groups with granted and required, plus canPost, canFetchAnalytics and missingRequired. See Scopes. |
issues |
Plain-language problems, ready to show an operator. |
recommendations |
What to do next, for example reconnecting through a specific endpoint. |
analyticsSync |
ok, failing, stalled or never_synced, with lastSyncedAt. A failing or stalled sync raises a healthy account to at least warning. |
messagingRestriction |
Set when the platform has paused messaging on the account, with the platform's code, message and pausedUntil. |
platformConnection |
WhatsApp only: a live check of the number behind the account. See below. |
disconnectReason, disconnectionType, unhealthySince |
Why and since when the account stopped working. |
#What status means
status |
Meaning | Typical action |
|---|---|---|
healthy |
Posting and analytics work. | None. |
warning |
The account works, but something needs attention, for example a failing analytics sync. | Read issues. |
error |
Pozy cannot use the account for at least one core job. | Reconnect, or fix the cause in issues. |
#Meta accounts
For Facebook, Instagram and Threads, Pozy also checks the token live with Meta. Meta sometimes refuses a valid token for a moment, so a refusal does not mark the token invalid if an analytics sync succeeded with it in the last six hours; issues then says the check was inconclusive. Health checks never disconnect an account on their own.
A WhatsApp account's token can be valid while Meta no longer serves the number behind it, for example after the number was disconnected from the WhatsApp Business app on the phone. platformConnection is the live check:
platformConnection.status: "disconnected"sets the overallstatustoerror.inboundWebhookSubscribed: falsemeans incoming messages are not reaching Pozy. It adds an issue and setsstatusto at leastwarning.
For WhatsApp, poll health rather than relying only on the account.disconnected event. See WhatsApp phone numbers.
#How disconnects reach you
account.disconnected fires when an account stops working or is removed. How fast depends on what happened:
| Cause | disconnectionType |
When the event fires |
|---|---|---|
You called DELETE /v1/accounts/{accountId} |
intentional |
Immediately. |
| WhatsApp number disconnected from the phone | unintentional |
Within seconds of Meta's notice. reason carries Meta's explanation. |
| A publish or analytics sync gets a definitive auth error | unintentional |
On that call. For publishing, Pozy tries a token refresh first, so the event means the refresh failed too. |
| Access revoked quietly on the platform side | unintentional |
When Pozy's periodic checks confirm it, from minutes to about a day later. |
Do not treat the absence of account.disconnected as proof an account works. Combine the webhook with a scheduled health check.
#Reconnect an account
Send the user through the connect flow again with reconnectAccountId. The account keeps its id, posts and analytics history.
curl "https://api.pozy.ai/v1/connect/linkedin?profileId=6650c1f2a9e4b7d3c8a1f0e2&reconnectAccountId=6651d3a7b2c9e4f1a0b8c7d6&redirect_url=https://app.example.com/connected" \
-H "Authorization: Bearer $POZY_API_KEY"For standalone ads connections (Google Ads, Reddit Ads), recommendations points to GET /v1/connect/{platform}/ads instead. Its authUrl reconnects the same ads account.
Show a banner in your app for every account with needsReconnect: true. Name the platform and the handle, and add a button that calls your backend to create the reconnect URL.
#Facebook Page events
Lead ads, comments and messages on a Facebook Page arrive through the Page's webhook subscription. If one of them stops while the rest still work, read the subscription live with GET /v1/accounts/{accountId}/webhook-subscription and repair it with POST /v1/accounts/{accountId}/webhook-subscription.
#Disconnect an account
DELETE /v1/accounts/{accountId} disconnects the account and fires account.disconnected with disconnectionType: "intentional". Calling it again for the same account returns 404.
#A daily health job
export async function dailyHealthCheck() {
const res = await fetch("https://api.pozy.ai/v1/accounts/health", {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
const broken = data.accounts.filter((a) => a.status === "error" || a.needsReconnect);
for (const a of broken) {
await notifyOwner(a.profileId, `Your ${a.platform} account @${a.username} needs to be reconnected.`);
}
}notifyOwner is your own code: email, in-app message, or a Slack alert to your support team.
#Webhook events
| Event | When it fires |
|---|---|
account.connected |
Account connected. |
account.disconnected |
Account disconnected. |
account.permissions_changed |
Account permissions changed. |
#Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/accounts/health |
Check accounts health |
GET /v1/accounts/{accountId}/health |
Check account health |
GET /v1/accounts |
List accounts |
DELETE /v1/accounts/{accountId} |
Disconnect account |
GET /v1/accounts/{accountId}/webhook-subscription |
Read a Facebook Page's webhook subscription |
POST /v1/accounts/{accountId}/webhook-subscription |
Re-subscribe a Facebook Page to Pozy's webhooks |