Python SDK for the Synup API
This project has been archived.
The maintainers of this project have marked this project as archived. No new releases are expected.
Project description
Synup SDK
Build local presence automations in minutes — review auto-responders, listings monitors, reputation dashboards, bulk onboarding tools, and more.
Installation
pip install synup-sdk
Quick start: auto-reply to reviews in 10 lines
import 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")
Quick start: listings health audit in 3 lines
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)}")
Configuration
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)
)
Locations
# 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])
Reviews
# 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")
Listings
# 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")
Analytics
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
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
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
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
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
tags = client.tags.list()
client.tags.add(16808, "vip")
client.tags.remove(16808, "old-tag")
Photos
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)
Connected accounts
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")
Grid reports
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)
Automations
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,
)
Account-level
sites = client.plan_sites()
countries = client.countries()
subs = client.subscriptions()
Workflows — pre-built automations
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}")
Error handling
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")
Version
Current version: 0.4.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file synup_sdk-0.4.0.tar.gz.
File metadata
- Download URL: synup_sdk-0.4.0.tar.gz
- Upload date:
- Size: 31.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
206fbdac7678521b19fbd4693d938be3e5be9b56839a3e56a94d244d26eafc6a
|
|
| MD5 |
57049b4fa622e1a9ba9ace221d819a6a
|
|
| BLAKE2b-256 |
146210c707a17aa3f839893c5040b49719758068cddebb796b40e1821adef606
|
File details
Details for the file synup_sdk-0.4.0-py3-none-any.whl.
File metadata
- Download URL: synup_sdk-0.4.0-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
665edee65a7401f586c4f72311c95795256c38e044989cd6ce781da784e3293e
|
|
| MD5 |
a25cb0eb846b51714feb7aa23b7fd4bb
|
|
| BLAKE2b-256 |
50fe5c43e1a3b1d3a27e3dde019e38d30275f4ae42d899c8048b444096bf663b
|