Synup · AsyncAPI Specification

Synup Webhooks

Version

View Spec View on GitHub Local MarketingListings ManagementReputation ManagementLocal SEOReviewsSocial-MediaAnalyticsBusiness ListingsReview ManagementAgency SoftwareAsyncAPIWebhooksEvents

AsyncAPI Specification

Raw ↑
name: Synup webhook event catalog
generated: '2026-08-13'
method: searched
source: https://developer.synup.com/synup-webhooks-doc-2259000
description: Synup publishes 43 account webhook events as OpenAPI 3.1 webhook documents (one page per
  event) plus a delivery guide. There is no AsyncAPI document — this catalog and openapi/synup-webhooks-openapi.yml
  are the machine-readable capture. Payload schemas are verbatim provider content and live in the OpenAPI
  file.
spec: openapi/synup-webhooks-openapi.yml
asyncapi_published: false
delivery:
  transport: HTTPS POST with a JSON body
  subscription_model: account-wide; a single Webhooks URL per account receives every event — there is
    no per-event subscription
  configuration: Synup workspace -> Settings -> Notifications -> Configure Webhooks
  endpoint_requirements:
  - HTTPS only, plain HTTP rejected
  - Publicly resolvable host; loopback, RFC-1918, link-local and cloud metadata IPs are refused
  - Respond within 10 seconds
  - Be duplicate-tolerant — de-duplicate on the stable IDs inside data
  ack: Return 2xx to acknowledge; any non-2xx or timeout is a failed attempt
  ordering: not guaranteed
  retries: Synup records attempt count, last attempt time and HTTP response code per delivery
  gates:
  - webhooks feature enabled on the account
  - a Webhooks URL is set
  - a signing secret has been generated
  - the endpoint has passed verification
security:
  signature_header: X-Synup-Signature
  algorithm: sha256=base64(HMAC-SHA256(signing_secret, raw_request_body))
  verification_guidance:
  - Use the raw request body bytes; re-serializing parsed JSON breaks the HMAC
  - Compare in constant time
  - Reject with 401 on mismatch
  secret_rotation: Regenerating the secret invalidates the old one immediately and resets verified status;
    changing the Webhooks URL also resets it
  handshake:
    event: endpoint.verification
    request: '{"event":"endpoint.verification","nonce":"<random hex>","timestamp":"<ISO-8601 UTC>"}'
    expected_response: HTTP 200 whose body is HMAC-SHA256(secret, nonce) as a lowercase hex string (a
      JSON-quoted hex string is also accepted)
envelope:
  event: string — the dotted event name
  timestamp: ISO-8601 UTC datetime the event was emitted
  account_id: integer — the Synup account
  location_id: string | null — numeric string for location-scoped events, null for brand-scoped events
  data: object — event-specific payload
  agency_account_id: integer — present only when the account is managed by a parent agency account
  scope: string — present only on AI post idea events; "local" or "social"
event_count: 43
event_groups:
- prefix: campaign
  events: 6
- prefix: connection
  events: 6
- prefix: endpoint
  events: 1
- prefix: idea
  events: 2
- prefix: idea_image
  events: 2
- prefix: idea_pipeline
  events: 2
- prefix: idea_series
  events: 1
- prefix: interaction
  events: 2
- prefix: listing
  events: 1
- prefix: profile
  events: 3
- prefix: rankings
  events: 2
- prefix: review_analytics
  events: 2
- prefix: social_connection
  events: 4
- prefix: social_post
  events: 9
events:
- event: campaign.feedback_submitted
  summary: Campaign feedback submitted
  scope: location
  description: 'A customer submitted a rating/feedback on the campaign''s review-funnel page. Scope: location-scoped.
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: campaign.recipients_added
  summary: Campaign recipients added
  scope: location
  description: 'A batch of customers was enrolled into a campaign. Scope: location-scoped. Delivered as
    a signed HTTP POST to your Webhooks URL.'
- event: campaign.review_posted
  summary: Review posted (campaign-attributed)
  scope: location
  description: '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.'
- event: campaign.send_rejected
  summary: Campaign message send rejected
  scope: location
  description: 'A message could not be sent (insufficient credits, invalid contact, or provider rejection).
    Scope: location-scoped. Delivered as a signed HTTP POST to your Webhooks URL.'
