Skip to Content
APIEndpointsCompetitor rankings

Competitor rankings

The leaderboard. Your brand and every active competitor, ranked by visibility, each with market share, sentiment and average first-mention rank. Rank 1 is the most visible.

With compare_to_previous you also get per-row deltas and a movers block naming who gained and who lost — which is usually the actual question behind “how are we doing”.

GET /v1/brands/{brand_id}/competitors/rankings

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.
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.
topic_iduuid, repeatableoptionalRestrict to these topics. From List topics. Includes the topic and its subtopics. A root topic returns everything beneath it; a subtopic returns only itself. Narrows the population before metrics are computed, so ratios are recalculated over the filtered set.
enginestring, repeatableoptionalRestrict to these AI search engines, by slug. From List engines. Narrows the population before metrics are computed.
countrystring, repeatableoptionalRestrict to these execution country codes. Narrows the population before metrics are computed.
tag_iduuid, repeatableoptionalRestrict to prompts carrying these tags. From List tags. Narrows the population before metrics are computed.
tag_match_modestringoptionalHow to combine tag_id values. Defaults to ‘any’. One of: any, all.

Request

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

Response

{ "data": [ { "rank": 1, "name": "Asky", "is_our_brand": true, "visibility_pct": 34.2, "market_share_pct": 24.1, "sentiment_score": 71.4, "avg_rank": 2.8, "previous": { "rank": 2, "visibility_pct": 29.7, "market_share_pct": 22 }, "rank_change": 1, "visibility_delta": 4.5, "market_share_delta": 2.1 } ], "pagination": { "limit": 20, "has_more": true, "next_cursor": "eyJ2IjoxLCJvIjoyMCwibCI6MjB9" }, "meta": { "period": { "start_date": "2026-08-06", "end_date": "2026-08-13" }, "brand_id": "242546de-4cee-4a7d-952e-f6aa60c63ef8", "total_competitors": 6, "previous_period": { "start_date": "2026-07-30", "end_date": "2026-08-06" }, "movers": { "gainers": [ { "name": "Asky", "is_our_brand": true, "visibility_delta": 4.5, "market_share_delta": 2.1 } ], "losers": [] } }, "request_id": "req_c72f18e0b34a49d5812c" }

Response fields

FieldTypeDescription
data.brand_iduuidrequired
data.periodobjectrequired. { start_date, end_date } actually used. Read it before comparing endpoints — their defaults differ
data.rankingsobject[]required, rank ascending
data.rankings[].rankintegerrequired. 1 is most visible
data.rankings[].namestringrequired
data.rankings[].is_our_brandbooleanrequired. Your row is in this list
data.rankings[].visibility_pctnumber | null
data.rankings[].market_share_pctnumber | nullShare of voice by mention count
data.rankings[].sentiment_scorenumber | null0–100
data.rankings[].avg_ranknumber | nullAverage first-mention position
data.rankings[].rank_changeinteger | nullOnly with compare. Positive means climbed
data.total_competitorsintegerrequired. Excludes your own row
data.moversobjectOnly with compare. { gainers, losers }, computed over the full set rather than the returned page
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

movers is computed over every entity, not just the returned page. Paging with limit never changes who is reported as a mover.

Your own brand is a row in rankings, flagged with is_our_brand. A leaderboard that omitted the subject would force every client to merge two responses to draw one table.

Last updated on