Skip to Content
APIEndpointsVisibility by topic or market

Visibility by topic or market

The same breakdown as by engine, cut instead by topic or by market. This is the “where should we focus” call.

One request replaces a filtered analytics call per topic, which is what makes it practical to look at every segment rather than the three you already suspected.

GET /v1/brands/{brand_id}/visibility/segments

Authorization

HeaderTypeRequired
AuthorizationBearer asky_sk_…required

Path parameters

ParameterTypeRequiredDescription
brand_iduuidrequiredFrom List brands

Query parameters

ParameterTypeRequiredDescription
limitintegeroptionalRows per page, 1 to 100. Defaults to 20.
cursorstringoptionalOpaque cursor from the previous response. Treat it as a token, never construct one.
dimensionstringrequiredWhat to segment by. One of: topic, market. No default. The two dimensions answer different questions.
start_dateYYYY-MM-DDoptionalInclusive lower bound, YYYY-MM-DD in UTC. Narrows the population before metrics are computed.
end_dateYYYY-MM-DDoptionalInclusive upper bound, YYYY-MM-DD in UTC. Narrows the population before metrics are computed.
compare_to_previousbooleanoptionalAlso return the prior equal-length period and per-row deltas.

Request

curl --request GET \ --url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/visibility/segments?dimension=topic' \ --header 'Authorization: Bearer <api-key>'

Response

{ "data": [ { "segment": "AI Visibility Tracking", "topic_id": "4beb0694-7c2e-488b-84c1-613738e7eaf6", "executions": 410, "visibility_pct": 41.2, "market_share_pct": 26.9, "sentiment": 73, "leader": "Asky", "top_competitors": [ { "name": "Peec AI", "rank": 2, "visibility_pct": 33.1, "market_share_pct": 21.4 } ] } ], "pagination": { "limit": 20, "has_more": true, "next_cursor": "eyJ2IjoxLCJvIjoyMCwibCI6MjB9" }, "meta": { "period": { "start_date": "2026-08-06", "end_date": "2026-08-13" }, "dimension": "topic", "brand_id": "242546de-4cee-4a7d-952e-f6aa60c63ef8", "omitted_segments": 3 }, "request_id": "req_e6c018b47d2a4931b70f" }

Response fields

FieldTypeDescription
data.brand_iduuidrequired
data.dimensionstringrequired. Echoes the request
data.periodobjectrequired. { start_date, end_date } actually used. Read it before comparing endpoints — their defaults differ
data.segmentsobject[]required, ordered by executions
data.segments[].segmentstringrequired. Topic name or country code
data.segments[].topic_iduuidOnly when dimension=topic. Chains into topic_id filters elsewhere
data.segments[].executionsintegerrequired
data.segments[].visibility_pctnumber | nullYour visibility in this segment
data.segments[].market_share_pctnumber | null
data.segments[].sentimentnumber | null
data.segments[].leaderstring | nullRank-1 entity in this segment
data.segments[].top_competitorsobject[]required
data.omitted_segmentsintegerSegments cut by segment_limit or beyond the fan-out bound
data.unavailable_segmentsstring[]Could not be read on this attempt
data.unavailable_notestringPlain-language warning shipped alongside unavailable_segments
request_idstringrequired. Also returned as the x-request-id header. Quote it when contacting support

Errors

StatusCodeWhen
400invalid_requestA parameter is unknown or malformed. The message names it
401invalid_tokenThe key is missing, malformed, or does not exist
401token_expiredThe key passed its expiry date
401token_revokedThe key was revoked
404not_foundThe brand does not exist, or this key is not allowed to reach it. The two are deliberately indistinguishable
429rate_limitedOver 300 requests per minute. See the Retry-After header

Notes

unavailable_segments is not zero. The response ships an explicit unavailable_note saying so, because reading a transient read failure as “we have no presence there” is the exact mistake this data invites.

omitted_segments > 0 means you are seeing a slice. Raise segment_limit or accept that the tail is missing; do not treat the returned set as exhaustive.

Last updated on