- event: campaign.sent
  summary: Review campaign sent
  scope: location
  description: 'A campaign was launched and invites started going out. Scope: location-scoped. Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: campaign.status_change
  summary: Campaign message status changed
  scope: location
  description: 'A recipient''s message engagement changed (delivered / opened / clicked / bounced / dropped
    / unsubscribed). Scope: location-scoped. Delivered as a signed HTTP POST to your Webhooks URL.'
- event: connection.google_verification_failed
  summary: Google verification failed
  scope: location
  description: 'A Google Business Profile verification reached a terminal failure (suspended, duplicate,
    or fetch error). In-progress states do not fire. Scope: location-scoped. Delivered as a signed HTTP
    POST to your Webhooks URL.'
- event: connection.google_verification_verified
  summary: Google verification passed
  scope: location
  description: 'A location''s Google Business Profile passed verification. Scope: location-scoped. Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: connection.listing_inaccessible
  summary: Listing became inaccessible
  scope: location
  description: 'The connected account can no longer access the location''s listing (access lost even though
    credentials may still be valid). Scope: location-scoped. Delivered as a signed HTTP POST to your Webhooks
    URL.'
- event: connection.location_connected
  summary: Listing connected
  scope: location
  description: 'A Google or Facebook listing is newly linked to a location. Scope: location-scoped. Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: connection.location_disconnected
  summary: Listing disconnected
  scope: location
  description: 'A Google or Facebook listing is unlinked/removed from a location. Scope: location-scoped.
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: connection.reauth_required
  summary: Listing re-authorization required
  scope: location
  description: 'The connected account''s credentials were invalidated; the customer must reconnect / re-authorize.
    Scope: location-scoped. Delivered as a signed HTTP POST to your Webhooks URL.'
- event: endpoint.verification
  summary: Endpoint verification handshake
  scope: location
  description: 'Endpoint-verification handshake. Sent when a customer saves or clicks "Verify" on a Webhooks
    URL. Your endpoint must reply HTTP 200 with the lowercase hex HMAC-SHA256 of the nonce, keyed by your
    signing secret: hex(HMAC-SHA256(signing_secret, nonce)). Synup accepts the URL only if the returned
    digest matches. This request carries no location_id and no data object.'
- event: idea.generated
  summary: AI post idea generated
  scope: brand
  description: 'A new AI post idea was generated. Scope: local or social (see the top-level scope field).
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: idea.scheduled_as_post
  summary: AI idea scheduled as post
  scope: brand
  description: 'An idea was linked to a published social post (social only). Scope: social (see the top-level
    scope field). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: idea_image.generation_job_completed
  summary: AI idea image generated
  scope: brand
  description: 'An AI image for an idea finished generating. Scope: local or social (see the top-level
    scope field). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: idea_image.generation_job_failed
  summary: AI idea image generation failed
  scope: brand
  description: 'An AI image for an idea failed generating. Scope: local or social (see the top-level scope
    field). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: idea_pipeline.scrape_completed
  summary: AI idea scrape completed
  scope: brand
  description: 'A website-analysis scrape job for idea generation completed. Scope: local or social (see
    the top-level scope field). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: idea_pipeline.scrape_failed
  summary: AI idea scrape failed
  scope: brand
  description: 'A website-analysis scrape job for idea generation failed terminally. Scope: local or social
    (see the top-level scope field). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: idea_series.all_posts_generated
  summary: AI idea series completed
  scope: brand
  description: 'All slots in a content series finished generating. Scope: local or social (see the top-level
    scope field). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: interaction.response
  summary: New response to a review received
  scope: location
  description: Sent when Synup detects a new response to an existing review — including responses posted
    through Synup and responses detected directly on the platform. Responses arrive asynchronously, often
    well after the original review. Delivered to your Webhooks URL (Reviews webhook). Location-scoped.
    Use data.interaction.parent_id to link the response to the review it answers.
- event: interaction.review
  summary: New review received for a location
  scope: location
  description: Sent when Synup detects a new review for one of your locations on any monitored platform
    (Google, Yelp, TripAdvisor, etc.). Delivered to your Webhooks URL (Reviews webhook — requires the
    reviews webhook permission). Location-scoped. Social-category interactions are not delivered.
