Skip to Content
APIEndpointsPrompt metrics

Prompt metrics

How each individual prompt performed over a window. Join prompt_id against List prompts for the text — this endpoint returns numbers only, so the two together are the full picture without either being heavy.

With compare_to_previous you also get a movers block: the prompts that gained and lost the most. That is usually what you actually want when a headline visibility number has moved and you need to know which questions caused it.

GET /v1/brands/{brand_id}/prompts/metrics

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.
movers_limitintegeroptionalMax gainers and losers returned, default 10.
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.
include_adsbooleanoptionalAlso return the advertisers running against each prompt as an advertisers array. Caps limit at 25. The advertisers array is the largest field this endpoint returns, so the default 100-row page is refused rather than truncated.

Request

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

Response

{ "data": [ { "prompt_id": "7c2f5a91-3b8e-4d06-9a44-1e7b30c9f852", "visibility_share": 0.412, "citation_rate": 0.238, "avg_ranking": 2.4, "previous_visibility_share": 0.361, "visibility_share_delta": 0.051, "previous_citation_rate": 0.201, "citation_rate_delta": 0.037, "previous_avg_ranking": 2.9, "avg_ranking_delta": -0.5 } ], "pagination": { "limit": 20, "has_more": true, "next_cursor": "eyJ2IjoxLCJvIjoyMCwibCI6MjB9" }, "meta": { "period": { "start_date": "2026-07-14", "end_date": "2026-08-13" }, "movers": { "top_gainers": [ { "prompt_id": "7c2f5a91-3b8e-4d06-9a44-1e7b30c9f852", "visibility_share": 0.412, "previous_visibility_share": 0.361, "visibility_share_delta": 0.051 } ], "top_losers": [] }, "newly_active": [], "newly_inactive": [] }, "request_id": "req_9b3c07e5f1284ad6b0c9" }

Response fields

FieldTypeDescription
data.periodobjectrequired. { start_date, end_date } actually used. Defaults differ between endpoints, so read it before comparing
data.metricsobject[]required
data.metrics[].prompt_iduuidrequired
data.metrics[].visibility_sharenumberrequired. Share of answers to this prompt naming you
data.metrics[].citation_ratenumberrequired
data.metrics[].avg_rankingnumber | null1-based, lower is better. null when never named
data.metrics[].chatgpt_response_countintegerrequired. ChatGPT answers collected for this prompt in the window
data.metrics[].ad_eligible_response_countintegerrequired. Of those, the ones in a market where OpenAI actually serves ads. The denominator behind ad_rate
data.metrics[].ads_response_countintegerrequired. Answers that carried at least one sponsored card
data.metrics[].ad_ratenumber | null0 to 100. null, not 0, when ad_eligible_response_count is 0 — there is no denominator, which is different from “ads never appeared”
data.metrics[].advertisersobject[]Present only with include_ads. Up to 25 {domain, name, n, is_own_brand}, your own brand first and then most frequent, where n is how many answers that advertiser appeared in. is_own_brand is true when the ad points at one of your own domains, i.e. you are bidding against your own prompt. domain is null when the card carried no link and the group fell back to the advertiser name
data.totalintegerrequired
data.limitintegerrequired
data.offsetintegerrequired
data.has_morebooleanrequired
data.moversobjectOnly with compare. { top_gainers, top_losers }
data.newly_activeuuid[]Prompts with data this period but not the previous one
data.newly_inactiveuuid[]The reverse. Often the more urgent list
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

A prompt with no completed execution in the window is absent, not zero. Do not read a missing row as a score of nought — it means the prompt did not run.

movers and the newly-active lists are computed over the full set, not the page you fetched. Paging never changes which prompts are reported as movers.

Rates are fractions, not percentages. 0.412 is 41.2%.

Last updated on