Learn how to use the Qwairy API with real-world examples, from simple queries to complete integrations.
Quick Start
Get your GEO Score in one command:
curl -s -H "Authorization: Bearer $QWAIRY_API_TOKEN" \
"https://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://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 getSources(brandId, params = {}) {
return this.request(`/brands/${brandId}/sources`, 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[];
}
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 | /performance | scores.global | Overall optimization score (0-100) |
| Brand Visibility | /performance | scores.mentionRate | % of responses mentioning your brand |
| Citation Rate | /performance | scores.sourceRate | % of responses citing your content |
| Share of Voice | /competitors | shareOfVoice | Your % of all competitor mentions |
| Share of Citations | /sources | rate | Source’s % of all citations |
| Sentiment | /performance | scores.sentiment | Average sentiment score (0-100) |
| Average Position | /competitors | avgPosition | Average rank in AI responses (1 = first) |
Use /performance for aggregated KPIs. Use /competitors and /sources for detailed breakdowns.