- event: listing.submission
  summary: Directory listing synced (success/incomplete)
  scope: location
  description: 'Sent when Synup finishes attempting to sync a business listing to a directory (Google,
    Facebook, etc.), triggered by profile updates or new directory submissions. Delivered to your Webhooks
    URL (Listings webhook). One delivery per status change — a move from incomplete to success sends two
    separate calls. Note the compact envelope: there is no top-level timestamp or account_id, and the
    location is'
- event: profile.created
  summary: Location created
  scope: location
  description: 'A new business location was created (customer-initiated only). Scope: location-scoped.
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: profile.deleted
  summary: Location deleted
  scope: location
  description: 'A location was archived (soft delete; there is no hard delete). Scope: location-scoped.
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: profile.updated
  summary: Location updated
  scope: location
  description: 'An existing location''s details were edited. Debounced to at most one delivery per location
    per 60 seconds. Scope: location-scoped. Delivered as a signed HTTP POST to your Webhooks URL.'
- event: rankings.gridrank_report_ready
  summary: Grid rank report ready
  scope: location
  description: 'A Grid (local-rank map) report finished generating. Scope: location-scoped. Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: rankings.sov_snapshot_completed
  summary: Share-of-Voice snapshot completed
  scope: location
  description: 'A Share-of-Voice snapshot was stored for a keyword (one event per keyword). Scope: location-scoped.
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: review_analytics.daily_snapshot
  summary: Daily review analytics snapshot
  scope: location
  description: 'The daily review-analytics roll-up for a location. Scope: location-scoped. Delivered as
    a signed HTTP POST to your Webhooks URL.'
- event: review_analytics.weekly_snapshot
  summary: Weekly review analytics snapshot
  scope: location
  description: 'The weekly review-analytics roll-up for a location. Scope: location-scoped. Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: social_connection.ad_account_status_changed
  summary: Ad account status changed
  scope: brand
  description: 'A connected ad account''s status changed. Scope: brand-scoped (location_id is null). Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: social_connection.archived
  summary: Social channel archived
  scope: brand
  description: 'A social channel connection was archived. Scope: brand-scoped (location_id is null). Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: social_connection.connected
  summary: Social channel connected
  scope: brand
  description: 'A social channel was connected (or reconnected) to a brand. Scope: brand-scoped (location_id
    is null). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_connection.disconnected
  summary: Social channel disconnected
  scope: brand
  description: 'A social channel was disconnected from a brand. Scope: brand-scoped (location_id is null).
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_post.boost_active
  summary: Boost active
  scope: brand
  description: 'A boost went live and is actively spending. Scope: brand-scoped (location_id is null).
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_post.boost_created
  summary: Boost created
  scope: brand
  description: 'A boost (paid promotion) was created for a social post. Scope: brand-scoped (location_id
    is null). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_post.boost_rejected
  summary: Boost rejected
  scope: brand
  description: 'A boost was rejected by the ad platform. Scope: brand-scoped (location_id is null). Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: social_post.boost_stopped
  summary: Boost stopped
  scope: brand
  description: 'A boost was stopped / completed. Scope: brand-scoped (location_id is null). Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: social_post.created
  summary: Social post created
  scope: brand
  description: 'A social post was created (draft or scheduled) in Synup. Scope: brand-scoped (location_id
    is null). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_post.deleted
  summary: Social post deleted
  scope: brand
  description: 'A social post was archived/removed. Scope: brand-scoped (location_id is null). Delivered
    as a signed HTTP POST to your Webhooks URL.'
- event: social_post.failed
  summary: Social post failed
  scope: brand
  description: 'A social post failed to publish on one or more platforms. Scope: brand-scoped (location_id
    is null). Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_post.published
  summary: Social post published
  scope: brand
  description: 'A social post was published to its platforms. Scope: brand-scoped (location_id is null).
    Delivered as a signed HTTP POST to your Webhooks URL.'
- event: social_post.rejected
  summary: Social post rejected
  scope: brand
  description: 'A social post was rejected in an approval workflow. Scope: brand-scoped (location_id is
    null). Delivered as a signed HTTP POST to your Webhooks URL.'