curl --request POST \
--url https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"domains": [
"<string>"
],
"group_label": "<string>",
"rollup_mode": "auto",
"rollup_pillars": [
"<string>"
],
"rollup_limit": 13
}
'import requests
url = "https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights"
payload = {
"domains": ["<string>"],
"group_label": "<string>",
"rollup_mode": "auto",
"rollup_pillars": ["<string>"],
"rollup_limit": 13
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
domains: ['<string>'],
group_label: '<string>',
rollup_mode: 'auto',
rollup_pillars: ['<string>'],
rollup_limit: 13
})
};
fetch('https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights', 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.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'domains' => [
'<string>'
],
'group_label' => '<string>',
'rollup_mode' => 'auto',
'rollup_pillars' => [
'<string>'
],
'rollup_limit' => 13
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights"
payload := strings.NewReader("{\n \"domains\": [\n \"<string>\"\n ],\n \"group_label\": \"<string>\",\n \"rollup_mode\": \"auto\",\n \"rollup_pillars\": [\n \"<string>\"\n ],\n \"rollup_limit\": 13\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"domains\": [\n \"<string>\"\n ],\n \"group_label\": \"<string>\",\n \"rollup_mode\": \"auto\",\n \"rollup_pillars\": [\n \"<string>\"\n ],\n \"rollup_limit\": 13\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"domains\": [\n \"<string>\"\n ],\n \"group_label\": \"<string>\",\n \"rollup_mode\": \"auto\",\n \"rollup_pillars\": [\n \"<string>\"\n ],\n \"rollup_limit\": 13\n}"
response = http.request(request)
puts response.read_body{
"brand_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"generated_at": "2023-11-07T05:31:56Z",
"group_key": "<string>",
"module": "content",
"historical_evidence": {},
"group_label": "<string>",
"brand_domain": "<string>",
"domains": [
"<string>"
],
"cohort_domains": [
"<string>"
],
"coverage": {
"targets_total": 0,
"measured": 0,
"missing": [
"<string>"
],
"fetch_failed": [
"<string>"
],
"persist_failed": [
"<string>"
],
"skipped_cost": [
"<string>"
],
"last_run_at": "2023-11-07T05:31:56Z",
"brand_measured": false,
"brand_domain": "<string>",
"brand_not_measured_reason": "<string>",
"near_duplicate_pairs": [
{
"domain_a": "<string>",
"domain_b": "<string>",
"edit_distance": 123
}
],
"near_duplicate_scan_truncated": false,
"near_duplicate_scanned_count": 0
},
"position": [
{
"dimension": "<string>",
"label": "<string>",
"higher_is_better": true,
"brand_value": 123,
"brand_rank": 123,
"tied_count": 123,
"measured_count": 0,
"cohort_total": 0,
"best_domain": "<string>",
"best_tied_count": 123,
"best_value": 123,
"median_value": 123,
"not_measured_reason": "<string>"
}
],
"source_health": {
"sources_total": 0,
"sources_fetched": 0,
"sources_failed": 0,
"domains_with_failures": 0,
"failures": [
{
"domain": "<string>",
"url": "",
"source_type": "unknown",
"error": "<string>"
}
]
},
"cadence": {
"rows": [
{
"domain": "<string>",
"is_brand": false,
"measured": false,
"posts_last_30d": 123,
"avg_cadence_days": 123,
"cadence_span_days": 123,
"cadence_suppressed_reason": "<string>",
"previous_posts_last_30d": 123,
"comparison_days": 2
}
],
"measured_count": 0,
"cohort_median_posts": 123,
"brand_posts_last_30d": 123,
"brand_rank": 123,
"brand_tied_count": 123,
"rows_with_suppressed_cadence": 123,
"brand_monthly_posts": [
{
"month": "<string>",
"count": 0
}
],
"brand_monthly_dated_items": 0,
"brand_monthly_undated_items": 0,
"brand_monthly_sample_truncated": false,
"measured": false
},
"format_mix": {
"taxonomy_version": "<string>",
"dimensions": {},
"basis_notice": "<string>",
"rows": [
{
"content_format": "<string>",
"cohort_count": 0,
"cohort_share_pct": 123,
"cohort_domains": 0,
"brand_count": 0,
"brand_share_pct": 123
}
],
"cohort_items_classified": 0,
"brand_items_classified": 0,
"missing_formats": [
"<string>"
],
"measured": false
},
"pillars": {
"shared": [
{
"pillar": "<string>",
"cohort_domains": 0,
"brand_covers": false,
"example_domains": [
"<string>"
],
"evidence": "title_term",
"demand_keywords": [
"<string>"
],
"search_volume": 123
}
],
"whitespace": [
{
"pillar": "<string>",
"cohort_domains": 0,
"brand_covers": false,
"example_domains": [
"<string>"
],
"evidence": "title_term",
"demand_keywords": [
"<string>"
],
"search_volume": 123
}
],
"brand_only": [
{
"pillar": "<string>",
"cohort_domains": 0,
"brand_covers": false,
"example_domains": [
"<string>"
],
"evidence": "title_term",
"demand_keywords": [
"<string>"
],
"search_volume": 123
}
],
"cohort_domains_measured": 0,
"threshold_domains": 0,
"measured": false
},
"pillar_rollup": {
"mode": "auto",
"rollup_pillars": [
"<string>"
],
"limit": 12,
"rows": [
{
"pillar": "<string>",
"evidence": "strategy_label",
"demand_keywords": [
"<string>"
],
"search_volume": 1,
"cpc": 1,
"competitor_domains_measured": 0,
"competitor_domains_covering": 0,
"competitor_count_total": 1,
"competitor_median_count": 1,
"brand_measured": false,
"brand_covers": false,
"brand_count": 1,
"brand_share_pct": 50,
"brand_rank": 2,
"brand_tied_count": 2,
"gap_domains": [
"<string>"
],
"examples": [
{
"domain": "<string>",
"title": "<string>",
"is_brand": false,
"url": "<string>",
"published_at": "2023-11-07T05:31:56Z"
}
],
"domain_cells": [
{
"domain": "<string>",
"is_brand": false,
"measured": false,
"covers": false,
"count": 1,
"share_pct": 50,
"evidence": "strategy_label"
}
]
}
],
"competitor_domains_total": 0,
"competitor_domains_included": 0,
"competitor_domains_truncated": 0,
"competitor_domains_measured": 0,
"brand_measured": false,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Counts and shares use each domain's bounded stored latest-item sample; pillar-evidence coverage can also use stored strategy labels; the median excludes your brand and missing samples are never zero."
},
"headline_patterns": {
"rows": [
{
"pattern": "<string>",
"cohort_count": 0,
"cohort_share_pct": 123,
"cohort_domains": 0,
"brand_count": 123,
"brand_share_pct": 123
}
],
"length_buckets": [
{
"bucket": "<string>",
"cohort_count": 0,
"cohort_share_pct": 123,
"brand_count": 123,
"brand_share_pct": 123
}
],
"cohort_titles_measured": 0,
"cohort_domains_measured": 0,
"brand_titles_measured": 0,
"cohort_median_title_chars": 123,
"cohort_median_title_words": 123,
"brand_median_title_chars": 123,
"brand_median_title_words": 123,
"min_cohort_titles": 0,
"min_brand_titles": 0,
"measured": false,
"brand_measured": false,
"not_measured_reason": "<string>"
},
"lead_magnets": {
"rows": [
{
"play": "<string>",
"cohort_domains": 0,
"cohort_count": 0,
"brand_count": 0,
"brand_uses": false
}
],
"missing_plays": [
"<string>"
],
"cohort_domains_measured": 0,
"measured": false
},
"demand_join": {
"validated_pillars": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"demand_you_are_missing": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"publishing_without_demand": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"cohort_demand": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"brand_side_measured": false,
"brand_side_withheld_reason": "<string>",
"seo_domains_measured": 0,
"content_domains_measured": 0,
"seo_keyword_universe_size": 0,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Computed over the stored keyword samples for each competitor, not the full domain-wide keyword population."
},
"ads_join": {
"validated_pillars": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"ad_spend_you_are_missing": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"publishing_without_ad_backing": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"cohort_ad_spend": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"brand_side_measured": false,
"brand_side_withheld_reason": "<string>",
"ads_domains_measured": 0,
"content_domains_measured": 0,
"ads_keyword_universe_size": 0,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Computed over the stored keyword samples for each competitor, not the full domain-wide keyword population."
},
"ai_visibility": {
"status": "measured",
"scope": "brand_category_projected",
"scope_notice": "Projected onto this selected cohort from the brand's weekly brand-category capture. This is not a group- or pillar-specific capture.",
"measured": false,
"expected_answers": 0,
"measured_answers": 0,
"missing_answers": 0,
"mention_denominator": 1,
"citation_denominator": 1,
"citation_denominator_basis": "source_list_observed",
"cohort_domains_total": 0,
"cohort_domains_measured": 0,
"missing_domains": [
"<string>"
],
"rows_truncated": 0,
"provider": "dataforseo",
"platform": "",
"location_code": 2,
"language_code": "<string>",
"captured_at": "2023-11-07T05:31:56Z",
"stale": false,
"rows": [
{
"brand": "<string>",
"domain": "<string>",
"is_brand": false,
"answers_naming": 1,
"mention_share": 0.5,
"answers_citing": 1,
"citation_share": 0.5
}
],
"evidence": [
{
"prompt": "<string>",
"provider": "dataforseo",
"platform": "",
"model": "",
"mention_observed": true,
"sources_observed": true,
"check_url": "",
"citations": [
{
"url": "<string>",
"title": ""
}
]
}
],
"basis_notice": "Mention share is answers naming the domain divided by answers whose mention inputs were observed. Citation share is answers citing the domain divided by answers whose source list was observed; an explicit empty source list is a measured zero, while an omitted source list is unmeasured. The denominators are separate and are never combined."
},
"page_performance": {
"rows": [
{
"domain": "<string>",
"page_url": "<string>",
"is_brand": false,
"title": "<string>",
"organic_etv": 1,
"organic_keyword_count": 1,
"organic_top_3": 1,
"organic_top_10": 1,
"backlinks": 1,
"referring_domains": 1,
"ai_mentions": 1,
"ai_search_volume": 1,
"ai_platform": "<string>",
"sources": [
"<string>"
]
}
],
"domains_measured": 0,
"domains_in_cohort": 0,
"pages_sampled": 0,
"pages_matched": 0,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Per-URL organic traffic and link counts for the content pieces already in each publisher's stored sample, matched against that domain's top pages by organic traffic and by backlinks. Traffic is a provider ESTIMATE, not analytics. A blank cell is not measured; zero is measured. An unmatched piece is absent from the page indexes we bought, which is not the same as earning nothing."
},
"ai_citations": {
"rows": [
{
"domain": "<string>",
"page_url": "<string>",
"is_brand": false,
"title": "<string>",
"organic_etv": 1,
"organic_keyword_count": 1,
"organic_top_3": 1,
"organic_top_10": 1,
"backlinks": 1,
"referring_domains": 1,
"ai_mentions": 1,
"ai_search_volume": 1,
"ai_platform": "<string>",
"sources": [
"<string>"
]
}
],
"domains_measured": 0,
"domains_in_cohort": 0,
"pages_sampled": 0,
"pages_cited": 0,
"platform": "<string>",
"platform_span": "unknown",
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "How often an AI assistant cited each individual page, for the content pieces already in each publisher's stored sample. This is a PAGE-level citation count from the AI-answer citation index - not the same measurement as this module's brand-level AI visibility panel, which asks whether the BRAND is named in an answer. A brand can be named constantly with none of its pages cited. A blank cell is not measured; zero is measured."
},
"tech_stack": {
"rows": [
{
"technology": "<string>",
"category": "<string>",
"category_label": "<string>",
"detected_domains": [
"<string>"
],
"detected_count": 0,
"on_brand": true
}
],
"competitors_scanned": 0,
"competitors_in_cohort": 0,
"brand_scanned": false,
"technologies_detected": 0,
"rows_truncated": false,
"oldest_detected_at": "2023-11-07T05:31:56Z",
"newest_detected_at": "2023-11-07T05:31:56Z",
"stale_domain_count": 0,
"stale_after_days": 45,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Technologies a fingerprinting scan DETECTED on each domain, counted only where they were found. Detection is not declaration: a tool can be in use and go undetected because it runs server-side, sits behind a login, is proxied through a CDN, or simply has no signature in the provider's set. So \"not detected\" is not evidence a publisher does not use something, and this panel never counts an absence. Each domain is scanned separately and the scan dates differ, so treat the oldest date as the age of the comparison."
},
"publisher_evidence": [
{
"domain": "<string>",
"is_brand": false,
"measured": false,
"latest_items": [
{
"title": "<string>",
"url": "<string>",
"published_at": "2023-11-07T05:31:56Z",
"media_type": "<string>",
"tags": [
"<string>"
]
}
],
"latest_items_source": "recent_30d",
"strategy_summary": "<string>",
"strategy_source": "llm",
"strategy_evidence": [
{
"ref": "<string>",
"value": "<string>"
}
],
"captured_at": "2023-11-07T05:31:56Z"
}
],
"comparison_basis": {
"measured": false,
"publishers_with_snapshots": 0,
"publishers_with_prior_snapshot": 0,
"has_prior_snapshot": false
},
"findings": [
{
"rule_id": "<string>",
"module": "seo",
"panel": "<string>",
"title": "<string>",
"detail": "<string>",
"severity": "info",
"evidence_refs": [
"<string>"
]
}
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Get Brand Intelligence Content Group Insights Route
Cohort content analysis for one competitor Brand Group (INSIGHTS tab).
Includes the content ↔ demand join, which reads the SAME cohort’s stored SEO keyword universe. No new provider spend on either side.
curl --request POST \
--url https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"domains": [
"<string>"
],
"group_label": "<string>",
"rollup_mode": "auto",
"rollup_pillars": [
"<string>"
],
"rollup_limit": 13
}
'import requests
url = "https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights"
payload = {
"domains": ["<string>"],
"group_label": "<string>",
"rollup_mode": "auto",
"rollup_pillars": ["<string>"],
"rollup_limit": 13
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
domains: ['<string>'],
group_label: '<string>',
rollup_mode: 'auto',
rollup_pillars: ['<string>'],
rollup_limit: 13
})
};
fetch('https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights', 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.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'domains' => [
'<string>'
],
'group_label' => '<string>',
'rollup_mode' => 'auto',
'rollup_pillars' => [
'<string>'
],
'rollup_limit' => 13
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights"
payload := strings.NewReader("{\n \"domains\": [\n \"<string>\"\n ],\n \"group_label\": \"<string>\",\n \"rollup_mode\": \"auto\",\n \"rollup_pillars\": [\n \"<string>\"\n ],\n \"rollup_limit\": 13\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"domains\": [\n \"<string>\"\n ],\n \"group_label\": \"<string>\",\n \"rollup_mode\": \"auto\",\n \"rollup_pillars\": [\n \"<string>\"\n ],\n \"rollup_limit\": 13\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/brands/{brand_id}/brand-intelligence/content-group-insights")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"domains\": [\n \"<string>\"\n ],\n \"group_label\": \"<string>\",\n \"rollup_mode\": \"auto\",\n \"rollup_pillars\": [\n \"<string>\"\n ],\n \"rollup_limit\": 13\n}"
response = http.request(request)
puts response.read_body{
"brand_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"generated_at": "2023-11-07T05:31:56Z",
"group_key": "<string>",
"module": "content",
"historical_evidence": {},
"group_label": "<string>",
"brand_domain": "<string>",
"domains": [
"<string>"
],
"cohort_domains": [
"<string>"
],
"coverage": {
"targets_total": 0,
"measured": 0,
"missing": [
"<string>"
],
"fetch_failed": [
"<string>"
],
"persist_failed": [
"<string>"
],
"skipped_cost": [
"<string>"
],
"last_run_at": "2023-11-07T05:31:56Z",
"brand_measured": false,
"brand_domain": "<string>",
"brand_not_measured_reason": "<string>",
"near_duplicate_pairs": [
{
"domain_a": "<string>",
"domain_b": "<string>",
"edit_distance": 123
}
],
"near_duplicate_scan_truncated": false,
"near_duplicate_scanned_count": 0
},
"position": [
{
"dimension": "<string>",
"label": "<string>",
"higher_is_better": true,
"brand_value": 123,
"brand_rank": 123,
"tied_count": 123,
"measured_count": 0,
"cohort_total": 0,
"best_domain": "<string>",
"best_tied_count": 123,
"best_value": 123,
"median_value": 123,
"not_measured_reason": "<string>"
}
],
"source_health": {
"sources_total": 0,
"sources_fetched": 0,
"sources_failed": 0,
"domains_with_failures": 0,
"failures": [
{
"domain": "<string>",
"url": "",
"source_type": "unknown",
"error": "<string>"
}
]
},
"cadence": {
"rows": [
{
"domain": "<string>",
"is_brand": false,
"measured": false,
"posts_last_30d": 123,
"avg_cadence_days": 123,
"cadence_span_days": 123,
"cadence_suppressed_reason": "<string>",
"previous_posts_last_30d": 123,
"comparison_days": 2
}
],
"measured_count": 0,
"cohort_median_posts": 123,
"brand_posts_last_30d": 123,
"brand_rank": 123,
"brand_tied_count": 123,
"rows_with_suppressed_cadence": 123,
"brand_monthly_posts": [
{
"month": "<string>",
"count": 0
}
],
"brand_monthly_dated_items": 0,
"brand_monthly_undated_items": 0,
"brand_monthly_sample_truncated": false,
"measured": false
},
"format_mix": {
"taxonomy_version": "<string>",
"dimensions": {},
"basis_notice": "<string>",
"rows": [
{
"content_format": "<string>",
"cohort_count": 0,
"cohort_share_pct": 123,
"cohort_domains": 0,
"brand_count": 0,
"brand_share_pct": 123
}
],
"cohort_items_classified": 0,
"brand_items_classified": 0,
"missing_formats": [
"<string>"
],
"measured": false
},
"pillars": {
"shared": [
{
"pillar": "<string>",
"cohort_domains": 0,
"brand_covers": false,
"example_domains": [
"<string>"
],
"evidence": "title_term",
"demand_keywords": [
"<string>"
],
"search_volume": 123
}
],
"whitespace": [
{
"pillar": "<string>",
"cohort_domains": 0,
"brand_covers": false,
"example_domains": [
"<string>"
],
"evidence": "title_term",
"demand_keywords": [
"<string>"
],
"search_volume": 123
}
],
"brand_only": [
{
"pillar": "<string>",
"cohort_domains": 0,
"brand_covers": false,
"example_domains": [
"<string>"
],
"evidence": "title_term",
"demand_keywords": [
"<string>"
],
"search_volume": 123
}
],
"cohort_domains_measured": 0,
"threshold_domains": 0,
"measured": false
},
"pillar_rollup": {
"mode": "auto",
"rollup_pillars": [
"<string>"
],
"limit": 12,
"rows": [
{
"pillar": "<string>",
"evidence": "strategy_label",
"demand_keywords": [
"<string>"
],
"search_volume": 1,
"cpc": 1,
"competitor_domains_measured": 0,
"competitor_domains_covering": 0,
"competitor_count_total": 1,
"competitor_median_count": 1,
"brand_measured": false,
"brand_covers": false,
"brand_count": 1,
"brand_share_pct": 50,
"brand_rank": 2,
"brand_tied_count": 2,
"gap_domains": [
"<string>"
],
"examples": [
{
"domain": "<string>",
"title": "<string>",
"is_brand": false,
"url": "<string>",
"published_at": "2023-11-07T05:31:56Z"
}
],
"domain_cells": [
{
"domain": "<string>",
"is_brand": false,
"measured": false,
"covers": false,
"count": 1,
"share_pct": 50,
"evidence": "strategy_label"
}
]
}
],
"competitor_domains_total": 0,
"competitor_domains_included": 0,
"competitor_domains_truncated": 0,
"competitor_domains_measured": 0,
"brand_measured": false,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Counts and shares use each domain's bounded stored latest-item sample; pillar-evidence coverage can also use stored strategy labels; the median excludes your brand and missing samples are never zero."
},
"headline_patterns": {
"rows": [
{
"pattern": "<string>",
"cohort_count": 0,
"cohort_share_pct": 123,
"cohort_domains": 0,
"brand_count": 123,
"brand_share_pct": 123
}
],
"length_buckets": [
{
"bucket": "<string>",
"cohort_count": 0,
"cohort_share_pct": 123,
"brand_count": 123,
"brand_share_pct": 123
}
],
"cohort_titles_measured": 0,
"cohort_domains_measured": 0,
"brand_titles_measured": 0,
"cohort_median_title_chars": 123,
"cohort_median_title_words": 123,
"brand_median_title_chars": 123,
"brand_median_title_words": 123,
"min_cohort_titles": 0,
"min_brand_titles": 0,
"measured": false,
"brand_measured": false,
"not_measured_reason": "<string>"
},
"lead_magnets": {
"rows": [
{
"play": "<string>",
"cohort_domains": 0,
"cohort_count": 0,
"brand_count": 0,
"brand_uses": false
}
],
"missing_plays": [
"<string>"
],
"cohort_domains_measured": 0,
"measured": false
},
"demand_join": {
"validated_pillars": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"demand_you_are_missing": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"publishing_without_demand": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"cohort_demand": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"demand_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_ranking_domains": 0,
"gap_domains": [
"<string>"
]
}
],
"brand_side_measured": false,
"brand_side_withheld_reason": "<string>",
"seo_domains_measured": 0,
"content_domains_measured": 0,
"seo_keyword_universe_size": 0,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Computed over the stored keyword samples for each competitor, not the full domain-wide keyword population."
},
"ads_join": {
"validated_pillars": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"ad_spend_you_are_missing": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"publishing_without_ad_backing": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"cohort_ad_spend": [
{
"term": "<string>",
"content_domains": 0,
"brand_publishes": true,
"ad_keywords": [
"<string>"
],
"search_volume": 123,
"cpc": 1,
"competitor_advertiser_domains": 0
}
],
"brand_side_measured": false,
"brand_side_withheld_reason": "<string>",
"ads_domains_measured": 0,
"content_domains_measured": 0,
"ads_keyword_universe_size": 0,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Computed over the stored keyword samples for each competitor, not the full domain-wide keyword population."
},
"ai_visibility": {
"status": "measured",
"scope": "brand_category_projected",
"scope_notice": "Projected onto this selected cohort from the brand's weekly brand-category capture. This is not a group- or pillar-specific capture.",
"measured": false,
"expected_answers": 0,
"measured_answers": 0,
"missing_answers": 0,
"mention_denominator": 1,
"citation_denominator": 1,
"citation_denominator_basis": "source_list_observed",
"cohort_domains_total": 0,
"cohort_domains_measured": 0,
"missing_domains": [
"<string>"
],
"rows_truncated": 0,
"provider": "dataforseo",
"platform": "",
"location_code": 2,
"language_code": "<string>",
"captured_at": "2023-11-07T05:31:56Z",
"stale": false,
"rows": [
{
"brand": "<string>",
"domain": "<string>",
"is_brand": false,
"answers_naming": 1,
"mention_share": 0.5,
"answers_citing": 1,
"citation_share": 0.5
}
],
"evidence": [
{
"prompt": "<string>",
"provider": "dataforseo",
"platform": "",
"model": "",
"mention_observed": true,
"sources_observed": true,
"check_url": "",
"citations": [
{
"url": "<string>",
"title": ""
}
]
}
],
"basis_notice": "Mention share is answers naming the domain divided by answers whose mention inputs were observed. Citation share is answers citing the domain divided by answers whose source list was observed; an explicit empty source list is a measured zero, while an omitted source list is unmeasured. The denominators are separate and are never combined."
},
"page_performance": {
"rows": [
{
"domain": "<string>",
"page_url": "<string>",
"is_brand": false,
"title": "<string>",
"organic_etv": 1,
"organic_keyword_count": 1,
"organic_top_3": 1,
"organic_top_10": 1,
"backlinks": 1,
"referring_domains": 1,
"ai_mentions": 1,
"ai_search_volume": 1,
"ai_platform": "<string>",
"sources": [
"<string>"
]
}
],
"domains_measured": 0,
"domains_in_cohort": 0,
"pages_sampled": 0,
"pages_matched": 0,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Per-URL organic traffic and link counts for the content pieces already in each publisher's stored sample, matched against that domain's top pages by organic traffic and by backlinks. Traffic is a provider ESTIMATE, not analytics. A blank cell is not measured; zero is measured. An unmatched piece is absent from the page indexes we bought, which is not the same as earning nothing."
},
"ai_citations": {
"rows": [
{
"domain": "<string>",
"page_url": "<string>",
"is_brand": false,
"title": "<string>",
"organic_etv": 1,
"organic_keyword_count": 1,
"organic_top_3": 1,
"organic_top_10": 1,
"backlinks": 1,
"referring_domains": 1,
"ai_mentions": 1,
"ai_search_volume": 1,
"ai_platform": "<string>",
"sources": [
"<string>"
]
}
],
"domains_measured": 0,
"domains_in_cohort": 0,
"pages_sampled": 0,
"pages_cited": 0,
"platform": "<string>",
"platform_span": "unknown",
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "How often an AI assistant cited each individual page, for the content pieces already in each publisher's stored sample. This is a PAGE-level citation count from the AI-answer citation index - not the same measurement as this module's brand-level AI visibility panel, which asks whether the BRAND is named in an answer. A brand can be named constantly with none of its pages cited. A blank cell is not measured; zero is measured."
},
"tech_stack": {
"rows": [
{
"technology": "<string>",
"category": "<string>",
"category_label": "<string>",
"detected_domains": [
"<string>"
],
"detected_count": 0,
"on_brand": true
}
],
"competitors_scanned": 0,
"competitors_in_cohort": 0,
"brand_scanned": false,
"technologies_detected": 0,
"rows_truncated": false,
"oldest_detected_at": "2023-11-07T05:31:56Z",
"newest_detected_at": "2023-11-07T05:31:56Z",
"stale_domain_count": 0,
"stale_after_days": 45,
"measured": false,
"not_measured_reason": "<string>",
"basis_notice": "Technologies a fingerprinting scan DETECTED on each domain, counted only where they were found. Detection is not declaration: a tool can be in use and go undetected because it runs server-side, sits behind a login, is proxied through a CDN, or simply has no signature in the provider's set. So \"not detected\" is not evidence a publisher does not use something, and this panel never counts an absence. Each domain is scanned separately and the scan dates differ, so treat the oldest date as the age of the comparison."
},
"publisher_evidence": [
{
"domain": "<string>",
"is_brand": false,
"measured": false,
"latest_items": [
{
"title": "<string>",
"url": "<string>",
"published_at": "2023-11-07T05:31:56Z",
"media_type": "<string>",
"tags": [
"<string>"
]
}
],
"latest_items_source": "recent_30d",
"strategy_summary": "<string>",
"strategy_source": "llm",
"strategy_evidence": [
{
"ref": "<string>",
"value": "<string>"
}
],
"captured_at": "2023-11-07T05:31:56Z"
}
],
"comparison_basis": {
"measured": false,
"publishers_with_snapshots": 0,
"publishers_with_prior_snapshot": 0,
"has_prior_snapshot": false
},
"findings": [
{
"rule_id": "<string>",
"module": "seo",
"panel": "<string>",
"title": "<string>",
"detail": "<string>",
"severity": "info",
"evidence_refs": [
"<string>"
]
}
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Content cohort plus the vocabulary used by the pillar roll-up.
auto derives a deterministic starting vocabulary from the stored
cohort evidence and ignores rollup_pillars. frozen uses exactly
the supplied vocabulary. Carrying that vocabulary in the request keeps a
saved comparison stable when later acquisitions discover new terms.
Response
Successful Response
"content"N-of-M acquisition coverage for one module's cohort (the ★S0/★C0 strip).
measured counts cohort domains that produced a stored metric row.
missing are targets that never did — their fetch or persist failed, or
they have not been acquired yet. For Content, fetch_failed is a typed
subset of missing, not an additional shortfall, so clients must
de-duplicate rather than sum those lengths. A competitor with a failed
acquisition must render as a failure chip, never as a measured zero.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
★C0 — per-competitor source health rolled up for the cohort.
Failed sources used to be DELETED from the UI, which made a brand whose blog was blocked look identical to one with no blog.
Show child attributes
Show child attributes
★C1 — publishing velocity vs measured competitors.
measured_count and cohort_median_posts exclude the user's brand;
brand_rank ranks the brand across the combined measured population.
brand_rank is a COMPETITION rank ("1224"): domains that published the
same number of posts share a place, and only a domain that published MORE
pushes the brand down one. So rank 1 means "nobody published more" — NOT
"published more than everyone", which a tie also satisfies.
brand_tied_count includes the brand itself and makes that shared place
explicit to every renderer.
rows_with_suppressed_cadence counts over the FULL cohort, not the
truncated rows list, and is None rather than 0 when nothing was
suppressed: module_group_commentary._flatten_refs skips None but
flattens 0 into evidence the narrator may quote, so a 0 would hand the
model a "0 rows suppressed" fact about every cohort.
brand_monthly_* is the BRAND'S OWN history, never the cohort's.
A cohort-total line would blend domains whose samples reach back
different distances, so months where the older domains ran out of sample
would render as a decline nobody published — an artefact indistinguishable
from a real slowdown. One domain, one sample, one truncation boundary is
the only series this data can honestly draw. brand_monthly_dated_items
and brand_monthly_undated_items are its denominators; a renderer that
shows the line owes the reader both.
Show child attributes
Show child attributes
★C2 — article/video/gated split across the cohort vs the brand.
Show child attributes
Show child attributes
★C3 — shared topics (table stakes) vs uncontested ground.
Show child attributes
Show child attributes
Request-scoped pillar vocabulary rolled across stored item samples.
Unlike the sibling full-cohort panels, this comparison deliberately caps competitors before vocabulary and aggregate computation. The explicit total/included/truncated accounting prevents that bounded denominator from masquerading as complete cohort coverage.
Show child attributes
Show child attributes
★C10 — the shape of the cohort's headlines, from stored titles only.
Fully deterministic: every field is arithmetic over
CompetitorContentMetric.latest_items[*].title, which is already
persisted. No provider call, no model call, no acquisition — see
content_headline_patterns.py for why an LLM was declined.
Four states, deliberately distinguishable:
measured=False+not_measured_reason="no_content_measured";measured=False+"no_titles_stored"(read, but zero titles);measured=False+"insufficient_titles"(below the floor — the counts are still carried so the reader sees "12 of 20 needed");measured=Truewith a0.0share — a measured zero.
A measured panel carries a row for EVERY pattern, including unused ones. Filtering the zeros would make a real "nobody does this" indistinguishable from "we did not check".
Show child attributes
Show child attributes
★C4 — the cohort's tried-and-true capture patterns.
Show child attributes
Show child attributes
★C8 — the content ↔ demand join, benchmarked on the SAME cohort.
Three buckets: pillars the brand publishes that the cohort's SEO keyword universe confirms have demand; demand the cohort captures that the brand publishes nothing for; and pillars the brand publishes with no demand evidence anywhere in the cohort's keyword universe.
measured is False unless BOTH sides were measured for this cohort —
a missing SEO capture must never render as "no demand".
cohort_demand is the brand-side-WITHHELD half of the join: the demand
the cohort captures, with brand_publishes=None on every row. It is
populated ONLY when the SEO side is measured and the brand side is not,
which is the default new-cohort state — a fully-measured cohort should not
render as a blank panel just because the brand has not been read yet. When
measured is True this list is empty and the three comparison buckets
carry the answer, so no term is ever rendered twice.
Show child attributes
Show child attributes
★C8b — the content ↔ paid-ads join, benchmarked on the SAME cohort.
Three buckets: pillars the brand publishes that the cohort's Google Ads keyword universe confirms someone is backing with paid spend; paid keywords the cohort bids on that the brand publishes no content for; and pillars the brand publishes with no paid-keyword evidence anywhere in the cohort's Ads universe.
measured is False unless BOTH sides were measured for this cohort —
a missing Ads capture must never render as "no paid demand".
cohort_ad_spend is the brand-side-WITHHELD half of the join: the paid
keywords the cohort backs, with brand_publishes=None on every row. It
is populated ONLY when the ads side is measured and the brand side is
not, which is the default new-cohort state — a fully-measured cohort
should not render as a blank panel just because the brand has not been
read yet. When measured is True this list is empty and the three
comparison buckets carry the answer, so no term is ever rendered twice.
Show child attributes
Show child attributes
Weekly observed AI-answer mentions and citations for this cohort.
This is a read-only projection of the already-bounded weekly SEO capture; opening Content Insights never triggers a provider request.
Show child attributes
Show child attributes
Content's first MEASURED performance signal (design 9.2).
Every other Content panel counts what a publisher SHIPPED. This one reports what individual pieces EARNED, joined by URL onto the same bounded item sample the rest of the module already renders.
Three states, and collapsing any two is the defect this panel exists to avoid:
measured=False- no publisher in this cohort has a stored page-index capture. Nothing can be said. This is the state a cohort sits in while the acquisition flag is off, and it must never render as zeros.measured=Truewithrows == []- a page index WAS read for at least one publisher and none of the sampled URLs appear in it. A real finding, sized bypages_sampled, not a failure.measured=Truewith rows - render them, remembering that a blank cell inside a row is still "not measured".
Show child attributes
Show child attributes
Which of a publisher's PAGES an AI assistant cites (design 9.3).
Deliberately its own panel rather than three more columns on
ContentPagePerformancePanel, and deliberately NOT merged into the
module's brand-level AI visibility panel. The three are different claims:
- brand-level AI visibility (C5) - is this BRAND named when an assistant is
asked about the category. Re-read of the SEO module's
llm_scrapercapture. - per-page citations (this) - is this URL cited. DataForSEO LLM Mentions, keyed per page, different denominator.
- per-page organic/link performance - did this URL earn search traffic and links. No AI surface involved at all.
A reader must be able to tell which is which, so each gets its own heading,
its own basis notice and its own measured/unmeasured verdict. platform
is required reading alongside any count: "cited by ChatGPT" and "cited in
Google's AI Overviews" are not interchangeable.
Show child attributes
Show child attributes
What the tracked publishers BUILD with, versus what the brand builds with.
Every other Content panel measures output. This one measures the content stack behind the output — CMS, static-site generator, analytics, tag manager, personalisation, email platform — so a reader can see that four of the publishers they track run a headless CMS and they do not.
The claim is bounded on three axes, and each one is on the payload.
- Evidence direction. Only detections are counted.
detected_countis out ofcompetitors_scanned, never out ofcompetitors_in_cohort: a domain nobody scanned is not a domain that lacks the technology. - Sample size.
competitors_scanned/competitors_in_cohortsizes the comparison, andbrand_scannedsays whether the "versus you" half is expressible at all. When it is False the differential is withheld — enforced below, not merely documented. - Age. Detections carry the provider's own
last_visited, which can be materially older than the refresh that fetched it.oldest_detected_atbounds how current the comparison is andstale_domain_countsays how much of it is paststale_after_days.
Three states, as everywhere else in this module: measured=False is "no
cohort domain has a stored scan" and must never render as "no technologies";
measured=True with rows == [] is "we scanned and detected nothing we
report", which is genuinely rare and still not proof of an empty stack.
Show child attributes
Show child attributes
25Show child attributes
Show child attributes
Whether a period-over-period comparison is possible for this cohort AT ALL.
Three states. Collapsing any two of them is the defect this panel exists to prevent, because each one licenses a different sentence on screen:
measured=False— no tracked publisher has a stored capture, so we cannot say anything about history. Not a first generation; an unknown.measured=Trueandhas_prior_snapshot=False— captures exist but none has a predecessor on its own measurement series. This is the FIRST-EVER generation for the group: there is nothing to compare against, which is emphatically not "we compared and nothing changed".has_prior_snapshot=True— a real comparison basis exists, so an empty change feed is a measured absence of qualifying movement.
The series grain matches content_insight_events's own baseline test
(detect_content_publisher_delta returns None when the previous
snapshot on the same domain/source/source_url series is
missing): a publisher needs two captures on ONE series before any delta
can exist. Normalization here is deliberately no tighter than the emitter's
so that a mismatch can only over-count history — which suppresses the
first-generation copy and falls back to the existing wording, never the
other way round.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?