curl --request GET \
--url https://api.surfais.com/v1/orgs/{orgId}/brands/{brandId}/share-of-voice \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.surfais.com/v1/orgs/{orgId}/brands/{brandId}/share-of-voice"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.surfais.com/v1/orgs/{orgId}/brands/{brandId}/share-of-voice', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"window": {
"from": "2023-12-25",
"to": "2023-12-25"
},
"score_version": "<string>",
"panel_version": "<string>",
"entries": [
{
"brand_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"is_self": true,
"sov": 123,
"visibility": 123,
"ais_score": 123,
"mentions": 0,
"days": 0
}
]
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}Get share of voice
Share of voice over a window.
The own brand and its competitors. The field’s MEMBERSHIP and its sums come from one database statement, so the numerator and every competitor in its denominator are one snapshot. EVERY MEMBER IS MEASURED IN THIS FIELD’S SCOPE, FROM ONE SOURCE: mentions / visibility / days are counted on THIS own brand’s completed, non-preview runs for every entry, the own brand’s own included, never off a score row — those carry no record of which own brand it was scored for and keep whichever (own brand, candidate) pairing scored them last, which reaches an own brand too, since a competitor link is a link between BRANDS. sov = Σ this entry’s mentions ÷ Σ over every entry; visibility = mean daily presence over days; ais_score = mean AIS Score over the PERSISTED rows that carry one AND belong to BOTH generations the envelope pins — its score_version (the formula that produced the point) and its panel_version (the model set that measured it), which are ONE persisted, SCORED point’s pair (among the rows carrying an AIS and belonging to this field: latest date, then the highest panel generation, then the highest scoring generation) rather than the newest of each picked separately — a point of a known DIFFERENT generation, of either kind, is excluded from that mean only, never from mentions, visibility, sov or days. Null where nothing is persisted, and null for an entry that is ITSELF an own brand: no rival-field AIS Score is recorded for one, so this field has none for it and its rows cannot pin this field’s generation — its mentions, visibility and days are this field’s all the same. A field wider than 1000 members (the brand plus its tracked competitors) cannot be measured in one snapshot and answers 500 field_too_large rather than a share computed against a truncated denominator. Own brands only.
curl --request GET \
--url https://api.surfais.com/v1/orgs/{orgId}/brands/{brandId}/share-of-voice \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.surfais.com/v1/orgs/{orgId}/brands/{brandId}/share-of-voice"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.surfais.com/v1/orgs/{orgId}/brands/{brandId}/share-of-voice', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"window": {
"from": "2023-12-25",
"to": "2023-12-25"
},
"score_version": "<string>",
"panel_version": "<string>",
"entries": [
{
"brand_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"is_self": true,
"sov": 123,
"visibility": 123,
"ais_score": 123,
"mentions": 0,
"days": 0
}
]
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": "<unknown>"
},
"request_id": "<string>"
}Authorizations
A Surfais API key — an organisation key or a partner key. Issued by Surfais; shown once. Rotate by creating a new key, then revoking the old one.
Path Parameters
Organisation id. Org keys: the key's own org. Partner keys: any org with an active link. Anything else is 404.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Brand id within the org (own brand or competitor row); 404 when not in the org. Writes that add tracking need an own (400 validation_error with details[].code = "own_brand_only"), non-archived (409 brand_archived) brand.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$Query Parameters
Window start (inclusive). Default: to minus 30 days.
^\d{4}-\d{2}-\d{2}$Window end (inclusive). Default: today (UTC). Max span 366 days; from after to is 400 validation_error. On a paginated endpoint the resolved window is pinned by the first page and carried in the cursor — continue with the cursor alone; naming a different from/to on a continuation is 400 invalid_cursor (details.reason = "window_changed").
^\d{4}-\d{2}-\d{2}$Response
Share of voice.
Show child attributes
Show child attributes