Documentation Index Fetch the complete documentation index at: https://docs.qwairy.co/llms.txt
Use this file to discover all available pages before exploring further.
Learn how to use the Qwairy API with real-world examples, from simple queries to complete integrations.
Custom Dashboard Build a branded GEO dashboard with KPIs and competitor rankings
Weekly Reports Automate week-over-week performance reports
Competitive Analysis Track your position against competitors
Data Export Export data for BI tools (BigQuery, Snowflake, CSV)
Quick Start
Get your GEO Score in one command:
curl -s -H "Authorization: Bearer $QWAIRY_API_TOKEN " \
"https://www.qwairy.co/api/v1/brands/YOUR_BRAND_ID/performance?period=30" \
| jq '.scores'
Output:
{
"global" : 62 ,
"mentionRate" : 45.2 ,
"sourceRate" : 23.9 ,
"shareOfVoice" : 8.13 ,
"sentiment" : 78.1
}
API Client
Reusable client with error handling for all guides on this site.
// qwairy-client.js
class QwairyClient {
constructor ( apiToken ) {
this . baseUrl = 'https://www.qwairy.co/api/v1' ;
this . headers = {
'Authorization' : `Bearer ${ apiToken } ` ,
'Content-Type' : 'application/json' ,
};
}
async request ( endpoint , params = {}) {
const url = new URL ( ` ${ this . baseUrl }${ endpoint } ` );
Object . entries ( params ). forEach (([ key , value ]) => {
if ( value !== undefined && value !== null ) {
url . searchParams . append ( key , value );
}
});
const response = await fetch ( url . toString (), { headers: this . headers });
if ( ! response . ok ) {
const error = await response . json (). catch (() => ({}));
const code = error . error ?. code || 'UNKNOWN_ERROR' ;
const message = error . error ?. message || `HTTP ${ response . status } ` ;
if ( response . status === 429 ) {
const resetTime = response . headers . get ( 'X-RateLimit-Reset' );
throw new Error ( `Rate limited. Retry after: ${ resetTime } ` );
}
throw new Error ( `[ ${ code } ] ${ message } ` );
}
return response . json ();
}
async getPerformance ( brandId , params = {}) {
return this . request ( `/brands/ ${ brandId } /performance` , params );
}
async getCompetitors ( brandId , params = {}) {
return this . request ( `/brands/ ${ brandId } /competitors` , params );
}
async getSourceDomains ( brandId , params = {}) {
return this . request ( `/brands/ ${ brandId } /source-domains` , params );
}
async getSourceUrls ( brandId , params = {}) {
return this . request ( `/brands/ ${ brandId } /source-urls` , params );
}
async getAnswers ( brandId , params = {}) {
return this . request ( `/brands/ ${ brandId } /answers` , params );
}
async getSearch ( brandId , params = {}) {
return this . request ( `/brands/ ${ brandId } /search` , params );
}
async getCompetitorEvolution ( brandId , competitorId , params = {}) {
return this . request ( `/brands/ ${ brandId } /competitors/ ${ competitorId } /evolution` , params );
}
}
// Usage
const client = new QwairyClient ( process . env . QWAIRY_API_TOKEN );
All guides on this site use this client. Copy it to your project or adapt it to your needs.
TypeScript Types
Type definitions for the API client.
// qwairy-types.ts
interface QwairyScores {
global : number ;
mentionRate : number ;
sourceRate : number ;
shareOfVoice : number ;
sentiment : number ;
}
interface QwairyMethodology {
promptsCount : number ;
responsesTotal : number ;
providers : string [];
}
interface QwairyPerformance {
scores : QwairyScores ;
methodology : QwairyMethodology ;
byProvider ?: Array <{ provider : string ; scores : QwairyScores }>;
byTopic ?: Array <{ topic : string ; scores : QwairyScores }>;
byTag ?: Array <{ tag : string ; scores : QwairyScores }>;
}
interface QwairyCompetitor {
id : string ;
name : string ;
relationship : 'SELF' | 'DIRECT' | 'INDIRECT' ;
totalMentions : number ;
shareOfVoice : number ;
avgPosition : number ;
avgSentiment : number ;
}
interface QwairySource {
id : string ;
domain : string ;
type : 'INSTITUTIONAL' | 'COMMERCIAL' | 'MEDIA' | 'BLOG' | 'SOCIAL' | 'OTHER' ;
isSelf : boolean ;
totalMentions : number ;
rate : number ;
avgPosition : number ;
}
interface QwairyPagination {
total : number ;
count : number ;
limit : number ;
offset : number ;
}
interface QwairyCompetitorsResponse {
success : boolean ;
pagination : QwairyPagination ;
competitors : QwairyCompetitor [];
}
interface QwairySourcesResponse {
success : boolean ;
pagination : QwairyPagination ;
sources : QwairySource [];
}
interface QwairyAnswer {
id : string ;
promptId : string ;
promptText : string ;
provider : string ;
model : string ;
textPreview : string ;
hasSelfMention : boolean ;
selfMentionPosition : number | null ;
hasSelfSource : boolean ;
competitorsCount : number ;
sourcesCount : number ;
sentiment : number ;
relevance : number ;
createdAt : string ;
}
interface QwairySearchQuery {
id : string ;
query : string ;
prompt : string ;
provider : string ;
createdAt : string ;
}
interface QwairyAnswersResponse {
success : boolean ;
pagination : QwairyPagination ;
answers : QwairyAnswer [];
}
interface QwairySearchResponse {
success : boolean ;
pagination : QwairyPagination ;
searches : QwairySearchQuery [];
}
Fetch all results when you have more than 100 items.
async function fetchAllCompetitors ( client , brandId , period = 30 ) {
const allCompetitors = [];
let offset = 0 ;
const limit = 100 ;
while ( true ) {
const response = await client . getCompetitors ( brandId , { period , limit , offset });
allCompetitors . push ( ... response . competitors );
if ( response . competitors . length < limit || allCompetitors . length >= response . pagination . total ) {
break ;
}
offset += limit ;
}
return allCompetitors ;
}
// Usage
const allCompetitors = await fetchAllCompetitors ( client , 'your-brand-id' , 30 );
console . log ( `Total competitors: ${ allCompetitors . length } ` );
Field Reference
Mapping between business metrics and API fields:
Business Metric Endpoint Field Description GEO Score /performancescores.globalOverall optimization score (0-100) Brand Visibility /performancescores.mentionRate% of responses mentioning your brand Citation Rate /performancescores.sourceRate% of responses citing your content Share of Voice /competitorsshareOfVoiceYour % of all competitor mentions Share of Citations /source-domainsrateSource’s % of all citations Sentiment /performancescores.sentimentAverage sentiment score (0-100) Average Position /competitorsavgPositionAverage rank in AI responses (1 = first) Mentioned but not cited /answershasSelfMention + hasSelfSourceResponses where you’re mentioned but not linked AI search queries /searchqueryWeb queries triggered by AI before responding
Use /performance for aggregated KPIs. Use /competitors and /source-domains for detailed breakdowns. Use /answers and /search for LLM-level diagnostics.