Topic scoreboard
Every topic and subtopic in one call, each with its visibility, its change against the prior window, the leading competitor, the gap to them, and how much open work it carries.
This is the closest thing on the surface to a to-do list: it answers “which topics need attention” without you first knowing which topics to ask about.
GET /v1/brands/{brand_id}/topics/scoreboardAuthorization
| Header | Type | Required |
|---|---|---|
Authorization | Bearer asky_sk_… | required |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
brand_id | uuid | required | From List brands |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | optional | Rows per page, 1 to 100. Defaults to 20. |
cursor | string | optional | Opaque cursor from the previous response. Treat it as a token, never construct one. |
window_days | integer | optional | Lookback window in days. |
Request
cURL
curl --request GET \
--url 'https://api.askylabs.com/v1/brands/242546de-4cee-4a7d-952e-f6aa60c63ef8/topics/scoreboard?window_days=28' \
--header 'Authorization: Bearer <api-key>'Response
200
{
"data": [
{
"topic_id": "4beb0694-7c2e-488b-84c1-613738e7eaf6",
"topic_name": "AI Visibility Tracking",
"parent_topic_id": null,
"is_subtopic": false,
"visibility_pct": 41.2,
"previous_visibility_pct": 36.8,
"visibility_delta_pts": 4.4,
"top_competitor_name": "Peec AI",
"top_competitor_visibility_pct": 33.1,
"gap_pts": -8.1,
"our_rank": 1,
"max_rank": 7,
"prompt_count": 34,
"citation_count": 128,
"open_content_actions": 2,
"open_task_count": 1,
"has_enough_data": true
}
],
"pagination": {
"limit": 20,
"has_more": true,
"next_cursor": "eyJ2IjoxLCJvIjoyMCwibCI6MjB9"
},
"meta": {
"window": {
"days": 28,
"start_date": "2026-07-16"
}
},
"request_id": "req_38b7ea15c9024fd0a6e3"
}Response fields
| Field | Type | Description |
|---|---|---|
data.window | object | required. { days, start_date } |
data.topics | object[] | required |
data.topics[].topic_id | uuid | required |
data.topics[].topic_name | string | required |
data.topics[].parent_topic_id | uuid | null | |
data.topics[].is_subtopic | boolean | required |
data.topics[].visibility_pct | number | null | |
data.topics[].previous_visibility_pct | number | null | |
data.topics[].visibility_delta_pts | number | null | Change in percentage points |
data.topics[].top_competitor_name | string | null | Whoever leads this topic |
data.topics[].top_competitor_visibility_pct | number | null | |
data.topics[].gap_pts | number | null | Signed. Positive means they are ahead, negative means you lead |
data.topics[].our_rank | integer | null | |
data.topics[].max_rank | integer | null | How many entities are ranked on this topic |
data.topics[].prompt_count | integer | required |
data.topics[].citation_count | integer | required |
data.topics[].open_content_actions | integer | required |
data.topics[].open_task_count | integer | required |
data.topics[].has_enough_data | boolean | required. See the note below |
data.count | integer | required |
request_id | string | required. Also returned as the x-request-id header. Quote it when contacting support |
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | A parameter is unknown or malformed. The message names it |
| 401 | invalid_token | The key is missing, malformed, or does not exist |
| 401 | token_expired | The key passed its expiry date |
| 401 | token_revoked | The key was revoked |
| 404 | not_found | The brand does not exist, or this key is not allowed to reach it. The two are deliberately indistinguishable |
| 429 | rate_limited | Over 300 requests per minute. See the Retry-After header |
Notes
Filter on has_enough_data before ranking anything. It applies the product’s own eligibility
floor — at least 2 prompts and 5 citations in the window. Thin topics produce wild percentages and
will dominate any “worst topics” list if you let them.
gap_pts is signed the way it reads: positive means the leading competitor is ahead of you.
Not paginated. A brand carries at most a few dozen topics, and the whole tree is returned.