Vendasta Listing Products API
Listing Products services through the gRPC gateway: ListingProductsService, ListingSourceService, ListingProfileService, SEOService and Citations — the fuller local-listings surface behind Local SEO.
Listing Products services through the gRPC gateway: ListingProductsService, ListingSourceService, ListingProfileService, SEOService and Citations — the fuller local-listings surface behind Local SEO.
{
"components": {
"schemas": {
"HealthCareProfessionalInformationGender": {
"default": "NotSpecified",
"enum": [
"NotSpecified",
"Female",
"Male",
"Other"
],
"type": "string"
},
"HealthCareProfessionalInformationIsProvider": {
"default": "IsProviderNotSpecified",
"enum": [
"IsProviderNotSpecified",
"IsProviderTrue",
"IsProviderFalse"
],
"type": "string"
},
"HoursOfOperationSpan": {
"properties": {
"closes": {
"type": "string"
},
"dayOfWeek": {
"items": {
"type": "string"
},
"type": "array"
},
"description": {
"type": "string"
},
"opens": {
"type": "string"
}
},
"type": "object"
},
"RichDataPaymentMethods": {
"default": "AMERICAN_EXPRESS",
"enum": [
"AMERICAN_EXPRESS",
"ANDROID_PAY",
"APPLE_PAY",
"CASH",
"CHECK",
"DEBIT",
"DINERS_CLUB",
"DISCOVER",
"MASTERCARD",
"PAYPAL",
"SAMSUNG_PAY",
"STORE_CARD",
"TRAVELERS_CHECK",
"VISA",
"CCS",
"SODEXO",
"GOPAY",
"V_PAY",
"FINANCING",
"INVOICE",
"PAYSEC",
"BITCOIN",
"NFC_MOBILE_PAYMENTS"
],
"type": "string"
},
"listing_productsv1Location": {
"properties": {
"address": {
"type": "string"
},
"address2": {
"type": "string"
},
"callTrackingNumber": {
"items": {
"type": "string"
},
"type": "array"
},
"city": {
"type": "string"
},
"companyName": {
"type": "string"
},
"country": {
"type": "string"
},
"location": {
"$ref": "#/components/schemas/v1Geo"
},
"primaryOperatingLanguage": {
"description": "The primary BCP 47 language the business operates in (e.g. \"en\", \"fr-ca\").\nEmpty when unset. Consumers fall back to \"en\".",
"type": "string"
},
"serviceArea": {
"$ref": "#/components/schemas/v1ServiceArea"
},
"serviceAreaBusiness": {
"type": "boolean"
},
"state": {
"type": "string"
},
"timezone": {
"type": "string"
},
"website": {
"type": "string"
},
"workNumber": {
"items": {
"type": "string"
},
"type": "array"
},
"zip": {
"type": "string"
}
},
"type": "object"
},
"protobufAny": {
"additionalProperties": {},
"properties": {
"@type": {
"type": "string"
}
},
"type": "object"
},
"rpcStatus": {
"properties": {
"code": {
"format": "int32",
"type": "integer"
},
"details": {
"items": {
"$ref": "#/components/schemas/protobufAny"
},
"type": "array"
},
"message": {
"type": "string"
}
},
"type": "object"
},
"v1AccuracyStatus": {
"default": "ACCURACY_STATUS_INVALID",
"description": "AccuracyStatus represents the overall accuracy state of a listing on a directory.\nThis is determined by comparing the business profile data against what's actually live on the directory (scraped data).\n\n - ACCURACY_STATUS_INVALID: ACCURACY_STATUS_INVALID means the accuracy data could not be interpreted or there was an error during scraping.\nThis is a technical error, not a listing problem.\n - ACCURACY_STATUS_UNKNOWN: ACCURACY_STATUS_UNKNOWN means either no scraped data was found (listing might not exist yet), or we haven't scraped this source yet.\nCommon for new listings that haven't been indexed by the directory, or directories we don't actively scrape.\n - ACCURACY_STATUS_ACCURATE: ACCURACY_STATUS_ACCURATE means the scraped listing data matches the business profile perfectly.\nAll NAP fields match - the listing is correct and healthy.\n - ACCURACY_STATUS_INACCURATE: ACCURACY_STATUS_INACCURATE means the scraped listing has one or more discrepancies compared to the business profile.\nCheck anchor_data_matches to see exactly which fields don't match.\nUser action: Review and correct the inaccurate fields, then wait for next sync.\n - ACCURACY_STATUS_UNAVAILABLE: ACCURACY_STATUS_UNAVAILABLE means this directory doesn't support accuracy reporting (we don't scrape it).\nCommon for data aggregators (Neustar, Data Axle) that don't have public listing pages to scrape.",
"enum": [
"ACCURACY_STATUS_INVALID",
"ACCURACY_STATUS_UNKNOWN",
"ACCURACY_STATUS_ACCURATE",
"ACCURACY_STATUS_INACCURATE",
"ACCURACY_STATUS_UNAVAILABLE"
],
"type": "string"
},
"v1AnchorData": {
"description": "AnchorData contains the expected business NAP (Name, Address, Phone) data from the business profile.\nThis is the \"source of truth\" that we compare against what's live on the directory to determine accuracy.",
"properties": {
"address": {
"title": "address is the expected street address",
"type": "string"
},
"city": {
"title": "city is the expected business city",
"type": "string"
},
"companyName": {
"title": "company_name is the expected business name",
"type": "string"
},
"country": {
"title": "country is the expected country code",
"type": "string"
},
"phone": {
"title": "phone is the expected primary phone number",
"type": "string"
},
"state": {
"title": "state is the expected state/province",
"type": "string"
},
"website": {
"title": "website is the expected business website URL",
"type": "string"
},
"zip": {
"title": "zip is the expected postal/zip code",
"type": "string"
}
},
"type": "object"
},
"v1AnchorDataMatches": {
"properties": {
"address": {
"title": "address is true if the directory's street address matches the expected address\nAddress mismatches prevent customers from finding the business",
"type": "boolean"
},
"city": {
"title": "city is true if the directory's city matches the expected city",
"type": "boolean"
},
"companyName": {
"title": "company_name is true if the directory's business name matches the expected name\nName mismatches are common causes of listing inaccuracy",
"type": "boolean"
},
"country": {
"title": "country is true if the directory's country matches the expected country",
"type": "boolean"
},
"phone": {
"title": "phone is true if the directory's phone number matches the expected phone\nPhone mismatches are critical - often the most important field for users",
"type": "boolean"
},
"state": {
"title": "state is true if the directory's state/province matches the expected state",
"type": "boolean"
},
"website": {
"title": "website is true if the directory's website matches the expected website",
"type": "boolean"
},
"zip": {
"title": "zip is true if the directory's zip code matches the expected zip code",
"type": "boolean"
}
},
"title": "AnchorDataMatches contains field-by-field accuracy comparison results.\nEach boolean indicates if the expected value (from AnchorData) matches what's currently live on the directory.\nTrue = field is accurate, False = field is inaccurate or missing on the directory.\nThis is critical for answering \"which specific fields are wrong on this listing?\"",
"type": "object"
},
"v1BingAttribute": {
"properties": {
"name": {
"title": "The name of the Bing attribute in the form \"attributes/is_owned_by_women\"",
"type": "string"
},
"value": {
"title": "Contains the value of the attribute. This can be of 4 types:\n bool\n URL (represented as a string google.protobuf.Value)\n enum (represented as a string google.protobuf.Value)\n repeated_enum (represented as a struct google.protobuf.Value)\nhttps://bpprodpublicstorage.blob.core.windows.net/bingplacesapi/BingPlaces_API_Latest.pdf"
}
},
"type": "object"
},
"v1BingAttributes": {
"properties": {
"bingAttribute": {
"items": {
"$ref": "#/components/schemas/v1BingAttribute"
},
"type": "array"
}
},
"type": "object"
},
"v1BusinessHours": {
"properties": {
"hoursTypeId": {
"description": "The hours types are based on the type of business so we don't give an exhaustive list of hours\ntypes here. We get the hours types for the business's category using the Google endpoint\nhttps://developers.google.com/my-business/reference/businessinformation/rest/v1/categories/batchGet",
"title": "hours type IDs are based on the Google hours types\nhttps://developers.google.com/my-business/reference/businessinformation/rest/v1/accounts.locations#morehours",
"type": "string"
},
"regularHours": {
"items": {
"$ref": "#/components/schemas/v1RegularHoursPeriod"
},
"title": "RegularHours is a collection of times that this location is open for business. Each\nperiod represents a range of hours when the location is open during the week. You may specify\nmultiple entries for the same date if you are open for multiple periods (Example lunch and supper)",
"type": "array"
},
"specialHours": {
"description": "SpecialHours represents a set of time periods when a location's operational hours differ from\nits regular business hours. This may be a holiday or special event. These hours replace the\nall regular hours for the day. The openTime and startDate must predate the closeTime and endDate.",
"items": {
"$ref": "#/components/schemas/v1SpecialHoursPeriod"
},
"type": "array"
}
},
"type": "object"
},
"v1Citation": {
"description": "Citation contains details for a citation.",
"properties": {
"breadcrumb": {
"description": "Output only. The breadcrumb path of the citation page.",
"readOnly": true,
"type": "string"
},
"created": {
"description": "Output only. When this citation was first discovered.",
"format": "date-time",
"readOnly": true,
"type": "string"
},
"description": {
"description": "Output only. The page description or snippet of the citation.",
"readOnly": true,
"type": "string"
},
"domain": {
"description": "Output only. The domain where the citation was found.",
"readOnly": true,
"type": "string"
},
"matchedFields": {
"description": "Output only. The NAP fields that matched in this citation.",
"items": {
"type": "string"
},
"readOnly": true,
"type": "array"
},
"searchTerm": {
"description": "Output only. The search term that found this citation.",
"readOnly": true,
"type": "string"
},
"title": {
"description": "Output only. The page title of the citation.",
"readOnly": true,
"type": "string"
},
"url": {
"description": "Output only. The URL of the citation.",
"readOnly": true,
"type": "string"
}
},
"type": "object"
},
"v1CitationsByDomain": {
"properties": {
"citations": {
"items": {
"$ref": "#/components/schemas/v1Citation"
},
"type": "array"
},
"domain": {
"type": "string"
}
},
"title": "CitationsByDomain contains all citations for a domain",
"type": "object"
},
"v1ClosedStatus": {
"default": "UNSPECIFIED",
"enum": [
"UNSPECIFIED",
"OPEN",
"LIMITED",
"TEMPORARY",
"PERMANENT"
],
"title": "ClosedStatus describes if the business is permanently or temporarily closed, or in a limited state",
"type": "string"
},
"v1ConditionalField": {
"properties": {
"id": {
"type": "string"
},
"value": {
"type": "string"
}
},
"type": "object"
},
"v1ConnectedDirectSyncAccount": {
"description": "ConnectedDirectSyncAccount represents an OAuth-connected account for direct sync sources (Google, Facebook, Apple, Bing).\nThis is only populated for directories that require OAuth authentication to sync.",
"properties": {
"accountId": {
"title": "account_id is the directory's internal identifier for this account (e.g., Google Account ID, Facebook Page ID)",
"type": "string"
},
"accountType": {
"title": "account_type identifies the directory/service type (e.g., \"google\", \"facebook\", \"apple\", \"bing\")",
"type": "string"
},
"clientTags": {
"items": {
"type": "string"
},
"title": "client_tags are partner-specific tags associated with this account",
"type": "array"
},
"connectionId": {
"title": "connection_id uniquely identifies this connection in the Core Services system (also known as Social Service ID)",
"type": "string"
},
"disabledFlag": {
"title": "disabled_flag indicates this connection has been manually disabled and cannot be used",
"type": "boolean"
},
"isAuthenticated": {
"title": "is_authenticated indicates if the OAuth token is valid and the account is currently connected\nFalse means the user needs to re-authenticate (token expired or was revoked)",
"type": "boolean"
},
"isSyncingEnabled": {
"title": "is_syncing_enabled indicates if automatic syncing is turned on for this specific account\nA business might have multiple Google accounts connected but only sync to one",
"type": "boolean"
},
"isVerified": {
"title": "is_verified indicates the account has been verified/claimed by the provider\nExample: a verified Google Business Profile location vs. an unverified one",
"type": "boolean"
},
"profileImageUrl": {
"title": "profile_image_url is the avatar/logo URL for the connected account",
"type": "string"
},
"profileUrl": {
"title": "profile_url is the URL to the account's profile page on the directory (e.g., Google Business Profile dashboard)",
"type": "string"
},
"tokenBroken": {
"title": "token_broken indicates the OAuth token is invalid, expired, or revoked\nUser action required: Reconnect the account to get a fresh OAuth token",
"type": "boolean"
},
"username": {
"title": "username is the display name or email of the connected account (e.g., \"john@example.com\" for Google)",
"type": "string"
}
},
"type": "object"
},
"v1DayOfWeek": {
"default": "DAY_OF_WEEK_UNSPECIFIED",
"description": "Represents a day of the week.\n\n - DAY_OF_WEEK_UNSPECIFIED: The day of the week is unspecified.\n - MONDAY: Monday\n - TUESDAY: Tuesday\n - WEDNESDAY: Wednesday\n - THURSDAY: Thursday\n - FRIDAY: Friday\n - SATURDAY: Saturday\n - SUNDAY: Sunday",
"enum": [
"DAY_OF_WEEK_UNSPECIFIED",
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY"
],
"type": "string"
},
"v1DetailedSyndicationStatusResultValue": {
"description": "DetailedSyndicationStatusResultValue contains field-level sync results for a specific data type.\nThis shows exactly which fields synced successfully and which failed within a data category.",
"properties": {
"dataType": {
"title": "data_type is the category of data (matches the key in parent message)",
"type": "string"
},
"errorMessage": {
"title": "error_message contains the specific error for failed fields\nExample: \"Phone number format invalid for Bing Places. Must be (XXX) XXX-XXXX\"",
"type": "string"
},
"failedFields": {
"items": {
"type": "string"
},
"title": "failed_fields lists individual fields that failed to sync\nExample: [\"phone\"] - this tells you exactly which field is causing the problem",
"type": "array"
},
"lastSyncTime": {
"format": "date-time",
"title": "last_sync_time is when this data type was last synced successfully",
"type": "string"
},
"status": {
"title": "status is the high-level status for this data type (\"success\", \"failed\", \"partial\")",
"type": "string"
},
"syncedFields": {
"items": {
"type": "string"
},
"title": "synced_fields lists individual fields that synced successfully\nExample: [\"company_name\", \"address\", \"city\", \"state\", \"zip\"]",
"type": "array"
}
},
"type": "object"
},
"v1DetailedSyndicationStatusResults": {
"properties": {
"key": {
"title": "key identifies the data type category (e.g., \"location\" for NAP data, \"hours\" for business hours, \"photos\" for images)",
"type": "string"
},
"value": {
"$ref": "#/components/schemas/v1DetailedSyndicationStatusResultValue"
}
},
"title": "DetailedSyndicationStatusResults provides granular sync status for different data types within a sync.\nKey-value pairs where key is the data type (e.g., \"location\", \"hours\", \"photos\")",
"type": "object"
},
"v1DoctorDotComCategory": {
"properties": {
"fullName": {
"type": "string"
},
"id": {
"format": "int64",
"type": "string"
},
"nuccTaxonomyCode": {
"type": "string"
}
},
"type": "object"
},
"v1EcosystemSource": {
"description": "EcosystemSource represents a secondary directory that receives data when syncing to a primary aggregator.\nExample: When syncing to Neustar or Data Axle, data flows to dozens of downstream directories.",
"properties": {
"icon": {
"title": "icon is the URL to the directory's logo/icon",
"type": "string"
},
"name": {
"title": "name is the human-readable name of the downstream directory (e.g., \"TomTom\", \"Garmin\", \"MapQuest\")",
"type": "string"
},
"sourceId": {
"title": "source_id is the numeric ID of the downstream directory",
"type": "string"
}
},
"type": "object"
},
"v1ExternalIdentifiers": {
"properties": {
"actionLists": {
"items": {
"type": "string"
},
"type": "array"
},
"additionalSalesPersonIds": {
"items": {
"type": "string"
},
"type": "array"
},
"customerIdentifier": {
"type": "string"
},
"jobId": {
"items": {
"type": "string"
},
"type": "array"
},
"marketId": {
"type": "string"
},
"origin": {
"type": "string"
},
"partnerId": {
"type": "string"
},
"salesPersonId": {
"type": "string"
},
"socialProfileId": {
"type": "string"
},
"tags": {
"items": {
"type": "string"
},
"type": "array"
},
"taxIds": {
"items": {
"type": "string"
},
"type": "array"
},
"updateOrigin": {
"type": "string"
},
"vCategoryIds": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"v1GBPClaimStatus": {
"default": "GBP_CLAIM_STATUS_INVALID",
"description": "GBPClaimStatus indicates whether a Google Business Profile listing has been claimed by the business owner.",
"enum": [
"GBP_CLAIM_STATUS_INVALID",
"GBP_CLAIM_STATUS_UNKNOWN",
"GBP_CLAIM_STATUS_CLAIMED",
"GBP_CLAIM_STATUS_UNCLAIMED"
],
"type": "string"
},
"v1Geo": {
"description": "Represents a geo point location.",
"properties": {
"latitude": {
"format": "double",
"type": "number"
},
"longitude": {
"format": "double",
"type": "number"
}
},
"type": "object"
},
"v1GetCitationDataRequest": {
"description": "Request to retrieve citation data for a business, including citation counts, historical trends, and citations grouped by domain.",
"properties": {
"businessId": {
"description": "Required. The business ID (account group ID) for which to retrieve citation data.",
"type": "string"
},
"endDate": {
"description": "Optional. The end date of the date range for citation data retrieval.",
"format": "date-time",
"type": "string"
},
"startDate": {
"description": "Optional. The start date of the date range for citation data retrieval.",
"format": "date-time",
"type": "string"
}
},
"required": [
"businessId"
],
"title": "GetCitationDataRequest",
"type": "object"
},
"v1GetCitationDataResponse": {
"description": "Contains citation data for a business including total count, historical trends, and citations grouped by domain.",
"properties": {
"citationCount": {
"description": "Output only. The total number of citations found for the business.",
"format": "int64",
"readOnly": true,
"type": "string"
},
"citationPercentGrowth": {
"description": "Output only. The percentage growth in citations over the date range.",
"format": "int64",
"readOnly": true,
"type": "string"
},
"citationsByDomain": {
"description": "Output only. Citations grouped by domain.",
"items": {
"$ref": "#/components/schemas/v1CitationsByDomain"
},
"readOnly": true,
"type": "array"
},
"historicalCitationsSeries": {
"description": "Output only. Historical citation data points showing citation count over time.",
"items": {
"$ref": "#/components/schemas/v1HistoricalCitationsDataPoint"
},
"readOnly": true,
"type": "array"
},
"initialCitationCount": {
"description": "Output only. The initial citation count at the start of tracking.",
"format": "int64",
"readOnly": true,
"type": "string"
},
"startDate": {
"description": "Output only. The start date of the citation data range.",
"format": "date-time",
"readOnly": true,
"type": "string"
}
},
"title": "GetCitationDataResponse",
"type": "object"
},
"v1GetListingSourceByIdRequest": {
"description": "Request to retrieve detailed configuration for a specific listing directory by its numeric ID.",
"properties": {
"fieldMask": {
"$ref": "#/components/schemas/vendastatypesFieldMask"
},
"sourceId": {
"description": "Required. The numeric ID of the directory (e.g., 1 = Google, 2 = Facebook, etc.).\nYou can get this ID from the source_id field in GetSyncDataResponse.",
"format": "int64",
"type": "string"
}
},
"required": [
"sourceId"
],
"title": "GetListingSourceByIdRequest",
"type": "object"
},
"v1GetListingSourceByIdResponse": {
"description": "Contains comprehensive directory configuration and constraints for a single listing source.",
"properties": {
"source": {
"$ref": "#/components/schemas/v1Source"
}
},
"title": "GetListingSourceByIdResponse",
"type": "object"
},
"v1GetListingSourcesRequest": {
"description": "Request to fetch all listing sources, optionally filtered by provider.",
"properties": {
"fieldMask": {
"$ref": "#/components/schemas/vendastatypesFieldMask"
},
"provider": {
"$ref": "#/components/schemas/v1Provider"
}
},
"title": "GetListingSourcesRequest",
"type": "object"
},
"v1GetListingSourcesResponse": {
"description": "Contains a map of all listing sources keyed by source ID.",
"properties": {
"fieldMask": {
"$ref": "#/components/schemas/vendastatypesFieldMask"
},
"sources": {
"additionalProperties": {
"$ref": "#/components/schemas/v1Source"
},
"description": "Output only. Map of source_id to directory configuration.",
"readOnly": true,
"type": "object"
}
},
"title": "GetListingSourcesResponse",
"type": "object"
},
"v1GetLocalSearchSEODataRequest": {
"description": "Request to fetch detailed vicinity/local search data for a specific keyword, showing search results from multiple geographic locations around the business.",
"properties": {
"businessId": {
"description": "Required. The business ID (account group ID) for which to query local search data.",
"type": "string"
},
"endDate": {
"description": "Optional. The end date of the date range for which to retrieve local search data.",
"format": "date-time",
"type": "string"
},
"keyword": {
"description": "Required. The specific keyword to fetch local search data for. Unlike GetSEODataSummary, this endpoint\nonly accepts a single keyword to provide detailed vicinity analysis.",
"type": "string"
},
"startDate": {
"description": "Optional. The start date of the date range for which to retrieve local search data.",
"format": "date-time",
"type": "string"
}
},
"required": [
"businessId",
"keyword"
],
"title": "GetLocalSearchSEODataRequest",
"type": "object"
},
"v1GetLocalSearchSEODataResponse": {
"description": "Contains detailed vicinity/local search data for a keyword, showing search results from multiple geographic locations around the business.",
"properties": {
"averageLocalRank": {
"description": "Output only. The average ranking position across all 25 grid points (vicinities) in the Local Search Grid for\nthe current/most recent data. This metric represents the business's average visibility across the\n5x5 grid around the business location. Only grid points with available data are included in the\ncalculation. Grid points where the business was not found (rank 0, invalid, or \"-\") are treated as\nrank 21. Lower values indicate better average positioning across all geographic locations. Compare\nwith previous_average_local_rank to analyze visibility trends over time.\nNote: Although this field is a double, the agent response should display only the integer portion.",
"format": "double",
"readOnly": true,
"type": "number"
},
"keyword": {
"description": "Output only. The keyword for which this local search data was collected.",
"readOnly": true,
"type": "string"
},
"localSearchData": {
"description": "Output only. A list of local search data entries, each representing search results from a different geographic\nlocation (vicinity). Each entry contains results from one of the 25 locations in the 5x5 grid around\nthe business, showing which businesses appear in search results at that specific location.",
"items": {
"$ref": "#/components/schemas/v1LocalSearchData"
},
"readOnly": true,
"type": "array"
},
"previousAverageLocalRank": {
"description": "Output only. The average ranking position across all 25 grid points (vicinities) from the previous/historical\nlocal search data. This represents the baseline average visibility for comparison with the current\naverage_local_rank. Only grid points with available data are included in the calculation. Grid points\nwhere the business was not found (rank 0, invalid, or \"-\") are treated as rank 21. Used for trend\nanalysis to determine if local search visibility has improved, declined, or remained stable.\nNote: Although this field is a double, the agent response should display only the integer portion.",
"format": "double",
"readOnly": true,
"type": "number"
},
"previousLocalSearchData": {
"description": "Output only. Historical local search data entries from the oldest data point within the specified date range.\nThis represents baseline data for comparison to show performance changes over time.",
"items": {
"$ref": "#/components/schemas/v1LocalSearchData"
},
"readOnly": true,
"type": "array"
}
},
"title": "GetLocalSearchSEODataResponse",
"type": "object"
},
"v1GetSyncDataRequest": {
"description": "Request to retrieve comprehensive sync status and listing accuracy data for a business across all directory sources.",
"properties": {
"businessId": {
"description": "Required. The business ID (also known as account_group_id) uniquely i
# --- truncated at 32 KB (101 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/vendasta/refs/heads/main/openapi/vendasta-listing-products-openapi.json