Build local presence automations in minutes — review auto-responders, listings monitors, reputation dashboards, bulk onboarding tools, and more.
pip install synupimport synup
client = synup.Synup() # reads SYNUP_API_KEY from env
# Auto-reply to all 4-5 star reviews that haven't been answered
results = client.workflows.auto_reply_to_reviews(
16808,
template="Thanks for the {rating}-star review! We appreciate your support.",
min_rating=4,
)
print(f"Replied to {len(results)} reviews")import synup
client = synup.Synup()
audit = client.workflows.listings_health_audit(16808)
print(f"Health score: {audit.health_score}%")
print(f"Synced: {audit.synced_count}, Issues: {audit.issue_count}")
print(f"Duplicates found: {len(audit.duplicates)}")import synup
# Minimal — reads SYNUP_API_KEY env var
client = synup.Synup()
# Explicit key
client = synup.Synup(api_key="your-api-key")
# With custom config
client = synup.Synup(
api_key="your-api-key",
timeout=300.0, # request timeout in seconds (default: 240)
max_retries=3, # auto-retry on 429/5xx (default: 2)
)# List with pagination
page = client.locations.list(first=10)
for loc in page:
print(loc.name, loc.city, loc.stateIso)
# Next page
if page.has_more:
next_page = page.next_page()
# Auto-paginate all
for loc in client.locations.list(first=100).auto_paging_iter():
print(loc.name)
# Retrieve single location
location = client.locations.retrieve(16808)
print(location.name)
# Search
page = client.locations.search("cafe", first=20)
# By IDs, store codes, folder, or tags
locations = client.locations.list_by_ids([16808, 16749])
locations = client.locations.list_by_store_codes(["STORE01", "STORE02"])
locations = client.locations.list_by_folder(folder_name="franchise")
page = client.locations.list_by_tags(["vip", "recent"], first=20)
# Create
result = client.locations.create({
"name": "Acme Inc",
"storeId": "ACME01",
"street": "123 Main St",
"city": "New York",
"stateIso": "NY",
"postalCode": "10001",
"countryIso": "US",
"phone": "5551234567",
})
print(result.success, result.errors)
# Update, archive, activate
client.locations.update({"id": 16808, "phone": "5559876543"})
client.locations.archive([16808])
client.locations.activate([16808])# List reviews with filters
page = client.reviews.list(16808, first=20, rating_filters=[1, 2])
for review in page:
print(review.content, review.rating)
# Auto-paginate all reviews
for review in client.reviews.list(16808, first=50).auto_paging_iter():
print(review.content)
# Respond to a review
client.reviews.respond(interaction_id="uuid-here", content="Thank you!")
# Edit or archive a response
client.reviews.edit_response(review_id="...", response_id="...", content="Updated reply")
client.reviews.archive_response(response_id="...")
# Review analytics
overview = client.reviews.analytics.overview(16808, start_date="2024-01-01")
timeline = client.reviews.analytics.timeline(16808)
sites = client.reviews.analytics.sites_stats(16808)
# Review phrases
phrases = client.reviews.phrases(["TG9jYXRpb246MTY4MDg="], start_date="2024-01-01")# Premium, voice, AI, and additional listings
premium = client.listings.premium(16808)
voice = client.listings.voice(16808)
ai = client.listings.ai(16808)
additional = client.listings.additional(16808)
# Duplicates
dupes = client.listings.duplicates(16808)
client.listings.mark_duplicate(16808, ["listing-item-id"])
client.listings.mark_not_duplicate(16808, ["listing-item-id"])
# Connect/disconnect
client.listings.connect(16808, "listing-id", "account-id")
client.listings.disconnect(16808, "GOOGLE")google = client.analytics.google(16808, from_date="2024-01-01")
bing = client.analytics.bing(16808)
facebook = client.analytics.facebook(16808)
# Rankings
timeline = client.analytics.rankings_timeline(
[16808], "2024-01-01", "2024-03-31", ["Google"]
)
histogram = client.analytics.rankings_histogram(
[16808], "2024-01-01", "2024-03-31", ["Google"]
)keywords = client.keywords.list(16808)
performance = client.keywords.performance(16808, from_date="2024-01-01")
created = client.keywords.add(16808, ["plumber", "plumbing near me"])
client.keywords.archive("keyword-id")campaigns = client.campaigns.list(16808)
result = client.campaigns.create(
16808,
name="Holiday Feedback",
customers=[{"name": "John", "email": "john@example.com"}],
screening=False,
)
client.campaigns.add_customers("campaign-id", [{"name": "Jane", "email": "jane@example.com"}])folders = client.folders.list()
tree = client.folders.tree()
client.folders.create("franchise", parent_folder_name="all_franchise")
client.folders.rename("Old Name", "New Name")
client.folders.add_locations("franchise", [16808, 16749])
client.folders.remove_locations([16808])
client.folders.delete("folder-name")users = client.users.list()
roles = client.users.roles()
result = client.users.create(email="jane@example.com", role_id="...", first_name="Jane")
client.users.update("user-id", first_name="Jane Updated")
client.users.add_locations("user-id", [16808])
client.users.remove_locations("user-id", [16808])tags = client.tags.list()
client.tags.add(16808, "vip")
client.tags.remove(16808, "old-tag")photos = client.photos.list(16808)
client.photos.add(16808, [{"photo": "https://example.com/img.jpg", "type": "ADDITIONAL"}])
client.photos.remove(16808, ["photo-id"])
client.photos.star(16808, ["media-id"], starred=True)accounts = client.connected_accounts.list()
url = client.connected_accounts.connect_google("https://ok.com", "https://err.com")
client.connected_accounts.disconnect_google("account-id")
# OAuth for single location
url = client.connected_accounts.oauth_url(16808, "GOOGLE", "https://ok.com", "https://err.com")
client.connected_accounts.oauth_disconnect(16808, "FACEBOOK")result = client.grid_reports.create(
location_id=16808,
keywords=["italian restaurant"],
business_name="Chianti",
business_street="No 12, 5th Block",
business_city="Bengaluru",
business_state="Karnataka",
business_country="India",
latitude=12.935216,
longitude=77.619961,
distance=20,
distance_unit="km",
grid_size=3,
)
report = client.grid_reports.retrieve("report-id")
reports = client.grid_reports.list(16808, page_size=20, page=1)result = client.automations.temporary_close(
name="Holiday closure",
start_date="2025-12-24",
start_time="18:00:00",
end_date="2025-12-26",
location_id=16808,
)sites = client.plan_sites()
countries = client.countries()
subs = client.subscriptions()High-level functions that combine multiple API calls into real product features.
# Auto-reply to positive reviews
results = client.workflows.auto_reply_to_reviews(
16808,
template="Thanks for the {rating}-star review!",
min_rating=4,
dry_run=True, # preview without sending
)
# Onboard a location with folder, tags, and keywords in one call
result = client.workflows.onboard_location(
name="Acme Coffee",
street="123 Main St",
city="New York",
state="NY",
postal_code="10001",
country="US",
phone="5551234567",
folder_name="NYC Stores",
tags=["new", "coffee"],
keywords=["coffee shop near me"],
)
# Bulk onboard from CSV
results = client.workflows.bulk_onboard_locations("locations.csv", folder_name="Imported")
# Weekly reputation report
report = client.workflows.weekly_reputation_report(16808)
print(report.review_summary, report.analytics, report.listings_health)
# Listings health audit
audit = client.workflows.listings_health_audit(16808)
print(f"Score: {audit.health_score}%, Issues: {audit.issue_count}")import synup
client = synup.Synup()
try:
client.locations.list()
except synup.AuthenticationError:
print("Invalid API key")
except synup.RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after}s")
except synup.NotFoundError:
print("Resource not found")
except synup.ValidationError as e:
print(f"Bad request: {e.response_body}")
except synup.APIError as e:
print(f"API error {e.status_code}: {e.response_body}")
except synup.APIConnectionError:
print("Network error — could not reach API")Current version: 0.4.2