Vendasta Analytics Service API
The AnalyticsService API from Vendasta — 2 operation(s) for analyticsservice.
The AnalyticsService API from Vendasta — 2 operation(s) for analyticsservice.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/vendasta-analyticsservice-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Multi-Location Analytics Analytics Service API
version: 1.16.1
servers:
- description: Production
url: https://prod.apigateway.co/grpc
tags:
- name: AnalyticsService
paths:
/v1/multi-location-analytics/available-metrics:
post:
description: "The catalog is filtered by audience tier derived from the resource shape:\n - BusinessResourceId or JWTResourceId -> SMB-tier only\n - GroupResourceId, MarketId, or SalesTeam -> SMB + Partner tiers\n\nMixing Business with Market/Group/SalesTeam in one request returns InvalidArgument."
operationId: AnalyticsService_GetAvailableMetrics
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/v1GetAvailableMetricsRequest'
description: Request to retrieve the catalog of available analytics metrics for the given resources.
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/v1GetAvailableMetricsResponse'
description: A successful response.
default:
content:
application/json:
schema:
$ref: '#/components/schemas/rpcStatus'
description: An unexpected error response.
security:
- OAuth2:
- business-app
summary: Get Available Metrics
tags:
- AnalyticsService
/v1/multi-location-analytics/query:
post:
description: "This is the primary analytics endpoint. It supports flexible querying of any available metric\nwith full control over measures, dimensions, time alignment, filtering, grouping, and pagination.\n\nIMPORTANT: Call GetAvailableMetrics first to discover valid metric names and their schemas.\n\n## Quick start\n\n1. Call GetAvailableMetrics to get the list of metric names, measures, and dimensions.\n2. Pick a metric_name (e.g., \"reviews\", \"activation_counts\").\n3. Set partner_id and at least one resource_id (typically a business_id).\n4. Set time_range with start and end_exclusive timestamps.\n5. Set alignment (usually ALIGN_DELTA) and alignment_period (e.g., CALENDAR_MONTH).\n\n## Example: Monthly review counts for a business\n\n{\n \"partner_id\": \"PARTNER-ID\",\n \"metric_name\": \"reviews\",\n \"resource_ids\": [{\"business_id\": {\"business_id\": \"AG-XXXXXXXX\"}}],\n \"time_range\": {\"start\": \"2025-01-01T00:00:00Z\", \"end_exclusive\": \"2026-01-01T00:00:00Z\"},\n \"alignment\": \"ALIGN_DELTA\",\n \"alignment_period\": {\"calendar\": \"CALENDAR_MONTH\"}\n}"
operationId: AnalyticsService_QueryMetrics
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/v1QueryMetricsRequest'
description: Request to query analytics metrics for multi-location businesses with flexible measures, dimensions, time alignment, filtering, grouping, and pagination.
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/v1QueryMetricsResponse'
description: A successful response.
default:
content:
application/json:
schema:
$ref: '#/components/schemas/rpcStatus'
description: An unexpected error response.
security:
- OAuth2:
- business-app
summary: Query Analytics Metrics
tags:
- AnalyticsService
components:
schemas:
rpcStatus:
properties:
code:
format: int32
type: integer
details:
items:
$ref: '#/components/schemas/protobufAny'
type: array
message:
type: string
type: object
MeasureAggregate:
description: Aggregate applies a SQL aggregation function to a measure field.
properties:
aggOp:
$ref: '#/components/schemas/MeasureAggregateOperator'
alias:
description: 'Optional. An alias for the aggregated result in the response schema.
Useful when you have multiple aggregates on the same measure with different filters.'
type: string
filter:
$ref: '#/components/schemas/v1Filter'
measure:
description: The measure field to aggregate. Must be one of the metric's available measures.
type: string
type: object
v1CompositeFilter:
description: A filter that merges multiple other filters using the given operator.
properties:
filters:
description: 'The list of filters to combine.
Must contain at least one filter.'
items:
$ref: '#/components/schemas/v1Filter'
type: array
op:
$ref: '#/components/schemas/v1CompositeFilterOperator'
type: object
v1Order:
default: ORDER_ASC
enum:
- ORDER_ASC
- ORDER_DESC
type: string
v1GroupResourceId:
description: 'A group of businesses identified by a hierarchical path.
Groups allow querying aggregate analytics across multiple business locations.'
properties:
groupPathNodes:
description: The ordered list of group path nodes from root to leaf (e.g., ["root-node", "child-node"]).
items:
type: string
type: array
type: object
v1JWTResourceId:
description: A JWT that encodes a specific user/business combination for authenticated end-user queries.
properties:
jwt:
description: A signed JWT containing partner_id and business_id claims.
type: string
type: object
v1GroupByOperator:
default: OPERATOR_GROUP_BY
enum:
- OPERATOR_GROUP_BY
- OPERATOR_ROLLUP
- OPERATOR_CUBE
title: A Group By Operator
type: string
v1ResourceId:
description: 'ResourceId identifies the scope of a query. Exactly one resource type must be set.
Each resource type determines what data is returned and how it is aggregated.'
properties:
businessId:
$ref: '#/components/schemas/v1BusinessResourceId'
groupId:
$ref: '#/components/schemas/v1GroupResourceId'
jwtId:
$ref: '#/components/schemas/v1JWTResourceId'
marketId:
$ref: '#/components/schemas/v1MarketId'
salesTeam:
$ref: '#/components/schemas/v1SalesTeam'
type: object
MeasureAggregateOperator:
default: AVG
description: " - AVG: Calculate the average value.\n - COUNT: Count the number of rows.\n - SUM: Sum all values.\n - MIN: Get the minimum value.\n - MAX: Get the maximum value.\n - COUNT_DISTINCT: Count unique values.\n - ARRAY_AGG: Collect all values into an array."
enum:
- AVG
- COUNT
- SUM
- MIN
- MAX
- COUNT_DISTINCT
- ARRAY_AGG
type: string
v1MetricResult:
description: A single row of metric data with dimension value, measure values, and optional nested results.
properties:
dimension:
description: 'Output only. The value of the dimension for this row (e.g., a date string, source ID, or rating value).
When alignment is used, the outermost dimension is the time bucket start timestamp.'
readOnly: true
measures:
description: 'Output only. The measure values for this row, in the same order as measures_schema.properties.
Each value corresponds to the property at the same index in the schema.'
items:
type: object
readOnly: true
type: array
results:
$ref: '#/components/schemas/v1Metrics'
title: MetricResult
type: object
GroupByExcludeCombination:
properties:
dimensions:
items:
type: string
type: array
title: 'ExcludeCombination allows a user using ROLLUP OR CUBE to exclude a combination from the result
Example: CUBE (pid, agid) returns the combinations ((pid, agid), (pid), (agid), ()). Providing
ExcludeCombination{dimensions=[pid, agid]} would return the combinations ((pid), (agid), ())'
type: object
vendastatypesProperty:
properties:
description:
title: Description of this property
type: string
name:
title: 'Unique identifier for this property. Must be in snake case format.
Example(s): account_group_id, listing_id, company_name'
type: string
piiTag:
$ref: '#/components/schemas/PropertyPIITag'
properties:
description: 'Can only be specified if the Type supplied is a STRUCT.
Is the schema of the structured property.'
items:
$ref: '#/components/schemas/vendastatypesProperty'
type: array
repeated:
description: Indicates if the field is repeated.
type: boolean
type:
$ref: '#/components/schemas/vendastatypesPropertyType'
title: Property defines a single property for a schema
type: object
v1GroupBy:
properties:
dimension:
items:
$ref: '#/components/schemas/GroupByDimension'
title: A list of dimensions to group by
type: array
excludeCombination:
items:
$ref: '#/components/schemas/GroupByExcludeCombination'
title: Supports excluding a list of combinations
type: array
groupByOperator:
$ref: '#/components/schemas/v1GroupByOperator'
title: Group By is a reducer for aggregating rows into the given dimensions
type: object
GroupByDimension:
properties:
dimension:
type: string
limitDimension:
$ref: '#/components/schemas/GroupByLimit'
title: Dimension specifies which column to group by
type: object
v1CompositeFilterOperator:
default: OPERATOR_UNSPECIFIED
description: "A composite filter operator.\n\n - OPERATOR_UNSPECIFIED: Unspecified. This value must not be used.\n - AND: The results are required to satisfy each of the combined filters.\n - OR: The results are required to satisfy at least one of the combined filters."
enum:
- OPERATOR_UNSPECIFIED
- AND
- OR
type: string
v1SalesTeam:
description: One or more sales team IDs for querying analytics scoped to sales team assignments.
properties:
salesTeamIds:
description: The list of sales team IDs to query.
items:
type: string
type: array
type: object
v1CustomAlignerConfig:
properties:
alignmentBucketFilter:
$ref: '#/components/schemas/v1Filter'
skipFilteringEntitiesToDateRange:
title: 'Whether to skip filtering entities by the time column on the table to the provided date_range.
Usage: date_range is used for both filtering entities and defining the time period to aggregate over.
If true, date_range will only be used to define the aggregation time range (i.e. the last year)
If false, date_range will be used for BOTH filtering entities AND the aggregation time range'
type: boolean
type: object
GroupByLimit:
properties:
dimension:
type: string
limit:
format: int64
type: string
order:
$ref: '#/components/schemas/v1Order'
title: Limit reduces the number of dimensions to the specified amount
type: object
v1Metrics:
description: A list of metric result rows.
properties:
metrics:
items:
$ref: '#/components/schemas/v1MetricResult'
type: array
type: object
v1TypedValue:
description: A message that can hold any of the supported value types.
properties:
value:
title: the value of the field
valueType:
$ref: '#/components/schemas/vendastatypesPropertyType'
type: object
AlignmentPeriodCalendar:
default: UNSPECIFIED
description: "- UNSPECIFIED: No value has been specified.\n - CALENDAR_MINUTE: Align at minute boundaries\n - CALENDAR_HOUR: Align at hour boundaries\n - CALENDAR_DAY: Align at day boundaries\n - CALENDAR_WEEK: Align at week boundaries (where beginning of the week is monday)\n - CALENDAR_MONTH: Align at month boundaries\n - CALENDAR_QUARTER: Align at quarter boundaries\n - CALENDAR_YEAR: Align at year boundaries"
enum:
- UNSPECIFIED
- CALENDAR_MINUTE
- CALENDAR_HOUR
- CALENDAR_DAY
- CALENDAR_WEEK
- CALENDAR_MONTH
- CALENDAR_QUARTER
- CALENDAR_YEAR
type: string
v1DateRange:
properties:
end:
format: date-time
title: '`end` is implicitly inclusive'
type: string
endExclusive:
format: date-time
type: string
start:
format: date-time
title: '`start` is implicitly inclusive'
type: string
startExclusive:
format: date-time
type: string
title: Specifies a range of time for analytics queries
type: object
v1AlignmentPeriod:
properties:
calendar:
$ref: '#/components/schemas/AlignmentPeriodCalendar'
duration:
type: string
type: object
v1MetricDescription:
description: Description of a queryable analytics metric, including its available measures, dimensions, and time field.
properties:
description:
description: Output only. A human-readable description of what this metric measures.
readOnly: true
type: string
dimensions:
items:
type: string
readOnly: true
title: 'Output only. The dimension fields available for this metric. These can be used in QueryMetricsRequest.group_by
and QueryMetricsRequest.filter. Examples: "source_id", "rating", "account_group_id"'
type: array
measures:
items:
type: string
readOnly: true
title: 'Output only. The measure fields available for this metric. These can be used in QueryMetricsRequest.measures
for selection or aggregation. Examples: "scaled_stars", "review_count", "likes"'
type: array
name:
readOnly: true
title: 'Output only. The unique identifier for this metric. Pass this as QueryMetricsRequest.metric_name.
Examples: "reviews", "activation_counts", "facebook_post_stats"'
type: string
timeField:
description: 'Output only. The primary time field used for date range filtering and time alignment.
This is the field that alignment_period and time_range operate on.'
readOnly: true
type: string
title: MetricDescription
type: object
v1FieldFilter:
properties:
comparisonField:
title: A field to compare the dimension to
type: string
dimension:
description: The field to filter by.
type: string
operator:
$ref: '#/components/schemas/v1FieldFilterOperator'
operatorFunction:
$ref: '#/components/schemas/FieldFilterOperatorFunction'
operatorFunctionOnField:
title: Whether to apply the specified operator function to the field, or the value involved in the filter
type: boolean
value:
$ref: '#/components/schemas/v1TypedValue'
title: A filter on a specific field
type: object
OrderByOrderColumn:
properties:
column:
title: Either a dimension or a measure to order by
type: string
order:
$ref: '#/components/schemas/v1Order'
type: object
v1BusinessResourceId:
description: A single business location identified by its account group ID.
properties:
businessId:
description: The account group ID of the business (e.g., "AG-XXXXXXXX").
type: string
type: object
vendastatypesSchema:
properties:
properties:
items:
$ref: '#/components/schemas/vendastatypesProperty'
type: array
title: Schema describes the structure of data in a storage-agnostic way
type: object
v1Filter:
properties:
compositeFilter:
$ref: '#/components/schemas/v1CompositeFilter'
fieldFilter:
$ref: '#/components/schemas/v1FieldFilter'
unaryFilter:
$ref: '#/components/schemas/v1UnaryFilter'
title: A filter
type: object
v1UnaryFilter:
properties:
dimension:
description: The field to which to apply the operator.
type: string
op:
$ref: '#/components/schemas/v1UnaryFilterOperator'
title: A filter with a single operand
type: object
protobufAny:
additionalProperties: {}
properties:
'@type':
type: string
type: object
v1FieldFilterOperator:
default: OPERATOR_UNSPECIFIED
description: " - OPERATOR_UNSPECIFIED: Unspecified. This value must not be used.\n - LESS_THAN: Less than. Requires that the field come first in `order_by`.\n - LESS_THAN_OR_EQUAL: Less than or equal. Requires that the field come first in `order_by`.\n - GREATER_THAN: Greater than. Requires that the field come first in `order_by`.\n - GREATER_THAN_OR_EQUAL: Greater than or equal. Requires that the field come first in\n`order_by`.\n - EQUAL: Equal.\n - OVERLAP: Overlap (have elements in common). Field and values must be lists.\n - NOT_EQUAL: Not Equal."
enum:
- OPERATOR_UNSPECIFIED
- LESS_THAN
- LESS_THAN_OR_EQUAL
- GREATER_THAN
- GREATER_THAN_OR_EQUAL
- EQUAL
- OVERLAP
- NOT_EQUAL
type: string
v1GetAvailableMetricsRequest:
description: Request to retrieve the catalog of available analytics metrics for the given resources.
properties:
partnerId:
description: Required. The partner ID.
type: string
resourceIds:
description: Required. At least one resource ID.
items:
$ref: '#/components/schemas/v1ResourceId'
type: array
required:
- resourceIds
- partnerId
title: GetAvailableMetricsRequest
type: object
v1OrderBy:
properties:
orderBy:
items:
$ref: '#/components/schemas/OrderByOrderColumn'
type: array
type: object
v1QueryMetricsResponse:
description: Response containing analytics metric results for each requested resource.
properties:
metricResults:
description: Output only. Results for each requested resource, in the same order as the request's resource_ids.
items:
$ref: '#/components/schemas/v1ResourceMetricResult'
readOnly: true
type: array
title: QueryMetricsResponse
type: object
v1QueryMetricsRequest:
description: Request to query analytics metrics for multi-location businesses with flexible measures, dimensions, time alignment, filtering, grouping, and pagination.
properties:
alignment:
$ref: '#/components/schemas/v1Alignment'
alignmentPeriod:
$ref: '#/components/schemas/v1AlignmentPeriod'
cursor:
description: 'Optional. Pagination cursor from a previous response''s ResourceMetricResult.cursor.
Pass an empty string or omit to start from the beginning.'
type: string
customAligner:
$ref: '#/components/schemas/v1CustomAlignerConfig'
dateRange:
$ref: '#/components/schemas/v1DateRange'
filter:
$ref: '#/components/schemas/v1Filter'
groupBy:
$ref: '#/components/schemas/v1GroupBy'
limit:
description: 'Optional. Maximum number of result rows to return. 0 means no limit.
Use with order_by for "top N" queries (e.g., top 10 businesses by review count).'
format: int64
type: string
measures:
description: 'Optional. The measures to select or aggregate from the metric.
Each metric has a set of available measures (returned by GetAvailableMetrics).
If omitted, all default measures for the metric are returned.
Use Measure.measure for raw selection (e.g., "scaled_stars") or
Measure.aggregate for aggregations (e.g., AVG of "scaled_stars").'
items:
$ref: '#/components/schemas/v1Measure'
type: array
metricName:
title: 'Required. The name of the metric to query. Must be one of the names returned by GetAvailableMetrics.
Examples: "reviews", "activation_counts", "facebook_post_stats", "net_promoter_score"'
type: string
orderBy:
$ref: '#/components/schemas/v1OrderBy'
partnerId:
description: Required. The partner ID to scope the query to. All queries are scoped to a single partner.
type: string
resourceIds:
description: 'Required. At least one resource ID to scope the query to. Multiple resource IDs of the same type
can be provided to query across multiple businesses, groups, or markets in a single call.'
items:
$ref: '#/components/schemas/v1ResourceId'
type: array
timeRange:
$ref: '#/components/schemas/v1DateRange'
required:
- partnerId
- metricName
- resourceIds
title: QueryMetricsRequest
type: object
v1Alignment:
default: ALIGN_NONE
description: " - ALIGN_NONE: No alignment.\n - ALIGN_DELTA: Align and convert to delta metric type. This alignment is valid\nfor delta metrics. Aligning an existing delta metric to a delta metric\nrequires that the alignment period be increased. The value type of the\nresult is the same as the value type of the input.\n\nOne can think of this aligner as a rate but without time units; that\nis, the output is conceptually (second_point - first_point).\n - ALIGN_INTERPOLATE: Align by interpolating between adjacent points around the\nperiod boundary. This alignment is valid for gauge\nmetrics with numeric values. The value type of the result is the same\nas the value type of the input.\n - ALIGN_NEXT_OLDER: Align by shifting the oldest data point before the period\nboundary to the boundary. This alignment is valid for gauge\nmetrics. The value type of the result is the same as the\nvalue type of the input.\n - ALIGN_EXACT: Align by using data points that fall on the same UTC day of the period boundary.\nThis alignment is valid for daily gauge metrics.\nThe value type of the result is the same as the value type of the input.\n - ALIGN_CUSTOM: Allows the user to specify custom alignment logic, allowing the query to make more complex decisions on which\ntime/date bucket(s) a row should be placed in.\nThis is useful when your table has multiple columns that need to be considered when bucketing rows into time\nbuckets, such as a created and deleted date.\nThe custom aligner allows you to bucket these rows based on their status at one of the bucket boundaries or\nwithin the bucket."
enum:
- ALIGN_NONE
- ALIGN_DELTA
- ALIGN_INTERPOLATE
- ALIGN_NEXT_OLDER
- ALIGN_EXACT
- ALIGN_CUSTOM
type: string
PropertyPIITag:
default: PROPERTY_PII_TAG_CLEAN
description: "PIITag defines potential PII tags.\n\n - PROPERTY_PII_TAG_CLEAN: clean means the data is not PII or PD.\n - PROPERTY_PII_TAG_PII: PII means Personally Identifiable Information. It is information that can be used to retrieve personal data, such as IAM user ID.\n - PROPERTY_PII_TAG_PD: PD means personal data, such as name, email and address. They are sensitive data we need to protect in our system."
enum:
- PROPERTY_PII_TAG_CLEAN
- PROPERTY_PII_TAG_PII
- PROPERTY_PII_TAG_PD
type: string
vendastatypesPropertyType:
default: PROPERTY_TYPE_STRING
enum:
- PROPERTY_TYPE_STRING
- PROPERTY_TYPE_INT64
- PROPERTY_TYPE_DOUBLE
- PROPERTY_TYPE_BOOL
- PROPERTY_TYPE_TIMESTAMP
- PROPERTY_TYPE_GEOPOINT
- PROPERTY_TYPE_STRUCT
- PROPERTY_TYPE_BYTES
type: string
FieldFilterOperatorFunction:
default: NONE
description: "- NONE: No function will be applied to the values\n - ANY: Any value in the list must pass the filter\n - ALL: All values in the list must pass the filter"
enum:
- NONE
- ANY
- ALL
type: string
v1ResourceMetricResult:
description: Analytics result for a single resource, including data, schemas, and pagination cursor.
properties:
cursor:
description: 'Output only. Pagination cursor. Pass this value as QueryMetricsRequest.cursor to fetch the next page.
Empty when there are no more results.'
readOnly: true
type: string
dimensionsSchema:
$ref: '#/components/schemas/vendastatypesSchema'
explodedMetrics:
$ref: '#/components/schemas/v1QueryMetricsResponse'
measuresSchema:
$ref: '#/components/schemas/vendastatypesSchema'
metrics:
$ref: '#/components/schemas/v1Metrics'
resourceId:
$ref: '#/components/schemas/v1ResourceId'
title: ResourceMetricResult
type: object
v1Measure:
description: 'Measure selects or aggregates a field from the metric''s available measures.
Use GetAvailableMetrics to discover which measure names are valid for each metric.
Example: Select a raw measure
{"measure": "scaled_stars"}
Example: Aggregate a measure
{"aggregate": {"measure": "scaled_stars", "agg_op": "AVG"}}
Example: Count distinct values with an alias
{"aggregate": {"measure": "account_group_id", "agg_op": "COUNT_DISTINCT", "alias": "unique_businesses"}}'
properties:
aggregate:
$ref: '#/components/schemas/MeasureAggregate'
measure:
title: 'Select a measure field as-is without aggregation. Example: "scaled_stars"'
type: string
type: object
v1GetAvailableMetricsResponse:
description: The catalog of available analytics metrics with their schemas.
properties:
metrics:
description: 'Output only. All available metrics with their schemas. Use this to discover valid metric names,
measures, and dimensions for building QueryMetricsRequest messages.'
items:
$ref: '#/components/schemas/v1MetricDescription'
readOnly: true
type: array
title: GetAvailableMetricsResponse
type: object
v1UnaryFilterOperator:
default: OPERATOR_UNSPECIFIED
description: "A unary operator.\n\n - OPERATOR_UNSPECIFIED: Unspecified. This value must not be used.\n - IS_NAN: Test if a field is equal to NaN.\n - IS_NULL: Test if an expression evaluates to Null.\n - IS_NOT_NULL: Test if an expression evaluates to Not Null."
enum:
- OPERATOR_UNSPECIFIED
- IS_NAN
- IS_NULL
- IS_NOT_NULL
type: string
v1MarketId:
description: 'One or more market IDs. Markets are geographic or logical groupings of businesses within a partner.
When market_ids is empty, the query returns data across ALL markets for the partner (partner-wide query).'
properties:
marketIds:
description: The list of market IDs to query. An empty list means all markets for the partner.
items:
type: string
type: array
type: object
securitySchemes:
OAuth2:
flows:
authorizationCode:
authorizationUrl: https://sso-api-prod.apigateway.co/oauth2/auth
scopes:
business-app: Allows the application to manage all features of Business App
tokenUrl: https://sso-api-prod.apigateway.co/oauth2/token
type: oauth2