Get GEO matrix
curl --request GET \
--url https://www.qwairy.co/api/v1/brands/{brandId}/matrix \
--header 'Authorization: <authorization>'import requests
url = "https://www.qwairy.co/api/v1/brands/{brandId}/matrix"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://www.qwairy.co/api/v1/brands/{brandId}/matrix', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"success": true,
"brand": {
"id": "<string>",
"name": "<string>"
},
"granularity": "<string>",
"providers": [
{
"id": "<string>",
"name": "<string>"
}
],
"rows": [
{
"id": "<string>",
"name": "<string>",
"promptCount": 123,
"mentionRate": 123,
"coverage": {
"count": 123,
"total": 123,
"percentage": 123
},
"overall": {},
"cells": [
{
"provider": "<string>",
"score": 123,
"subScores": {
"mentionRate": 123,
"shareOfVoice": 123,
"citationRate": 123,
"sentiment": {}
},
"ranking": {
"mentionRate": {},
"shareOfVoice": {},
"citationRate": {},
"sentiment": {}
},
"citations": 123,
"position": 123,
"topCompetitor": "<string>",
"topCompetitors": [
{}
],
"topSources": [
{}
]
}
]
}
],
"providerAverages": [
{
"provider": "<string>",
"score": 123,
"mentionRate": 123,
"shareOfVoice": 123,
"citationRate": 123,
"sentiment": {}
}
],
"summary": {
"totalRows": 123,
"averageMentionRate": 123,
"topPerforming": {},
"needsAttention": {}
}
}Performance
Get GEO matrix
Get the GEO visibility matrix for your brand across providers and dimensions.
GET
https://www.qwairy.co
/
api
/
v1
/
brands
/
{brandId}
/
matrix
Get GEO matrix
curl --request GET \
--url https://www.qwairy.co/api/v1/brands/{brandId}/matrix \
--header 'Authorization: <authorization>'import requests
url = "https://www.qwairy.co/api/v1/brands/{brandId}/matrix"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://www.qwairy.co/api/v1/brands/{brandId}/matrix', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"success": true,
"brand": {
"id": "<string>",
"name": "<string>"
},
"granularity": "<string>",
"providers": [
{
"id": "<string>",
"name": "<string>"
}
],
"rows": [
{
"id": "<string>",
"name": "<string>",
"promptCount": 123,
"mentionRate": 123,
"coverage": {
"count": 123,
"total": 123,
"percentage": 123
},
"overall": {},
"cells": [
{
"provider": "<string>",
"score": 123,
"subScores": {
"mentionRate": 123,
"shareOfVoice": 123,
"citationRate": 123,
"sentiment": {}
},
"ranking": {
"mentionRate": {},
"shareOfVoice": {},
"citationRate": {},
"sentiment": {}
},
"citations": 123,
"position": 123,
"topCompetitor": "<string>",
"topCompetitors": [
{}
],
"topSources": [
{}
]
}
]
}
],
"providerAverages": [
{
"provider": "<string>",
"score": 123,
"mentionRate": 123,
"shareOfVoice": 123,
"citationRate": 123,
"sentiment": {}
}
],
"summary": {
"totalRows": 123,
"averageMentionRate": 123,
"topPerforming": {},
"needsAttention": {}
}
}Returns rows grouped by topic, tag, prompt, or funnel stage and columns grouped by provider. Each cell contains the current Matrix scoring output for its answer scope.
See Rate limits for retry behavior.
This endpoint returns a cross-tabulation of your brand’s visibility. See Performance for aggregated metrics and Competitor for entity structures used in
topCompetitors.string
required
Bearer token. Example:
Bearer qw-api-xxxGET /api/v1/brands/{brandId}/matrix
Path parameters
string
required
The unique identifier of the brand
Query parameters
string
Group rows by:
topics (default), tags, prompts, or funnelnumber
Number of days to include. Default: 30
string
Start date in
YYYY-MM-DD. Provide it with endDate; a lone boundary is currently ignored. Choose either period or the complete date pair.string
End date in
YYYY-MM-DD. Provide it with startDate; a lone boundary is currently ignored. Do not combine the complete date pair with period.string
Filter by AI provider. Supports comma-separated multi-select (e.g.,
chatgpt,claude).string
Filter by topic ID (keywordId). Supports comma-separated multi-select (e.g.,
id1,id2).string
Filter by tag ID. Supports comma-separated multi-select (e.g.,
id1,id2).number
Max rows to return. Default: 50, max: 100
Granularity options
| Value | Groups rows by |
|---|---|
topics | Keywords/topics (default) |
tags | Tags applied to prompts |
prompts | Individual monitored questions |
funnel | Funnel stages (TOFU/MOFU/BOFU) |
Response
boolean
Indicates if the request was successful
string
The granularity used for this matrix (
topics, tags, prompts, or funnel)array
array
Matrix rows, one per topic/tag/prompt/funnel stage
Show Row structure
Show Row structure
string
Row identifier (topic ID, tag ID, prompt ID, or funnel stage)
string
Display name of the row
number
Number of distinct prompts in this row
number
Pooled row-level Mention Rate: answers with a SELF mention divided by answers with a SELF or DIRECT mention
object
Provider-column coverage for this row. A provider counts when its cell has a non-zero SELF Mention Rate or SELF Citation Rate. This is not response-level or prompt-level Coverage.
object
Pooled
score, subScores, answerCount, and brand ranking across every selected provider in the rowarray
One cell per provider
Show Cell structure
Show Cell structure
string
Provider ID
number
Composite GEO score (0-100)
object
object
number
SELF source-mention occurrences in the cell
number
Best (minimum) position your brand reaches across this cell’s responses (lower is better;
null if not mentioned)string
Name of the leading competitor in this cell (
null if none)array
Top competitors in this cell, each with
name, mentions, avgPosition, and relationshiparray
Top cited sources in this cell
array
Per-provider average metrics across all returned rows.
Show Provider average object
Show Provider average object
string
Provider ID
number
Average composite GEO score for this provider (0-100)
number
Average mention rate for this provider (%)
number
Average share of voice for this provider (%)
number
Average citation rate for this provider (%)
number | null
Unweighted average of non-null row sentiment values for this provider, rounded to an integer
object
Show Summary statistics
Show Summary statistics
number
Total number of rows
number
Average of non-zero row Mention Rates, rounded to an integer
object
Highest mention-rate row, or
null. Shape: { rowId, rowName, mentionRate }.object
API summary field containing the lowest non-zero row below the built-in 50% rule, or
null. This rule is not an account benchmark.Synthetic request
curl "https://www.qwairy.co/api/v1/brands/YOUR_BRAND_ID/matrix?granularity=topics&period=30&limit=10" \
-H "Authorization: Bearer $QWAIRY_API_TOKEN"
Synthetic response
{
"success": true,
"brand": {
"id": "brand_01",
"name": "Acme Analytics"
},
"granularity": "topics",
"providers": [
{ "id": "openai", "name": "ChatGPT" },
{ "id": "perplexity", "name": "Perplexity" },
{ "id": "anthropic", "name": "Claude" }
],
"rows": [
{
"id": "topic_01",
"name": "Data exports",
"promptCount": 12,
"mentionRate": 52.4,
"coverage": { "count": 3, "total": 3, "percentage": 100 },
"overall": {
"score": 60,
"subScores": {
"mentionRate": 52.4,
"shareOfVoice": 13.5,
"citationRate": 29.1,
"sentiment": 76.3
},
"answerCount": 60,
"ranking": {
"mentionRate": { "rank": 2, "total": 8 },
"shareOfVoice": { "rank": 3, "total": 8 },
"citationRate": { "rank": 2, "total": 8 },
"sentiment": { "rank": 1, "total": 8 },
"score": { "rank": 2, "total": 8 }
}
},
"cells": [
{
"provider": "openai",
"score": 72,
"subScores": {
"mentionRate": 65.0,
"shareOfVoice": 18.5,
"citationRate": 30.2,
"sentiment": 81.0
},
"ranking": {
"mentionRate": { "rank": 2, "total": 8 },
"shareOfVoice": { "rank": 3, "total": 8 },
"citationRate": { "rank": 1, "total": 8 },
"sentiment": { "rank": 1, "total": 8 }
},
"citations": 12,
"position": 2,
"topCompetitor": "Rival Labs",
"topCompetitors": [
{ "name": "Rival Labs", "mentions": 9, "avgPosition": 2, "relationship": "DIRECT" },
{ "name": "Northstar Data", "mentions": 6, "avgPosition": 3, "relationship": "DIRECT" }
],
"topSources": [
{ "domain": "publisher.example", "citations": 8 }
]
},
{
"provider": "perplexity",
"score": 58,
"subScores": {
"mentionRate": 50.0,
"shareOfVoice": 12.3,
"citationRate": 42.1,
"sentiment": 76.0
},
"ranking": {
"mentionRate": { "rank": 3, "total": 7 },
"shareOfVoice": { "rank": 4, "total": 7 },
"citationRate": { "rank": 2, "total": 7 },
"sentiment": { "rank": 2, "total": 7 }
},
"citations": 18,
"position": 3,
"topCompetitor": "Northstar Data",
"topCompetitors": [
{ "name": "Northstar Data", "mentions": 11, "avgPosition": 2, "relationship": "DIRECT" },
{ "name": "Rival Labs", "mentions": 7, "avgPosition": 4, "relationship": "DIRECT" }
],
"topSources": [
{ "domain": "reviews.example", "citations": 14 }
]
},
{
"provider": "anthropic",
"score": 45,
"subScores": {
"mentionRate": 35.0,
"shareOfVoice": 9.8,
"citationRate": 15.0,
"sentiment": 72.0
},
"ranking": {
"mentionRate": { "rank": 5, "total": 6 },
"shareOfVoice": { "rank": 4, "total": 6 },
"citationRate": { "rank": 3, "total": 6 },
"sentiment": { "rank": 3, "total": 6 }
},
"citations": 4,
"position": 4,
"topCompetitor": "Rival Labs",
"topCompetitors": [
{ "name": "Rival Labs", "mentions": 5, "avgPosition": 3, "relationship": "DIRECT" }
],
"topSources": [
{ "domain": "acme.example", "citations": 3 }
]
}
]
}
],
"providerAverages": [
{ "provider": "openai", "score": 72, "mentionRate": 65.0, "shareOfVoice": 18.5, "citationRate": 30.2, "sentiment": 81.0 },
{ "provider": "perplexity", "score": 58, "mentionRate": 50.0, "shareOfVoice": 12.3, "citationRate": 42.1, "sentiment": 76.0 },
{ "provider": "anthropic", "score": 45, "mentionRate": 35.0, "shareOfVoice": 9.8, "citationRate": 15.0, "sentiment": 72.0 }
],
"summary": {
"totalRows": 12,
"averageMentionRate": 50,
"topPerforming": {
"rowId": "topic_01",
"rowName": "Data exports",
"mentionRate": 52.4
},
"needsAttention": {
"rowId": "topic7",
"rowName": "Pricing",
"mentionRate": 31.0
}
}
}
Errors
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_PARAMETER | Invalid query parameter (e.g., unknown granularity) |
| 401 | gateway error | Missing or invalid API token |
| 404 | BRAND_NOT_FOUND | Brand doesn’t exist or not accessible |
| 429 | gateway error | Rate limit exceeded; honor Retry-After |

