# post.approved

> Sent when a post is approved or added already approved, with the post and, when it has a creator, the creator's profile.

Breadcrumb: Webhooks › post.approved · Updated: 2026-11-04
Docs index: https://docs.cevoid.com/developers/llms.txt

Use it to reward creators once their content is cleared for use, for example with loyalty points in another system.

## When it fires

- When a post is approved in the inbox, one at a time or in bulk.
- When a post is added already approved, such as a workspace upload or an auto-approved Instagram or TikTok import.
- Saving a post that is already approved sends nothing.
- If a post is set back to pending and approved again, it fires again with a new `id`. To act once per post, deduplicate on `data.post.id`.
- `profile` is there only when the post has a creator. Most Instagram and TikTok imports have none.

## Receive it

Pick `post.approved` in a webhook destination's events, or tick All events. See [Create a destination](https://docs.cevoid.com/developers/webhooks/set-up.md#create-a-destination).

To filter it or wait before sending, send it from a Flow on the _Post approved_ trigger instead. See [Send from a Flow](https://docs.cevoid.com/developers/webhooks/set-up.md#send-from-a-flow).

## Payload

```json title="Example payload"
{
  "created_at": "2026-11-02T09:30:00.000Z",
  "data": {
    "post": {
      "added_by_workspace": false,
      "alt": "Person wearing a linen shirt",
      "caption": "Summer outfit",
      "created_at": "2026-08-01T10:00:00.000Z",
      "custom_link": {
        "description": "Explore the complete look.",
        "image_url": "https://cdn.cevoid.com/links/summer.jpg",
        "title": "Shop the summer edit",
        "url": "https://shop.example.com/summer"
      },
      "hide_caption": false,
      "id": "pst_summerlook",
      "labels": [
        "lbl_summer",
        "lbl_featured"
      ],
      "language": "en",
      "media": {
        "aspect_ratio": 1.25,
        "blurhash": "LEHV6nWB2yk8pyo0adR*.7kCMdnj",
        "duration_seconds": 12.5,
        "filename": "summer-look.jpg",
        "has_audio": true,
        "sprite_url": "https://cdn.cevoid.com/posts/pst_summerlook-sprite.jpg",
        "thumbnail_url": "https://cdn.cevoid.com/posts/pst_summerlook-thumbnail.jpg",
        "url": "https://cdn.cevoid.com/posts/pst_summerlook.jpg"
      },
      "origin": {
        "type": "INSTAGRAM_TAGGED"
      },
      "posted_at": "2026-08-01T09:00:00.000Z",
      "profile_id": "prf_sarah",
      "source": {
        "external_id": "18000000000000000",
        "platform": "INSTAGRAM",
        "posted_at": "2026-08-01T09:00:00.000Z",
        "url": "https://www.instagram.com/p/example/",
        "username": "sarah.lifestyle"
      },
      "status": "APPROVED",
      "tagged_products": [
        {
          "product_id": "prd_abc123def456gh",
          "x": 0.35,
          "y": 0.65
        }
      ],
      "type": "VIDEO",
      "updated_at": "2026-08-02T10:00:00.000Z",
      "video_captions": "WEBVTT\n\n00:00.000 --> 00:02.000\nSummer outfit.",
      "video_description": "A person shows a summer outfit."
    },
    "profile": {
      "avatar_url": "https://cdn.cevoid.com/avatars/prf_sarah/profile.jpg",
      "bio": "Lifestyle creator and photography enthusiast",
      "birthday": "1992-04-18",
      "country": "US",
      "created_at": "2026-01-15T09:30:00.000Z",
      "email": "sarah.johnson@example.com",
      "external_id": "customer_7391056823401",
      "first_name": "Sarah",
      "id": "prf_sarah",
      "language": "en",
      "last_name": "Johnson",
      "location": "San Francisco, CA",
      "name": "Sarah Johnson",
      "notes": "VIP customer; prefers email communication",
      "social_instagram_handle": "sarah.lifestyle",
      "social_tiktok_handle": "sarah.creates",
      "social_x_handle": "sarah_j",
      "updated_at": "2026-01-20T14:22:15.000Z"
    }
  },
  "id": "evt_m3p82kdq5xw7tz4c",
  "type": "post.approved",
  "version": 1
}
```

- `version` (`number`, required): The version of this event type. A published version only gains fields, so ignore fields you do not use; a breaking change is a new version.
- `id` (`string`, required): Stable event id (`evt_` plus 16 characters), also sent as the `webhook-id` header. Retries and manual replays send the same id, so ignore an event whose id you have already processed.
- `type` (`string`, required): What `data` describes. New types are added over time, and an endpoint on "All events" receives them, so ignore any type you do not handle.
- `created_at` (`string<date-time>`, required): When the event happened, as an ISO 8601 timestamp.
- `origin` (`object`): Why your endpoint received the event. Omitted when the event was forwarded without a Flow of your own.
  - `origin.flow` (`object`, required): The Flow that sent the event.
    - `origin.flow.id` (`string`, required): The Flow id, shown in the Flow URL.
    - `origin.flow.name` (`string`, required): The Flow name at the time of sending.
  - `origin.trigger` (`string`, required): The event that started the Flow. One of `order.fulfilled`, `order.delivered`, `product-review.submitted`, `company-review.submitted`, `product-review.replied`, `company-review.replied`, `upload.completed`, `post.approved`, `profile.program-joined`, `profile.program-left`, `tier.earned`, `reward.fulfilled`, `tier.evaluation-approaching`, `points.expiration-approaching`.
- `data` (`object`, required): The resources the event carries, keyed by resource name. `type` decides which resources are included, and resources your plan does not include are left out.
  - `data.post` (`object`)
    - `data.post.id` (`string`, required): Cevoid post ID.
    - `data.post.profile_id` (`string`): Cevoid profile ID for the contributor, when known.
    - `data.post.added_by_workspace` (`boolean`, required): Whether the post was added by the workspace rather than a profile.
    - `data.post.custom_username` (`string`): Post-specific display-name override, when set.
    - `data.post.type` (`string`, required): Primary media type. One of `IMAGE`, `VIDEO`.
    - `data.post.status` (`string`, required): Moderation state. One of `APPROVED`, `PENDING`, `DECLINED`, `REMOVED`, `NONE`.
    - `data.post.media` (`object`, required)
      - `data.post.media.url` (`string<uri>`, required): Delivery URL for the media asset.
      - `data.post.media.thumbnail_url` (`string<uri>`): Smaller preview image when available.
      - `data.post.media.sprite_url` (`string<uri>`): Video sprite image for timeline previews when available.
      - `data.post.media.blurhash` (`string`): BlurHash placeholder for the media asset.
      - `data.post.media.filename` (`string`): Original filename, when available.
      - `data.post.media.aspect_ratio` (`number`): Width divided by height.
      - `data.post.media.duration_seconds` (`number`): Video duration in seconds.
      - `data.post.media.has_audio` (`boolean`): Whether video media includes an audio track.
    - `data.post.caption` (`string`): Contributor caption.
    - `data.post.hide_caption` (`boolean`, required): Whether clients should hide the caption.
    - `data.post.language` (`string`): IETF BCP 47 language tag for the caption.
    - `data.post.alt` (`string`): Alternative text for the media.
    - `data.post.video_captions` (`string`): WebVTT captions for video media.
    - `data.post.video_description` (`string`): Accessible description of video content.
    - `data.post.source` (`object`)
      - `data.post.source.platform` (`string`, required): External platform where the post originated. One of `INSTAGRAM`, `TIKTOK`.
      - `data.post.source.carousel_index` (`integer`): Zero-based position within the source carousel. Omitted for standalone posts or unknown positions. Group slides by platform and external_id when available.
      - `data.post.source.username` (`string`): Source account username when stored with the post.
      - `data.post.source.external_id` (`string`): Post identifier from the external platform.
      - `data.post.source.url` (`string<uri>`): Original public post URL.
      - `data.post.source.posted_at` (`string<date-time>`): ISO 8601 timestamp when the external post was published.
    - `data.post.origin` (`object`)
      - `data.post.origin.type` (`string`, required): How the post entered the workspace. Omitted when the origin is unknown. One of `INSTAGRAM_FEED`, `INSTAGRAM_HASHTAG`, `INSTAGRAM_TAGGED`, `INSTAGRAM_MENTIONED`, `TIKTOK_FEED`, `CEVOID_GENERAL`, `CEVOID_CUSTOM`, `WORKSPACE_UPLOADS`, `WORKSPACE_COPIES`, `WORKSPACE_IMPORTS`, `ACTIVITIES`.
    - `data.post.custom_link` (`object`)
      - `data.post.custom_link.url` (`string<uri>`, required): Destination URL.
      - `data.post.custom_link.title` (`string`, required): Link title.
      - `data.post.custom_link.description` (`string`): Link description.
      - `data.post.custom_link.image_url` (`string<uri>`): Link preview image.
    - `data.post.labels` (`string[]`, required): Cevoid label IDs assigned to the post.
    - `data.post.tagged_products` (`object[]`, required)
      - `data.post.tagged_products[].product_id` (`string`, required): Cevoid product ID.
      - `data.post.tagged_products[].x` (`number`): Normalized horizontal position.
      - `data.post.tagged_products[].y` (`number`): Normalized vertical position.
    - `data.post.posted_at` (`string<date-time>`, required): Effective content date. Uses the stored posted date, falling back to the Instagram date, TikTok date, then creation date for legacy posts. Does not change list ordering.
    - `data.post.created_at` (`string<date-time>`, required): ISO 8601 timestamp when the Post was created.
    - `data.post.updated_at` (`string<date-time>`, required): ISO 8601 timestamp when the Post was last updated.
  - `data.profile` (`object`)
    - `data.profile.id` (`string`, required): Cevoid profile ID.
    - `data.profile.external_id` (`string`): Identifier this profile carries in the workspace source system, when known.
    - `data.profile.name` (`string`): Display name of the profile.
    - `data.profile.first_name` (`string`): First name of the profile.
    - `data.profile.last_name` (`string`): Last name of the profile.
    - `data.profile.email` (`string`): Email address for the profile.
    - `data.profile.avatar_url` (`string`): Profile image URL.
    - `data.profile.country` (`string`): Country code associated with the profile.
    - `data.profile.language` (`string`): Preferred language code associated with the profile.
    - `data.profile.location` (`string`): Free-form location associated with the profile.
    - `data.profile.social_instagram_handle` (`string`): Instagram handle associated with the profile.
    - `data.profile.social_tiktok_handle` (`string`): TikTok handle associated with the profile.
    - `data.profile.social_x_handle` (`string`): X handle associated with the profile.
    - `data.profile.birthday` (`string<date>`): Birthday in YYYY-MM-DD format.
    - `data.profile.bio` (`string`): Profile biography text.
    - `data.profile.notes` (`string`): Merchant notes about the profile.
    - `data.profile.created_at` (`string<date-time>`, required): ISO 8601 timestamp when the profile was created.
    - `data.profile.updated_at` (`string<date-time>`, required): ISO 8601 timestamp when the profile was last updated.

## Related articles

- [content-upload-request.created](https://docs.cevoid.com/developers/webhooks/content-upload-request-created.md) (Flow only)
- [Event types](https://docs.cevoid.com/developers/webhooks/event-types.md)
- [Webhooks via Flows](https://docs.cevoid.com/flows/webhooks.md)

---

Canonical: https://docs.cevoid.com/developers/webhooks/post-approved
