Skip to main content
Subscribe to Autoposting events and receive signed HTTP POST notifications at any URL you control. Use webhooks to trigger CMS updates, Slack alerts, database syncs, or downstream automation — without polling.

Create a Webhook

curl -X POST https://app.autoposting.ai/api-proxy/webhooks \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Pipeline",
    "url": "https://your-server.com/webhooks/autoposting",
    "events": ["post.published", "post.failed", "clip.render.completed"]
  }'
The webhook secret is returned only at creation time. Store it in a secrets manager immediately — if lost, delete the webhook and create a new one.

Event Types

EventTrigger
post.publishedAll targeted platforms succeeded
post.partialSome platforms succeeded, at least one failed
post.failedAll targeted platforms failed
post.scheduledPost saved with a future scheduledAt
post.cancelledScheduled post cancelled before publishing
clip.render.completedRender finished and uploaded
clip.render.failedRender failed — credits not consumed
agent.run.completedAgent run finished successfully
agent.run.failedAgent run failed
token.expiredConnected platform token expired or revoked

Delivery Format

Every delivery is a signed HTTP POST with this JSON envelope:
{
  "id": "evt_01HZ7XABCDEF1234567890",
  "event": "post.published",
  "timestamp": "2025-06-15T14:00:00Z",
  "orgId": "org_id",
  "data": {
    "postId": "post_id",
    "brandId": "brand_id",
    "platforms": ["x", "linkedin"],
    "publishedAt": "2025-06-15T14:00:03Z"
  }
}
Headers on every delivery: X-Autoposting-Event, X-Autoposting-Delivery, X-Autoposting-Signature, X-Autoposting-Timestamp.

Verify Signatures

Autoposting signs every delivery using HMAC-SHA256(secret, "${timestamp}.${rawBody}"). Always verify before processing.
import { createHmac, timingSafeEqual } from "crypto";

function verifyWebhook(payload: string, timestamp: string, signature: string, secret: string) {
  const expected = "sha256=" + createHmac("sha256", secret)
    .update(`${timestamp}.${payload}`)
    .digest("hex");
  return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

app.post("/webhooks/autoposting", express.raw({ type: "application/json" }), (req, res) => {
  const valid = verifyWebhook(
    req.body.toString(),
    req.headers["x-autoposting-timestamp"] as string,
    req.headers["x-autoposting-signature"] as string,
    process.env.WEBHOOK_SECRET!
  );
  if (!valid) return res.status(401).send("Invalid signature");
  const event = JSON.parse(req.body.toString());
  res.status(200).send("OK");
});
Always use timing-safe comparison (timingSafeEqual / hmac.compare_digest). Standard string equality is vulnerable to timing attacks. Reject deliveries where X-Autoposting-Timestamp is more than 5 minutes old to prevent replay attacks.

Retry Behavior

Failed deliveries (non-2xx response, timeout, unreachable) are retried with exponential backoff: ~5 min → 30 min → 2 h → 5 h → 10 h. Webhooks with repeated consecutive failures are auto-disabled. Re-enable after fixing the endpoint:
curl -X PATCH https://app.autoposting.ai/api-proxy/webhooks/:id \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'

Idempotency

Deliveries may arrive more than once in rare cases. Use the id field in the payload as an idempotency key — store processed IDs and discard duplicates.

Posts

Subscribe to post lifecycle events — published, partial, failed.

Clips

Get notified when clip renders complete or fail.

AI Agents

Receive agent run completion and failure events.

API Reference

Full endpoint reference for webhook management.