Webhooks

Account Webhooks

Events for accounts that connect, disconnect, are about to expire, expire, or lose their authorization.

Keep your account list current, and ask for a reconnect before scheduled posts fail. Each example is the payload's data.

Events

EventFires when
account.connectedAn account connects or reconnects
account.disconnectedAn account is disconnected
account.expiringAn account that cannot auto-renew expires in 7 days
account.expiredThe account's access expired
account.revokedThe platform or the owner withdrew access

After account.expired or account.revoked, the account cannot publish and its posts fail until you reconnect it. A reconnect keeps the id and sends account.connected with reconnected: true.

account.connected

data.object is the whole account, as GET /v1/accounts/{id} returns it, plus reconnected to tell a reconnect from a new connection.

{
  "object": {
    "id": "acc_YOUR_FACEBOOK_ACCOUNT_ID",
    "platform": "facebook",
    "displayName": "Your Brand",
    "handle": "yourbrand",
    "avatarUrl": "https://cdn.onepostly.com/avatars/yourbrand.jpg",
    "status": "active",
    "canAutoRenew": true,
    "tokenExpiresAt": "2027-05-14T10:00:00.000Z",
    "profile": "Default",
    "metadata": {
      "userId": "user_8412"
    },
    "createdAt": "2027-03-01T10:00:00.000Z",
    "updatedAt": "2027-03-01T10:00:00.000Z",
    "reconnected": false
  }
}

reconnected is true when an account is authorized again, such as after expiry. It is false for a new connection, even one after a disconnect.

Use id as accounts[].accountId to publish. List Accounts explains each field. Connecting several accounts at once sends one event each.

metadata is what you sent when you created the connect session. Use it to find the user the account belongs to, even when the browser never reached your redirect. See Link Accounts to Your Users.

account.disconnected

{
  "object": {
    "id": "acc_YOUR_FACEBOOK_ACCOUNT_ID",
    "platform": "facebook",
    "handle": "yourbrand",
    "status": "disconnected",
    "metadata": {
      "userId": "user_8412"
    }
  }
}

handle is the handle at disconnect time, or an empty string. Store it if you need it, since the API no longer returns the account. status is always disconnected, and GET /v1/accounts/{id} returns 404. metadata is what the account carried, which tells you whose account left. The account no longer keeps it.

It fires in these cases.

  • You disconnect the account in the dashboard or with DELETE /v1/accounts/{id}.
  • The owner removes Onepostly in their Facebook, Instagram or Threads settings, or asks the platform to delete their data.
  • A new connection cannot be billed. You get account.connected, then account.disconnected.

Connecting it later sends account.connected with reconnected: false.

account.expiring

data.object is the whole account, as GET /v1/accounts/{id} returns it.

{
  "object": {
    "id": "acc_YOUR_LINKEDIN_ACCOUNT_ID",
    "platform": "linkedin",
    "displayName": "Your Brand",
    "handle": "Your Brand",
    "avatarUrl": "https://cdn.onepostly.com/avatars/yourbrand.jpg",
    "status": "active",
    "canAutoRenew": false,
    "tokenExpiresAt": "2027-04-30T10:00:00.000Z",
    "profile": "Default",
    "metadata": {},
    "createdAt": "2027-03-01T10:00:00.000Z",
    "updatedAt": "2027-03-01T10:00:00.000Z"
  }
}

It fires about 7 days before tokenExpiresAt, only when canAutoRenew is false. An account connected with less time left sends it soon after connecting. It fires once per authorization, and again only after a reconnect.

Ask the owner to reconnect before tokenExpiresAt, or the account turns expired then and its posts fail. account.expired follows on its next use.

account.expired

{
  "object": {
    "id": "acc_YOUR_LINKEDIN_ACCOUNT_ID",
    "platform": "linkedin",
    "handle": "Your Brand",
    "status": "expired",
    "reason": "expired",
    "tokenExpiresAt": "2027-04-30T10:00:00.000Z",
    "previousStatus": "active"
  }
}

account.revoked

{
  "object": {
    "id": "acc_YOUR_TIKTOK_ACCOUNT_ID",
    "platform": "tiktok",
    "handle": "yourbrand",
    "status": "revoked",
    "reason": "token_invalid",
    "tokenExpiresAt": "2027-03-16T09:00:00.000Z",
    "previousStatus": "active"
  }
}

Expired and Revoked Fields

Prop

Type

EventreasonMeaning
account.expiredexpiredThe authorization reached its expiry
account.expiredrefresh_failedThe platform declined to extend it
account.revokedtoken_invalidThe platform rejected it on a request
account.revokedrefresh_revokedIt was withdrawn, such as the owner removing the app
account.revokedauthorization_removedThe platform said it was removed, such as the owner removing the app or the account being deleted

Every reason has the same fix. Reconnect the account. Each event fires once per status change, and a revoked account never moves back to expired.