Listings
Fetch premium, voice, and duplicate directory listings, manage duplicate suppression, and connect profiles with the listingsapi-js SDK.
Listings represent a location's presence on individual directories (Google,
Yelp, Bing, Alexa, Siri, and so on). All listing methods live directly on the
ListingsAPI client instance and are scoped to a location ID. Numeric
location IDs are encoded automatically, so 16808 and
'TG9jYXRpb246MTY4MDg=' are interchangeable.
fetchPremiumListings
Get premium directory listings for a location: Google, Yelp, Facebook, and
the rest of the core directory network. Returns an array of Listing
objects with fields like id, site, syncStatus, displayStatus, and
listingUrl.
const listings = await client.fetchPremiumListings(16808); for (const l of listings) {console.log(l.site, l.syncStatus, l.listingUrl);}Possible syncStatus values include SYNCED, PENDING, ERROR, and
NOT_CONNECTED.
fetchVoiceListings
Get voice assistant listings: Google Assistant, Amazon Alexa, Apple Siri,
and similar surfaces. Returns an array of VoiceListing objects with fields
like name, voiceIdentifier, and syncStatus.
const voice = await client.fetchVoiceListings(16808); console.log(voice.length + ' voice listings');for (const v of voice) {console.log(v.name, v.syncStatus);}fetchDuplicateListings
Get duplicate listings detected for a specific location. Returns an array of
DuplicateListing objects with fields like id, site, and listingUrl.
const duplicates = await client.fetchDuplicateListings(16808); for (const d of duplicates) {console.log(d.site, d.listingUrl);}fetchAllDuplicateListings
Get a rollup of duplicate listings across all locations in the account, with
optional tag filtering and pagination. Unlike fetchDuplicateListings, this
returns a rollup object rather than a plain array.
// All duplicates across the accountconst rollup = await client.fetchAllDuplicateListings(); // Filter by tag and pageconst page2 = await client.fetchAllDuplicateListings({ tag: 'region:west', page: 2 });Options
| Parameter | Type | Description |
|---|---|---|
tag | string | Filter to locations carrying this tag. |
page | number | Page number (1-indexed). |
markListingsAsDuplicate
Mark one or more listing items as duplicates for a location. The platform will attempt to suppress the flagged profiles.
await client.markListingsAsDuplicate(16808, ['listing-item-id-1','listing-item-id-2',]);Parameters
| Parameter | Type | Description |
|---|---|---|
locationId | string | number | Location the listing items belong to. |
listingItemIds | string[] | IDs of the listing items to flag. |
There is no success flag to check. If the platform rejects the mutation, the
client throws a ValidationError, so a resolved promise means it succeeded.
markListingsAsNotDuplicate
Clear the duplicate flag for listing items that were incorrectly marked.
await client.markListingsAsNotDuplicate(16808, ['listing-item-id-1',]);Parameters
| Parameter | Type | Description |
|---|---|---|
locationId | string | number | Location the listing items belong to. |
listingItemIds | string[] | IDs of the listing items to unflag. |
connectListing
Link a location to a listing from a connected Google or Facebook account. Use this after connecting the account and finding the matching listing.
await client.connectListing(16808,'connected-listing-id','connected-account-id',);Parameters
| Parameter | Type | Description |
|---|---|---|
locationId | string | number | Location to link. |
connectedAccountListingId | string | Listing ID from the connected account. |
connectedAccountId | string | ID of the connected Google or Facebook account. |
disconnectListing
Unlink a location from its Google or Facebook listing. The site name is
uppercased automatically, so 'google' and 'GOOGLE' both work.
await client.disconnectListing(16808, 'GOOGLE');Parameters
| Parameter | Type | Description |
|---|---|---|
locationId | string | number | Location to unlink. |
site | string | Directory to disconnect, for example 'GOOGLE' or 'FACEBOOK'. |
createGmbListing
Create a Google Business Profile listing for an existing location, using a connected Google account.
const result = await client.createGmbListing(16808, 'connected-account-id'); // Optionally place the new listing in a specific folderawait client.createGmbListing(16808, 'connected-account-id', {folderId: 'folder-id',});Parameters
| Parameter | Type | Description |
|---|---|---|
locationId | string | number | Location to create the listing for. |
connectedAccountId | string | ID of the connected Google account. |
options.folderId | string | Optional folder to create the listing in. |
Typical audit workflow
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); // reads LISTINGSAPI_KEY from envconst LOCATION_ID = 16808; // Acme Dental const [premium, duplicates] = await Promise.all([client.fetchPremiumListings(LOCATION_ID),client.fetchDuplicateListings(LOCATION_ID),]); const unsynced = premium.filter((l) => l.syncStatus !== 'SYNCED');console.log(unsynced.length + ' unsynced listings'); if (duplicates.length > 0) {const ids = duplicates .map((d) => d.id) .filter((id): id is string => Boolean(id));await client.markListingsAsDuplicate(LOCATION_ID, ids);console.log('Marked ' + ids.length + ' duplicates');}Related resources
- Locations: look up location IDs
- Error handling: typed errors thrown by every method
- Use cases: listings audit recipe