curl --request GET \
--url https://api.snowseo.com/v3/ai-tracker/visibility/competitors \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.snowseo.com/v3/ai-tracker/visibility/competitors"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.snowseo.com/v3/ai-tracker/visibility/competitors', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.snowseo.com/v3/ai-tracker/visibility/competitors",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.snowseo.com/v3/ai-tracker/visibility/competitors"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.snowseo.com/v3/ai-tracker/visibility/competitors")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snowseo.com/v3/ai-tracker/visibility/competitors")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"meta": {
"teamInfo": {},
"appliedFilters": {},
"totalPrompts": 123,
"activePrompts": 123,
"activeRegionRuns": 123,
"totalResponses": 123,
"promptStatus": {}
},
"competitors": {},
"roster": [
{}
],
"stats": {
"avgShareOfVoice": 123,
"activeCompetitors": 123
},
"total": 123,
"truncated": true
}{
"success": true,
"error": "<string>",
"code": "<string>",
"message": "<string>",
"reference": "<string>"
}{
"success": true,
"error": "<string>",
"code": "<string>",
"message": "<string>",
"reference": "<string>"
}{
"success": true,
"error": "<string>",
"code": "<string>",
"message": "<string>",
"reference": "<string>"
}Competitors
Your tracked competitor set with visibility and sentiment.
curl --request GET \
--url https://api.snowseo.com/v3/ai-tracker/visibility/competitors \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.snowseo.com/v3/ai-tracker/visibility/competitors"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.snowseo.com/v3/ai-tracker/visibility/competitors', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.snowseo.com/v3/ai-tracker/visibility/competitors",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.snowseo.com/v3/ai-tracker/visibility/competitors"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.snowseo.com/v3/ai-tracker/visibility/competitors")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.snowseo.com/v3/ai-tracker/visibility/competitors")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"meta": {
"teamInfo": {},
"appliedFilters": {},
"totalPrompts": 123,
"activePrompts": 123,
"activeRegionRuns": 123,
"totalResponses": 123,
"promptStatus": {}
},
"competitors": {},
"roster": [
{}
],
"stats": {
"avgShareOfVoice": 123,
"activeCompetitors": 123
},
"total": 123,
"truncated": true
}{
"success": true,
"error": "<string>",
"code": "<string>",
"message": "<string>",
"reference": "<string>"
}{
"success": true,
"error": "<string>",
"code": "<string>",
"message": "<string>",
"reference": "<string>"
}{
"success": true,
"error": "<string>",
"code": "<string>",
"message": "<string>",
"reference": "<string>"
}matrices=true for the per-AI-model breakdown. search matches the brand name and website before limit is applied; total, rows and roster cover the matches, while stats and the trend stay unfiltered.
The trend carries one line per brand unless you narrow it: trendBrands=default keeps your brand plus up to 9 tracked competitors, or pass a JSON array of names. Set includeRows=false when you only need the trend or the matrices. rowFields=roster returns every brand’s name, website, flags and segment tags in roster instead of full rows. stats always holds the average share of voice and the tracked competitor count across all rows.
Scope filters are described on AI Visibility.Authorizations
Your SnowSEO API key (sk_...).
Query Parameters
Comma-separated AI platform names, or 'All Platforms' for no filter.
Comma-separated competitor names, or 'All Competitors' for no filter. Keeps prompts where ANY listed competitor appears.
Comma-separated ISO2 country codes, or 'All Countries' for no filter.
YYYY-MM-DD. Omit with endDate set for All Time (from the first answer, no previous-period comparison).
YYYY-MM-DD
Days back from today on the team's calendar, converted to startDate/endDate. Ignored when startDate or endDate is set. Defaults to 30.
x >= 1'branded', 'unbranded', or 'all'.
'tracked', 'untracked', or empty for both.
Comma-separated prompt intents, or empty for all.
Include previous-period comparison values alongside each data point (roughly doubles the time-series payload). Defaults to false.
Home chart projection: top eight non-user brands by share of voice and mentions, plus your brand. Global totals remain unchanged.
true, false Case-insensitive text matched against the brand name and website. Applied before limit; total, rows and roster cover the matches. Stats and trend stay unfiltered.
Max competitor rows, or 'all'. Defaults to 25. Also bounds the trend series and the matrix; the response reports total and truncated.
Include each row's daily visibility sparkline (~85% of a row). Defaults to false.
Include the per-competitor x per-AI-model matrix. Defaults to false.
Include the daily visibility trend across competitors. Defaults to true.
Brands to keep in the trend: a JSON array of names, or 'default' for your brand plus up to 9 tracked competitors. Your brand is always kept. Omit for every brand.
Include the competitor rows. Defaults to true; set false when only the trend or matrices are needed.
roster returns every brand's name, website, flags and segment tags in roster instead of full rows, ignoring limit. Defaults to full.
full, roster Was this page helpful?

