ContentStudio
Dark mode
Webhooks: Contract and Publication Checklist

Webhooks: Contract and Publication Checklist

Webhooks

ContentStudio webhooks send signed HTTP POST requests to an endpoint you configure when subscribed events occur. Use webhooks when your integration needs to react to publishing or AI-video job results without polling.

Before you begin

  • Your account must have API access.

  • Your receiving endpoint must use HTTPS.

  • Your endpoint should return a 2xx response within 5 seconds.

  • Treat deliveries as at-least-once. Store each event id and ignore duplicate IDs.

Create a webhook

In ContentStudio, open API and select Webhooks. Create a webhook with:

  • An optional name

  • A required HTTPS payload URL

  • One or more event subscriptions

  • An optional signing secret

  • Optional custom headers

The signing secret is shown only when you create or regenerate it. Save it securely because it cannot be displayed again.

A user can have up to five active webhooks. Webhooks are owned by the user who creates them and can receive events for workspaces that user can access.

Available events

Event

When it is sent

Key result data

post.scheduled

A post is scheduled

Post ID, workspace ID, scheduled time, content, and platform targets

post.published

A post finishes publishing

Final post status: published, failed, or partially_failed; platform-level results and errors when applicable

video.completed

An AI video job reaches completed

Job ID, generated media ID, and final charged credit cost

video.failed

An AI video job reaches failed

Job ID and failure reason

post.published is the publish-completion event. Do not subscribe to separate post-failure events. Check the event payload's post status and platform results instead.

Cancellation of an AI video job does not send a webhook because the caller that cancelled it already has the result.

Delivery format

Every delivery contains a stable top-level event ID, event name, timestamp, workspace ID, and event-specific data. A publishing delivery follows this shape:

{
  "id": "evt_01H...",
  "event": "post.published",
  "timestamp": "2026-10-04T16:30:00Z",
  "workspace_id": "workspace_123",
  "post": {
    "id": "post_123",
    "status": "published",
    "scheduledFor": "2026-10-04T16:00:00Z",
    "publishedAt": "2026-10-04T16:30:00Z",
    "content": "Example post content",
    "platforms": [
      {
        "platform": "linkedin",
        "status": "published",
        "platformPostId": "platform-post-id",
        "publishedUrl": "https://example.com/post",
        "error": null
      }
    ]
  }
}

If post content is too large for a delivery, ContentStudio truncates it and marks the payload with content_truncated: true. Retrieve the complete post through the REST API using the post ID.

Verify signatures

When a signing secret is configured, ContentStudio sends:

  • X-ContentStudio-Signature: lowercase hexadecimal HMAC-SHA256 computed from the raw request body using your webhook secret

  • X-ContentStudio-Event-Id: the same value as the payload id

Verify the signature against the unmodified raw request body before parsing or acting on it. Reject requests with a missing or invalid signature.

Example in Node.js:

import crypto from "node:crypto";

const expected = crypto
  .createHmac("sha256", process.env.CONTENTSTUDIO_WEBHOOK_SECRET)
  .update(rawBody)
  .digest("hex");

const received = req.headers["x-contentstudio-signature"];
const valid = received && crypto.timingSafeEqual(
  Buffer.from(received, "hex"),
  Buffer.from(expected, "hex")
);

If you did not configure a secret, the signature header is not sent. Configure a secret for production endpoints.

Retries, duplicates, and failures

  • Delivery is at-least-once. The same event can be delivered more than once.

  • Return 2xx within 5 seconds to mark a delivery successful.

  • Non-2xx responses, connection failures, and timeouts are retried up to seven times with exponential backoff, capped at 24 hours.

  • After the final unsuccessful attempt, the delivery is dead-lettered and appears in the webhook delivery log.

  • A webhook is not automatically disabled after delivery failures.

  • Webhook delivery never blocks, delays, or changes post publishing.

Build idempotent receivers. Persist the event ID before starting downstream work, and return success for duplicates that you have already processed.

Credits and delivery logs

A successful 2xx delivery consumes one API request credit from the shared API request pool for each receiving webhook. Retries, failed deliveries, dead-lettered deliveries, and test events do not consume an API request credit.

When API request credits are unavailable, ContentStudio skips the delivery and records it as out of credits. Deliveries resume after credits become available. Events missed while a webhook is paused or out of credits are not backfilled.

Open an individual webhook in ContentStudio to review its delivery log. The log shows the event, delivery time, result, response code, payload sent, and response received. Use Send test event to validate an endpoint before relying on it in production.

Production checklist

  1. Use an HTTPS endpoint.

  2. Configure and securely store a signing secret.

  3. Verify the HMAC against the raw body.

  4. Deduplicate by id or X-ContentStudio-Event-Id.

  5. Return 2xx quickly and process long work asynchronously.

  6. Check post.status and per-platform statuses for post.published events.

  7. Monitor delivery logs and API request credits.

Was this article helpful?