WebhooksAPI

Know the moment a post lands, or does not

Register a URL once and FoPost calls it whenever a delivery settles. Each event carries the post id, the account, the platform, the permalink, or the error text, so your system reacts without polling.

POST /v1/webhooks
curl -X POST https://api.fopost.com/v1/webhooks \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workspaceId": "9b2f6c1e-...",
    "url": "https://yourbrand.com/hooks/social",
    "events": ["post.published", "post.failed"]
  }'

Fires on settle

One event per account delivery, sent as soon as the network confirms or rejects.

Signed

Every request carries a signature header so you can verify it came from us.

Retried

A non-2xx response is retried with backoff before the event is dropped.

Events

Two events cover the whole publish lifecycle

post.published fires when a network accepts a delivery and includes the external id and permalink. post.failed fires when retries are exhausted and includes the platform’s error text. Because a post fans out per account, you get one event per network.

Read the webhook reference
post.published
{
  "event": "post.published",
  "postId": "post_01j8...",
  "workspaceId": "9b2f6c1e-...",
  "delivery": {
    "accountId": "4a71d80b-...",
    "platform": "linkedin",
    "status": "delivered",
    "externalId": "urn:li:share:7301...",
    "externalUrl": "https://linkedin.com/feed/update/..."
  },
  "occurredAt": "2026-09-01T09:00:07Z"
}

post.published

Permalink and external id, ready to store or link back from your CMS.

post.failed

The network’s own error message, so you can fix the cause, not guess.

Per workspace

A webhook belongs to one workspace and only sees that workspace’s posts.

Verify

Trust the payload before you act on it

Each request is signed with the secret returned when you create the webhook. Compute the signature over the raw body, compare it with the header, and reject anything that does not match. Respond 2xx quickly and do the work afterward.

See signature verification
Handler
app.post('/hooks/social', async (req, res) => {
  const signature = req.header(SIGNATURE_HEADER) // header name is in the docs;
  if (!verify(req.rawBody, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).end();
  }
  const { event, postId, delivery } = req.body;
  await queue.add(event, { postId, delivery });
  res.status(200).end();
});

Signature header

Verify with the secret you were given at creation. Rotate by recreating.

Timestamped

occurredAt lets you ignore stale replays and order events correctly.

Idempotent by id

Retries carry the same event id, so a double delivery is easy to drop.

Manage

Create, list, and remove endpoints from code

Webhooks are plain API objects. Create one per environment, list them to audit what is registered, and delete the ones you no longer need. Point them at a staging URL during development and swap to production with one call.

Start building
Automations running on a schedule, on a feed and across networks

List endpoints

GET /v1/webhooks shows every URL and the events it subscribes to.

Per environment

Register a separate URL for staging so test posts never hit production.

webhooks scope

Managing endpoints needs its own scope. A publish-only key cannot add one.

Webhooks questions, answered

Which events are available?

post.published and post.failed. Each fires once per account delivery, so a post to three networks produces up to three events.

How do I verify a webhook?

Create the webhook and store the secret from the response. Compute a signature over the raw request body with that secret and compare it with the signature header on every call.

What if my endpoint is down?

Any non-2xx response or timeout is retried with backoff. Respond 2xx fast and process the event in the background to stay well inside the window.

Can I receive events for one account only?

Every event carries the accountId and platform, so filter on your side. Webhooks are scoped to a workspace, not an individual account.

Can I test without publishing for real?

Point a webhook at a request-capture URL and schedule a post to a test account. The events look identical in every environment.

Do I need webhooks at all?

No. GET /v1/posts/:id/deliveries returns the same status on demand. Webhooks save you the polling.

Build on the Webhooks today

Starting is free and the full API is included. Create a key and make your first call in minutes.

Get your API key