> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryordinal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# post.publish_failed

> Fired when a post fails to publish

All webhook payloads follow a consistent top-level structure with event-specific data nested within the `data` object.

<ResponseField name="type" type="string" required>
  The event type (e.g. `post.publish_failed`).
</ResponseField>

<ResponseField name="data" type="object" required>
  Event-specific payload for this webhook.

  <Expandable title="Data object parameters">
    <ResponseField name="post" type="object" required>
      The post that failed to publish.

      <Expandable title="Post object parameters">
        <ResponseField name="id" type="string" required>
          Post ID.
        </ResponseField>

        <ResponseField name="title" type="string" required>
          Post title.
        </ResponseField>

        <ResponseField name="channel" type="string" required>
          Channel where publish failed.
        </ResponseField>

        <ResponseField name="error" type="string" required>
          Error message describing the failure.
        </ResponseField>

        <ResponseField name="campaign" type="object | null">
          Campaign if assigned. Contains `id`, `name`, `startDate`, and `endDate`.
        </ResponseField>

        <ResponseField name="url" type="string" required>
          Ordinal post URL.
        </ResponseField>

        <ResponseField name="profile" type="object" required>
          Profile that attempted to publish. Contains `id`, `name`, and `detail`.
        </ResponseField>

        <ResponseField name="scheduledPublishAt" type="string" required>
          ISO 8601 timestamp when publish was attempted.
        </ResponseField>

        <ResponseField name="workspace" type="object" required>
          Workspace the post belongs to. Contains `id`, `slug`, and `name`.
        </ResponseField>

        <ResponseField name="createdBy" type="object" required>
          User who created the post. Contains `id`, `firstName`, `lastName`, and `email`.
        </ResponseField>

        <ResponseField name="failedAt" type="string" required>
          ISO 8601 timestamp when the publish failed.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="createdAt" type="string" required>
  ISO 8601 timestamp when the webhook event was created.
</ResponseField>

<ResponseExample>
  ```json Example theme={null}
  {
    "type": "post.publish_failed",
    "data": {
      "post": {
        "id": "550e8400-e29b-41d4-a716-446655440001",
        "title": "Q4 Product Launch Announcement",
        "channel": "LinkedIn",
        "error": "Token expired",
        "campaign": null,
        "url": "https://app.tryordinal.com/acme/posts/550e8400-e29b-41d4-a716-446655440001",
        "profile": {
          "id": "550e8400-e29b-41d4-a716-446655440002",
          "name": "Acme Inc",
          "detail": "acme-inc"
        },
        "scheduledPublishAt": "2025-03-01T14:00:00.000Z",
        "workspace": {
          "id": "550e8400-e29b-41d4-a716-446655440000",
          "slug": "acme",
          "name": "Acme Inc"
        },
        "createdBy": {
          "id": "550e8400-e29b-41d4-a716-446655440010",
          "firstName": "Jane",
          "lastName": "Doe",
          "email": "jane@example.com"
        },
        "failedAt": "2025-03-01T14:00:05.000Z"
      }
    },
    "createdAt": "2025-03-01T14:00:05.000Z"
  }
  ```
</ResponseExample>
