# Review posted (campaign-attributed)

**Event:** `campaign.review_posted`

**Event name:** `campaign.review_posted`

A new review landed at a location with at least one active campaign within the 30-day attribution window. Attribution is location-level. Scope: location-scoped. Delivered as a signed HTTP POST to your Webhooks URL.

Source: https://developer.synup.com/webhooks/campaign-review-posted

## Header parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `X-Synup-Signature` | string | required | sha256=base64(HMAC-SHA256(signing_secret, raw_request_body)). Verify with your signing secret before processing; reject on mismatch. |

## Request body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `event` | string | optional | Dotted event name. |
| `timestamp` | string | optional | ISO-8601 UTC time the event was emitted. |
| `account_id` | integer | optional | Synup account the event belongs to. |
| `location_id` | string | optional | Numeric string for location-scoped events; null for brand-scoped events. |
| `data` | object | optional |  |
| `data.attribution` | string | optional | Always "location_level". |
| `data.recency_window_days` | integer | optional | Attribution window in days (30). |
| `data.review` | object | optional | The posted review: interaction_id, source, author_name, rating (0-5), rating_scale, title, content, permalink, posted_at. |
| `data.campaigns` | array of object | optional | Active campaigns attributed (max 25, newest first): review_campaign_id, name, launched_at. |

## Responses

| Status | Description |
| --- | --- |
| `200` | Your endpoint acknowledges receipt with any 2xx. A non-2xx response or a timeout (>10s) is treated as a failed delivery. |
