v1Resources/Listings Published/getGet a listings summary
Get a listings summary
Publisher sync health across this client's (or the whole agency's) locations — an aggregate summary plus a per-location breakdown, insights (health %, sync distribution, weakest publishers, ranked "needs attention" items), and a deterministic headline. Scope to a subset with tags. Backed by the same rollup as the Listings → All locations view.
get
listings:read/api/v1/listings/summaryQuery parameters
clientIdstringoptional
Limit to one client's locations.
tagsstringoptional
Comma-separated location tag names — only locations carrying at least one of these are included.
pageintegeroptional
Page of the per-location rows (1-based). Default 1.
perPageintegeroptional
Rows per page (max 200). Default 50.
withVisibilitybooleanoptional
Set to true to add each row's citation and maps results and the visibility totals. Off by default.
Response
dataobjectoptional
summaryobjectoptional
Aggregate counts across every location in scope.
locationsnumberoptional
Number of locations in scope.
publishersTotalnumberoptional
Total publisher slots across all locations in scope.
publishersSyncednumberoptional
Of those, currently synced.
connectionIssuesnumberoptional
Native connector (Google/Facebook) rows with a connection problem.
duplicatesnumberoptional
Detected duplicate listings across the scope.
reviewsnumberoptional
Total reviews across the scope.
avgRatingnumberoptional
Average rating across locations that have one.
rowsarray of objectoptional
One row per location in scope (paginated).
locationIdstringoptional
Location id.
namestringoptional
Location name.
citystringoptional
Location city.
publishersnumberoptional
Publisher slots for this location.
syncednumberoptional
Of those, currently synced.
connectionIssuesnumberoptional
Native connector rows with a connection problem.
duplicatesnumberoptional
Detected duplicate listings for this location.
reviewsnumberoptional
Total reviews for this location.
unrepliednumberoptional
Reviews awaiting a reply.
avgRatingnumberoptional
Average rating for this location.
googleVerifiedbooleanoptional
Google listing is connected and verified.
googleConnectedbooleanoptional
Google is connected (may still be awaiting verification).
tagsarray of stringoptional
This location's internal tags.
healthobjectoptional
This location's listing health, counted over the same eligible listings as its own Listings Overview.
eligibleintegerrequired
Directory listings the location is eligible for: every active site available for its country, plan and publisher set.
liveintegerrequired
Of those, listings that are live.
inFlightintegerrequired
Of those, listings sent and awaiting a result (in progress or pending approval).
needsActionintegerrequired
Of those, directory listings whose status needs someone to act.
notLiveYetintegerrequired
The remaining eligible listings, not live yet. Null when the other counts don't fit inside the eligible total.
consistentbooleanrequired
True when live, inFlight, needsAction and notLiveYet add up to eligible.
phasestring (preparing | submitting | settled)required
Where the location's first round of directory submissions stands: preparing, submitting or settled.
citationobjectoptional
This location's listings in Google Search: its current live listing pages, counted by result. Only with withVisibility=true.
statestring (none | unchecked | measured)required
none: no eligible live page. unchecked: pages exist but none has a result yet. measured: at least one page has a result.
totalintegerrequired
Live listing pages counted.
indexedintegerrequired
Of those, pages shown in Google Search.
notIndexedintegerrequired
Of those, pages with a recorded result of not indexed.
pendingintegerrequired
Of those, pages awaiting a result.
notCheckedintegerrequired
Of those, pages with no usable result yet.
latestEvidenceAtstringrequired
When the newest page result was recorded, or null.
oldestEvidenceAtstringrequired
The oldest of the pages' latest results, or null. With latestEvidenceAt, the range the results were recorded over.
mapsobjectoptional
Top 3 on Google Maps for this location's default keyword, from one stored scan. Only with withVisibility=true.
statestring (noKeywords | notMeasured | measured)required
noKeywords: no tracked keywords. notMeasured: keywords are tracked but none has a measured scan. measured: a measured scan exists.
keywordIdstringrequired
The tracked keyword's id.
keywordstringrequired
The tracked keyword.
keywordCountintegerrequired
Number of keywords tracked for this location.
reportIdstringrequired
The stored report's id.
yearMonthstringrequired
The month this point covers, as "YYYY-MM".
measuredintegerrequired
Counted spots with a measured answer (ranked or outside). The denominator for top3.
top3integerrequired
Measured spots where you ranked in the top 3.
outsideintegerrequired
Measured spots where you weren't in the tracked top 20.
noDataintegerrequired
Counted spots whose check failed. Not a ranking.
withheldPointsintegerrequired
Stored spots from an earlier keyword or grid setup. Shown as withheld and not counted.
missingPointsintegerrequired
Grid spots with no stored result at all.
avgRanknumberrequired
Average rank over the measured spots, with outside counted as 21. Null when nothing was measured.
bestRankintegerrequired
Best measured position, 1 to 20. Null when every measured spot is outside.
evidencestring (proven | unverified)required
proven: every counted spot matches the current keyword and grid. unverified: a legacy scan whose keyword and grid can't be confirmed.
completedAtstringrequired
When the full-grid collection behind these exact results was completed. Null unless that is proven.
generatedAtstringrequired
The report's recorded date, set when it was first finalized. Not a collection time, a last-update time or a live check.
newerUnmeasuredbooleanrequired
True when a newer scan for the keyword measured nothing countable, so an older scan is shown.
scanInProgressbooleanrequired
True while a grid scan is running for this location. Location-wide: it doesn't say which keywords the scan covers.
healthobjectoptional
Listing health across every location in scope, not just this page. Counts are summed, never percentages averaged.
locationsintegerrequired
Number of locations in scope.
eligibleintegerrequired
Directory listings the location is eligible for: every active site available for its country, plan and publisher set.
liveintegerrequired
Of those, listings that are live.
inFlightintegerrequired
Of those, listings sent and awaiting a result (in progress or pending approval).
needsActionintegerrequired
Of those, directory listings whose status needs someone to act.
notLiveYetintegerrequired
The remaining eligible listings, not live yet. Null when the other counts don't fit inside the eligible total.
locationsNeedingActionintegerrequired
Locations with at least one directory listing needing action.
connectionIssuesintegerrequired
Native connector (Google/Facebook) rows with a connection problem.
locationsWithConnectionIssuesintegerrequired
Locations with at least one connection issue.
duplicatesintegerrequired
Detected duplicate listings across the scope.
locationsWithDuplicatesintegerrequired
Locations with at least one detected duplicate listing.
preparingintegerrequired
New locations whose first submissions are being prepared.
submittingintegerrequired
New locations whose first submissions are being sent.
visibilityobjectoptional
Visibility totals across every location in scope, not just this page. Only with withVisibility=true.
citationobjectrequired
Listings in Google Search, summed across locations with at least one live listing page.
totalintegerrequired
Live listing pages counted.
indexedintegerrequired
Of those, pages shown in Google Search.
notIndexedintegerrequired
Of those, pages with a recorded result of not indexed.
pendingintegerrequired
Of those, pages awaiting a result.
notCheckedintegerrequired
Of those, pages with no usable result yet.
locationsobjectrequired
Locations by citation state.
oldestEvidenceAtstringrequired
The oldest of the pages' latest results, or null. With latestEvidenceAt, the range the results were recorded over.
latestEvidenceAtstringrequired
When the newest page result was recorded, or null.
mapsobjectrequired
Top 3 on Google Maps, summed over each measured location's own scan.
measuredintegerrequired
Counted spots with a measured answer (ranked or outside). The denominator for top3.
top3integerrequired
Measured spots where you ranked in the top 3.
locationsobjectrequired
Locations by maps state.
completedintegerrequired
Measured locations whose scan date is a verified full-grid collection rather than a recorded report date.
scannedFromstringrequired
Start or end of the range of verified collection dates (completedAt) across measured locations. Null when there are none.
scannedTostringrequired
Start or end of the range of verified collection dates (completedAt) across measured locations. Null when there are none.
reportedFromstringrequired
Start or end of the range of recorded report dates (generatedAt) for measured locations without a verified collection. Null when there are none. Never merged with the scanned range.
reportedTostringrequired
Start or end of the range of recorded report dates (generatedAt) for measured locations without a verified collection. Null when there are none. Never merged with the scanned range.
insightsobjectoptional
Derived insights computed from the rows above.
healthnumberoptional
publishersSynced / publishersTotal, as a percentage.
distributionobjectoptional
Locations bucketed by sync rate (fullySynced 100%, healthy 90-99%, atRisk <90%).
fullySyncednumberoptional
Locations at 100% sync.
healthynumberoptional
Locations at 90-99% sync.
atRisknumberoptional
Locations below 90% sync.
weakestarray of objectoptional
Lowest-coverage publishers across the scope.
idstringoptional
Publisher id.
namestringoptional
Publisher name.
totalnumberoptional
Locations carrying this publisher.
syncednumberoptional
Of those, synced.
requiresActionnumberoptional
Of those, requiring action.
notConnectednumberoptional
Of those, not connected.
pctnumberoptional
Synced percentage, rounded.
directoriesarray of objectoptional
Full per-publisher coverage table.
idstringoptional
Publisher id.
namestringoptional
Publisher name.
totalnumberoptional
Locations carrying this publisher.
syncednumberoptional
Of those, synced.
requiresActionnumberoptional
Of those, requiring action.
notConnectednumberoptional
Of those, not connected.
pctnumberoptional
Synced percentage, rounded.
attentionarray of objectoptional
Ranked "needs attention" cards.
nnumberoptional
Count this card represents.
titlestringoptional
Card title.
substringoptional
Card subtitle.
tonestring (amber | blue | rose | zinc)optional
Visual tone for this card.
filterstring (issues | duplicates | under80 | unverified | notconnected)optional
Matching locations-table filter key.
headlinestringoptional
A deterministic one-line summary of scope health.
fixFirstarray of objectoptional
Ranked priority fixes.
textstringoptional
Fix description.
impactstring (High | Med | Low)optional
Estimated impact of this fix.
filterstring (issues | duplicates | under80 | unverified | notconnected)optional
Matching locations-table filter key.
totalnumberoptional
Total matching locations (for pagination), independent of perPage.
pagenumberoptional
Current page (1-based).
perPagenumberoptional
Rows per page.
Errors
401Missing, invalid, expired, or revoked API key.
403The key lacks the required scope, or isn't authorized for this client/location.
429Too many requests. Retry after the number of seconds in the Retry-After header.
get/api/v1/listings/summary
Your API key
clientId
tags
page
perPage
withVisibility
{
"data": {
"summary": {
"locations": 12,
"publishersTotal": 96,
"publishersSynced": 81,
"connectionIssues": 3,
"duplicates": 2,
"reviews": 340,
"avgRating": 4.6
},
"rows": [
{
"locationId": "loc_456",
"name": "Acme Dental — Downtown",
"city": "Austin",
"publishers": 8,
"synced": 7,
"connectionIssues": 0,
"duplicates": 0,
"reviews": 26,
"unreplied": 2,
"avgRating": 4.8,
"googleVerified": true,
"googleConnected": true,
"facebookConnected": true,
"tags": [
"vip"
]
}
],
"insights": {
"health": 84,
"distribution": {
"fullySynced": 9,
"healthy": 2,
"atRisk": 1
},
"weakest": [
{
"locationId": "loc_789",
"name": "Acme Dental — Eastside",
"health": 40
}
],
"directories": [
{
"id": "google",
"name": "Google Maps",
"total": 12,
"synced": 11,
"requiresAction": 0,
"notConnected": 1,
"pct": 92
}
],
"attention": [
{
"n": 1,
"title": "1 location under 90% synced",
"sub": "Listings not fully propagated",
"tone": "amber",
"filter": "under80"
}
],
"headline": "84% listing health — 1 location under 90% synced needs attention.",
"fixFirst": [
{
"text": "Reconnect 1 location's listing sync.",
"impact": "Med"
}
]
},
"total": 12,
"page": 1,
"perPage": 50
}
}Guides that use this endpoint
- Business Listings API: Complete Developer GuideHow a business listings API works and how to create, update, sync and monitor locations across Google, Apple, Bing and directories with the Synup API.
- How to Add Local Marketing Features to Your SaaSAdd listings management, reviews, Google posts, profile analytics, rank tracking and AI visibility to a SaaS product with the Synup API, tenant by tenant.
- How to Manage Business Listings ProgrammaticallyKeep business listings accurate from your own system with the Synup API. Covers change detection, idempotent updates, hours, photos and sync reporting.
- How to Update Business Information Across Google, Apple, Bing and DirectoriesPush one business-information change to Google, Apple, Bing and the directory network through a single API call, and verify it reached each publisher.
- How Listing Syndication WorksListing syndication takes one business record, translates it into each publisher's format, and pushes it out asynchronously, which is why sync status matters.
- How to Build an AI Agent for Local SEOBuild an AI agent that audits and fixes listings, tracks local rankings, checks AI visibility and drafts review replies with Synup's MCP server or REST tools.
- How to Manage Thousands of Business Locations via APIDesign a sync job for thousands of locations on the Synup API with cursor pagination, tags, rate-limit handling, an id map and rollup health checks.
- How to Find and Remove Duplicate Business ListingsDetect duplicate business listings across publishers, review them by confidence, and flag them for removal or dismiss them with the Synup API.
- How to Build a Multi-Location Marketing DashboardBuild a multi-location marketing dashboard from the API's rollup endpoints, one call per panel, covering listings, reviews, rank, AI visibility and duplicates.
- Local SEO APIs: What Developers Actually NeedA practical checklist of what a local SEO API must cover, from listings and sync status to reviews, rank tracking and AI visibility, mapped to endpoints.
- How to Monitor Local SEO Across Multiple LocationsMonitor local SEO across hundreds of locations through rollup endpoints, with rank and AI visibility per location and the weakest surfaced first.