Visibility
Measure brand visibility, compare competitors, and track performance trends across AI models for a project or location.
models.GETGet visibility overview
/projects/{project_id}/visibility/summaryReturns aggregate visibility and citation metrics for matching responses in the selected project.
Get visibility overview
/projects/{project_id}/visibility/summaryPath parameters
project_idproject UUID | project external IDProject identifier.
Query parameters
startdateFirst run date to include, in YYYY-MM-DD format.
enddateLast run date to include, in YYYY-MM-DD format.
modelsstringComma-separated or repeated model keys, such as chatgpt,claude,perplexity.
topic_idsstringComma-separated or repeated topic UUIDs.
topic_iduuidAlias for topic_ids when filtering by one topic UUID.
prompt_iduuidRestrict results to one prompt in the selected scope.
Response envelope
start:dateend:datemodels:string[]summary:objectstartdateResolved start date.
enddateResolved end date.
modelsstring[]Model keys included in the calculation. When omitted from the request, this contains every model key present in matching responses.
summaryobjectAggregate visibility metrics.
Summary object
primary_mentionsintegerResponses in which the primary tracked entity was mentioned.
visibility_percentagenumberShare of responses that mentioned the primary tracked entity, rounded to two decimals.
average_positionnumber | nullAverage 1-based position for primary-entity mentions with a detected position.
citationsintegerTotal citation occurrences across matching responses.
visibility_percentage is the share of matching responses that mention the primary entity. average_position uses only primary mentions with a detected position, and citations counts citation occurrences.Request and response
curl --request GET \
--url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/visibility/summary?start=2026-07-24&end=2026-07-30&models=chatgpt,perplexity' \
--header 'Authorization: Bearer ceyo_platform_...'{
"start": "2026-07-24",
"end": "2026-07-30",
"models": ["chatgpt", "perplexity"],
"summary": {
"primary_mentions": 17,
"visibility_percentage": 42.5,
"average_position": 2.82,
"citations": 31
}
}ErrorsResponse format and status codes
Error response envelope
errorErrorStructured error payload.
Error
codestringStable snake_case code suitable for programmatic handling.
messagestringHuman-readable explanation of the failure.
detailsobject | array | nullStructured validation or request context when available.
request_idstringIdentifier to provide when requesting support.
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid.",
"details": [
{
"field": "name",
"message": "must be present"
}
],
"request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
}
}Status codes
400invalid_date_range | range_too_largeA date is invalid or the requested window exceeds three months.
401invalid_api_keyThe Bearer API key is missing or invalid.
403forbiddenThe API key is valid but is not allowed to access this resource.
404not_foundThe project, location, or visibility scope was not found.
422visibility_unavailableProject-level visibility is unavailable for a locations-only container; use a location scope.
429rate_limit_exceededToo many requests were made.
GETCompare competitors
/projects/{project_id}/visibility/competitorsCompares the primary entity plus tracked competitors for the selected project, ordered with primary first, then by share_of_voice descending and name.
Compare competitors
/projects/{project_id}/visibility/competitorsPath parameters
project_idproject UUID | project external IDProject identifier.
Query parameters
startdateFirst run date to include, in YYYY-MM-DD format.
enddateLast run date to include, in YYYY-MM-DD format.
modelsstringComma-separated or repeated model keys, such as chatgpt,claude,perplexity.
topic_idsstringComma-separated or repeated topic UUIDs.
topic_iduuidAlias for topic_ids when filtering by one topic UUID.
prompt_iduuidRestrict results to one prompt in the selected scope.
Response envelope
start:dateend:datemodels:string[]total_mentions:integerentities:object[]startdateResolved start date.
enddateResolved end date.
modelsstring[]Model keys included in the calculation. When omitted from the request, this contains every model key present in matching responses.
total_mentionsintegerMentions across all returned entities.
entitiesobject[]The primary entity plus tracked competitors, ordered with primary first, then by share_of_voice descending and name.
Entity
tracked_entity_iduuidTracked primary brand or competitor identifier.
kindprimary | competitorEntity relationship to the selected scope.
namestringTracked entity name.
domainstring | nullNormalized entity domain when configured.
statusactiveCurrent tracked-entity status. Only active entities are returned.
mentionsintegerResponses in which this entity was mentioned.
coverage_percentagenumberShare of matching responses that mentioned the entity.
share_of_voicenumberEntity mentions divided by mentions across all returned entities, multiplied by 100.
average_positionnumber | nullAverage detected 1-based position when the entity was mentioned.
share_of_voice descending and then name. When there are no mentions, both percentages are 0.0 and average position is null.Request and response
curl --request GET \
--url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/visibility/competitors?start=2026-07-24&end=2026-07-30&topic_ids=ab20526b-6bb2-436c-8c93-5bf77ea43848' \
--header 'Authorization: Bearer ceyo_platform_...'{
"start": "2026-07-24",
"end": "2026-07-30",
"models": ["chatgpt", "perplexity"],
"total_mentions": 33,
"entities": [
{
"tracked_entity_id": "f3385d92-8f24-49f2-9819-18412e93427f",
"kind": "primary",
"name": "Ceyo",
"domain": "ceyo.ai",
"status": "active",
"mentions": 17,
"coverage_percentage": 42.5,
"share_of_voice": 51.52,
"average_position": 2.82
},
{
"tracked_entity_id": "2e230599-4918-49a7-bb08-b30711836aa8",
"kind": "competitor",
"name": "Example Competitor",
"domain": "competitor.example",
"status": "active",
"mentions": 16,
"coverage_percentage": 40.0,
"share_of_voice": 48.48,
"average_position": 3.13
}
]
}ErrorsResponse format and status codes
Error response envelope
errorErrorStructured error payload.
Error
codestringStable snake_case code suitable for programmatic handling.
messagestringHuman-readable explanation of the failure.
detailsobject | array | nullStructured validation or request context when available.
request_idstringIdentifier to provide when requesting support.
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid.",
"details": [
{
"field": "name",
"message": "must be present"
}
],
"request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
}
}Status codes
400invalid_date_range | range_too_largeA date is invalid or the requested window exceeds three months.
401invalid_api_keyThe Bearer API key is missing or invalid.
403forbiddenThe API key is valid but is not allowed to access this resource.
404not_foundThe project, location, or visibility scope was not found.
422visibility_unavailableProject-level visibility is unavailable for a locations-only container; use a location scope.
429rate_limit_exceededToo many requests were made.
GETGet competitor trends
/projects/{project_id}/visibility/competitors/timeseriesReturns dated coverage, mention, and position series for the primary entity and competitors in the selected project.
Get competitor trends
/projects/{project_id}/visibility/competitors/timeseriesPath parameters
project_idproject UUID | project external IDProject identifier.
Query parameters
startdateFirst run date to include, in YYYY-MM-DD format.
enddateLast run date to include, in YYYY-MM-DD format.
modelsstringComma-separated or repeated model keys, such as chatgpt,claude,perplexity.
topic_idsstringComma-separated or repeated topic UUIDs.
topic_iduuidAlias for topic_ids when filtering by one topic UUID.
prompt_iduuidRestrict results to one prompt in the selected scope.
Response envelope
start:dateend:datemodels:string[]entities:object[]points:object[]startdateResolved start date.
enddateResolved end date.
modelsstring[]Model keys included in the calculation. When omitted from the request, this contains every model key present in matching responses.
entitiesobject[]Metadata for each keyed series.
pointsobject[]One point for each date containing matching responses.
Timeseries entity
keystringStable series key in the form entity:{tracked_entity_id}.
tracked_entity_iduuidTracked entity identifier.
kindprimary | competitorEntity relationship to the selected scope.
namestringTracked entity name.
domainstring | nullNormalized entity domain when configured.
aliasesstring[]Additional names recognized as mentions of this entity.
Timeseries point
datedateVisibility measurement date.
mentionsobjectMention count keyed by entity series key.
average_positionsobjectAverage 1-based position or null, keyed by entity series key.
mentions and average_positions to entity metadata through key. Dates without matching responses are omitted; returned entity values are zero-filled for dates that have responses.Request and response
curl --request GET \
--url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/visibility/competitors/timeseries?start=2026-07-24&end=2026-07-30&models=chatgpt,perplexity' \
--header 'Authorization: Bearer ceyo_platform_...'{
"start": "2026-07-24",
"end": "2026-07-30",
"models": ["chatgpt", "perplexity"],
"entities": [
{
"key": "entity:f3385d92-8f24-49f2-9819-18412e93427f",
"tracked_entity_id": "f3385d92-8f24-49f2-9819-18412e93427f",
"kind": "primary",
"name": "Ceyo",
"domain": "ceyo.ai",
"aliases": ["Ceyo AI"]
}
],
"points": [
{
"date": "2026-07-30",
"mentions": {
"entity:f3385d92-8f24-49f2-9819-18412e93427f": 4
},
"average_positions": {
"entity:f3385d92-8f24-49f2-9819-18412e93427f": 2.5
}
}
]
}ErrorsResponse format and status codes
Error response envelope
errorErrorStructured error payload.
Error
codestringStable snake_case code suitable for programmatic handling.
messagestringHuman-readable explanation of the failure.
detailsobject | array | nullStructured validation or request context when available.
request_idstringIdentifier to provide when requesting support.
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid.",
"details": [
{
"field": "name",
"message": "must be present"
}
],
"request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
}
}Status codes
400invalid_date_range | range_too_largeA date is invalid or the requested window exceeds three months.
401invalid_api_keyThe Bearer API key is missing or invalid.
403forbiddenThe API key is valid but is not allowed to access this resource.
404not_foundThe project, location, or visibility scope was not found.
422visibility_unavailableProject-level visibility is unavailable for a locations-only container; use a location scope.
429rate_limit_exceededToo many requests were made.
GETGet model visibility trends
/projects/{project_id}/visibility/model-trendsReturns daily and range-level primary-brand visibility by model, plus an aggregate across models, for the selected project.
Get model visibility trends
/projects/{project_id}/visibility/model-trendsPath parameters
project_idproject UUID | project external IDProject identifier.
Query parameters
startdateFirst run date to include, in YYYY-MM-DD format.
enddateLast run date to include, in YYYY-MM-DD format.
modelsstringComma-separated or repeated model keys, such as chatgpt,claude,perplexity.
topic_idsstringComma-separated or repeated topic UUIDs.
topic_iduuidAlias for topic_ids when filtering by one topic UUID.
prompt_iduuidRestrict results to one prompt in the selected scope.
Response envelope
start:dateend:datemodels:string[]aggregate:objectmodel_summaries:object[]days:object[]startdateResolved start date.
enddateResolved end date.
modelsstring[]Model keys included in the calculation. When omitted from the request, this contains every model key present in matching responses.
aggregateobjectPrimary-brand visibility across all returned models.
model_summariesobject[]Range-level primary-brand visibility for each returned model, ordered by model key.
daysobject[]Daily primary-brand visibility in ascending date order. Dates without matching responses are omitted.
Aggregate object
mentionsintegerResponses in which the primary tracked brand was mentioned across all returned models.
visibility_percentagenumberShare of responses that mentioned the primary tracked brand, rounded to two decimals.
comparisonobject | nullComparison with the immediately preceding window of the same length, or null when that window has no matching responses.
Model summary object
modelstringStable model key.
mentionsintegerResponses for this model in which the primary tracked brand was mentioned.
visibility_percentagenumberShare of this model’s responses that mentioned the primary tracked brand, rounded to two decimals.
comparisonobject | nullComparison with the same model in the immediately preceding window, or null when that model has no matching responses in the comparison window.
Daily object
datedateVisibility measurement date in YYYY-MM-DD format.
aggregateobjectPrimary-brand visibility across all returned models for this date.
modelsobject[]Primary-brand visibility for each returned model on this date, ordered by model key.
Daily aggregate object
mentionsintegerResponses across all returned models that mentioned the primary tracked brand on this date.
visibility_percentagenumberShare of responses that mentioned the primary tracked brand on this date.
Daily model object
modelstringStable model key.
mentionsintegerResponses for this model that mentioned the primary tracked brand on this date.
visibility_percentagenumberShare of this model’s responses that mentioned the primary tracked brand on this date.
Comparison object
startdateFirst date of the immediately preceding comparison window.
enddateLast date of the immediately preceding comparison window.
mentionsintegerResponses that mentioned the primary tracked brand in the comparison window.
visibility_percentagenumberPrimary-brand visibility in the comparison window, expressed as a percentage from 0 to 100.
delta_percentage_pointsnumberSelected-window visibility_percentage minus comparison-window visibility_percentage, in percentage points.
visibility_percentage is a value from 0 to 100 calculated as the share of responses that mention the primary brand. Range-level comparisons use the immediately preceding window of equal length. A positive delta_percentage_points means visibility increased. Dates without matching responses are omitted.Request and response
curl --request GET \
--url 'https://api.signal.ceyo.ai/v1/projects/{project_id}/visibility/model-trends?start=2026-07-24&end=2026-07-30&models=chatgpt,perplexity' \
--header 'Authorization: Bearer ceyo_platform_...'{
"start": "2026-07-24",
"end": "2026-07-30",
"models": ["chatgpt", "perplexity"],
"aggregate": {
"mentions": 17,
"visibility_percentage": 42.5,
"comparison": {
"start": "2026-07-17",
"end": "2026-07-23",
"mentions": 14,
"visibility_percentage": 36.84,
"delta_percentage_points": 5.66
}
},
"model_summaries": [
{
"model": "chatgpt",
"mentions": 10,
"visibility_percentage": 50.0,
"comparison": {
"start": "2026-07-17",
"end": "2026-07-23",
"mentions": 8,
"visibility_percentage": 42.11,
"delta_percentage_points": 7.89
}
},
{
"model": "perplexity",
"mentions": 7,
"visibility_percentage": 35.0,
"comparison": {
"start": "2026-07-17",
"end": "2026-07-23",
"mentions": 6,
"visibility_percentage": 31.58,
"delta_percentage_points": 3.42
}
}
],
"days": [
{
"date": "2026-07-30",
"aggregate": {
"mentions": 4,
"visibility_percentage": 50.0
},
"models": [
{
"model": "chatgpt",
"mentions": 3,
"visibility_percentage": 75.0
},
{
"model": "perplexity",
"mentions": 1,
"visibility_percentage": 25.0
}
]
}
]
}ErrorsResponse format and status codes
Error response envelope
errorErrorStructured error payload.
Error
codestringStable snake_case code suitable for programmatic handling.
messagestringHuman-readable explanation of the failure.
detailsobject | array | nullStructured validation or request context when available.
request_idstringIdentifier to provide when requesting support.
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid.",
"details": [
{
"field": "name",
"message": "must be present"
}
],
"request_id": "req_01K1GP6J8QQFZ4D2B6C5A9V3TS"
}
}Status codes
400invalid_date_range | range_too_largeA date is invalid or the requested window exceeds three months.
401invalid_api_keyThe Bearer API key is missing or invalid.
403forbiddenThe API key is valid but is not allowed to access this resource.
404not_foundThe project, location, or visibility scope was not found.
422visibility_unavailableProject-level visibility is unavailable for a locations-only container; use a location scope.
429rate_limit_exceededToo many requests were made.