Events

Every webhook event FoPost can send, when it fires, and its payload.

Seventeen events, in five families. Subscribe to delivery.* when you want per-account granularity, post.* when you only care about the overall outcome. Subscribing to both means two notifications for the same publish, which is fine as long as your handler expects it.

Posts

EventFires when
post.scheduledA post was put on the calendar, by hand, by an approval, by a bulk import or by an automation. Rescheduling fires it again
post.publishedEvery account on the post published successfully
post.partially_failedSome accounts published, some did not
post.failedNo account published (failed and cancelled deliveries both count)
post.deletedA post was deleted. Any delivery still pending was cancelled with it

The three outcome events fire once per post, when every account has a final status. data carries the post and its status:

{ "postId": "7d2b8c11-…", "status": "published" }

post.scheduled adds scheduleAt; post.deleted carries only postId.

Delivery outcomes

One event per account on the post.

EventFires when
delivery.publishedOne account published. Fires once per account
delivery.failedOne account will not publish, after its retries, or immediately when the failure is final, such as expired credentials or an error the platform will never accept
delivery.delayedOne delivery was held by a platform rate limit and will retry at retryAt

delivery.published data:

{ "postId": "…", "postAccountId": "…", "accountId": "…", "platform": "linkedin", "externalUrl": "https://…" }

externalUrl is the live post when the platform reports one, and null when it does not.

delivery.failed swaps externalUrl for errorCode and errorMessage; delivery.delayed carries reason: "platform_rate_limit", a message, and retryAt. Ordinary retry backoff between attempts does not emit delivery.delayed; only a platform rate limit does.

Accounts

EventFires when
account.connectedA social account was connected to the workspace
account.disconnectedA social account was disconnected
account.health_changedA connected account's credential health changed: degraded, expired, revoked, or recovered

account.connected and account.disconnected carry the account:

{ "accountId": "…", "platform": "instagram", "username": "yourbrand" }

account.health_changed adds the transition:

{ "accountId": "…", "platform": "instagram", "username": "yourbrand", "previousStatus": "healthy", "newStatus": "expired" }

This is the one worth wiring even if you skip the rest. It is how you learn a token died before a scheduled post silently fails. It fires on recovery too, so you can close the alert it opened. When the change comes from a failed token refresh rather than a health check, the payload carries a reason instead of a username.

Inbox

One event per new inbound item, as the inbox poll picks it up. Your own replies never fire one.

EventFires when
inbox.comment_receivedSomeone commented on one of your posts
inbox.mention_receivedSomeone mentioned one of your accounts
inbox.message_receivedA direct message arrived
inbox.review_receivedA review or Page recommendation arrived
{ "itemId": "…", "type": "comment", "platform": "instagram", "accountId": "…", "receivedAt": "2026-09-01T09:00:12.000Z" }

The payload is ids only. Fetch the item from the inbox for its text and author, so nothing a customer wrote sits in your webhook logs. Building a bot on inbox.message_received? The chat adapter does the verify-and-fetch half for you.

Automations

EventFires when
automation.triggeredA run started
automation.completedA run finished every step
automation.failedA run stopped on an error
{ "automationId": "…", "runId": 4821, "totalSteps": 3 }

automation.triggered carries automationId and runId; automation.completed adds totalSteps; automation.failed adds error.

The envelope

Every delivery is the same three-key body:

{ "event": "<name>", "data": { … }, "timestamp": "<ISO 8601>" }

timestamp is when the event was queued. The delivery id lives in the X-FoPost-Delivery header. Deduplicate on that, since a retried delivery repeats the identical body. Ids in data are the same public ids the API uses, so a webhook payload can be followed with a GET.

Next

Related documentation
  • Webhooks

    Hear about publishing outcomes and account health without polling.

  • Verifying Signatures

    Prove a delivery came from FoPost before acting on it.

  • Retries and Failures

    Timeouts, retry backoff, auto-disable, and test deliveries.

  • Inbox

    Comments, mentions and reviews from every connected account, in one list.

  • Chat Adapter

    Plug the FoPost inbox into a chatbot framework as one send/receive channel.

  • API Overview

    Base URL, envelopes, pagination, and errors for the FoPost REST API.

Was this helpful?

On this page