API Reference
Complete reference for the LLMMonitor REST API. All endpoints return JSON. Base URL: https://api.llmmonitor.com.
Base URL
https://api.llmmonitor.com
Authentication
LLMMonitor supports two authentication methods:
Supabase JWT (Recommended)
Pass your Supabase session token in the Authorization header:
curl -X GET "https://api.llmmonitor.com/api/data" \
-H "Authorization: Bearer YOUR_SUPABASE_JWT"
import requests
headers = {"Authorization": f"Bearer {supabase_jwt}"}
response = requests.get("https://api.llmmonitor.com/api/data", headers=headers)
print(response.json())
const response = await fetch('https://api.llmmonitor.com/api/data', {
headers: { 'Authorization': `Bearer ${supabaseJwt}` }
});
const data = await response.json();
Legacy Header Auth
Pass the user email in the X-User-Email header. This method is available for backward compatibility.
curl -X GET "https://api.llmmonitor.com/api/data" \
-H "X-User-Email: user@example.com"
Data Endpoints
GET /api/data
Returns all scan records with optional filters.
curl -X GET "https://api.llmmonitor.com/api/data?llm=chatgpt&limit=50" \
-H "Authorization: Bearer YOUR_JWT"
params = {"llm": "chatgpt", "limit": 50}
response = requests.get(
"https://api.llmmonitor.com/api/data",
headers=headers, params=params
)
const params = new URLSearchParams({ llm: 'chatgpt', limit: '50' });
const response = await fetch(`https://api.llmmonitor.com/api/data?${params}`, {
headers: { 'Authorization': `Bearer ${jwt}` }
});
Response
{
"scans": [
{
"id": 1042,
"scan_id": "20260411_142530",
"date": "2026-04-11",
"time": "14:25:30",
"prompt": "What's the best CRM for small teams?",
"brand": "AcmeCorp",
"brand_mentioned": 1,
"position": "Rank 1",
"sentiment": "positive",
"sentiment_score": 7.0,
"mention_count": 3,
"competitors_found": "Salesforce,HubSpot,Pipedrive",
"competitor_count": 3,
"response_words": 342,
"llm": "ChatGPT",
"location": "US",
"search_queries": "best CRM small business,CRM comparison 2026",
"citations": "techcrunch.com,g2.com,capterra.com"
}
],
"total": 284
}
GET /api/summary
Aggregated KPIs: visibility, sentiment, SoV, position, and trends.
curl -X GET "https://api.llmmonitor.com/api/summary?days=30" \
-H "Authorization: Bearer YOUR_JWT"
Response
{
"visibility": 64.2,
"visibility_delta": 3.1,
"avg_sentiment": 5.8,
"sentiment_delta": -0.4,
"share_of_voice": 38.5,
"avg_position": 2.3,
"total_scans": 150,
"brand_mentions": 96,
"competitor_count": 4,
"top_competitors": [
{"name": "Salesforce", "visibility": 72.0, "sentiment": 6.2},
{"name": "HubSpot", "visibility": 58.4, "sentiment": 4.8}
]
}
GET /api/performance
Per-prompt performance metrics.
curl -X GET "https://api.llmmonitor.com/api/performance" \
-H "Authorization: Bearer YOUR_JWT"
Response
{
"prompts": [
{
"text": "What's the best CRM for small teams?",
"sov_pct": 42.0,
"visibility_pct": 68.0,
"scans": 25,
"competitors": ["Salesforce", "HubSpot"],
"avg_sentiment": 6.1
}
]
}
Analytics Endpoints
GET /api/brand-health
Composite brand health score with AI-generated insights.
curl -X GET "https://api.llmmonitor.com/api/brand-health" \
-H "Authorization: Bearer YOUR_JWT"
Response
{
"health_score": 72.4,
"components": {
"visibility": 68.0,
"sentiment": 65.2,
"position": 78.0
},
"insights": [
"Your visibility on ChatGPT (72%) is significantly higher than Gemini (48%)",
"Sentiment trending positive — up 3.2 points over last 30 days",
"Competitor 'HubSpot' gaining ground: +8% visibility this month"
]
}
GET /api/competitor-radar
Top competitors with visibility, sentiment, and position data.
curl -X GET "https://api.llmmonitor.com/api/competitor-radar?limit=6" \
-H "Authorization: Bearer YOUR_JWT"
Response
{
"competitors": [
{
"name": "Salesforce",
"visibility": 72.0,
"avg_sentiment": 6.2,
"avg_position": 1.8,
"co_mention_rate": 45.0
}
]
}
GET /api/sro-score
SRO Score with component breakdown and recommendations.
curl -X GET "https://api.llmmonitor.com/api/sro-score" \
-H "Authorization: Bearer YOUR_JWT"
Response
{
"sro_score": 71,
"components": {
"visibility": {"score": 78, "weight": 0.30},
"position": {"score": 65, "weight": 0.20},
"sentiment": {"score": 72, "weight": 0.15},
"citation_presence": {"score": 58, "weight": 0.20},
"ugc_coverage": {"score": 82, "weight": 0.15}
},
"recommendations": [
{"priority": "high", "action": "Improve citation presence — only 12% of scans cite your domain", "impact": "+8 points"},
{"priority": "medium", "action": "Target editorial sources in your industry for PR outreach", "impact": "+4 points"}
]
}
GET /api/battlecards
Head-to-head win rates against each competitor.
curl -X GET "https://api.llmmonitor.com/api/battlecards" \
-H "Authorization: Bearer YOUR_JWT"
Scan Endpoints
POST /api/scan
Trigger a manual scan. Requires scans.
curl -X POST "https://api.llmmonitor.com/api/scan" \
-H "Authorization: Bearer YOUR_JWT" \
-H "Content-Type: application/json" \
-d '{"llms": ["chatgpt", "gemini"], "headless": true}'
payload = {"llms": ["chatgpt", "gemini"], "headless": True}
response = requests.post(
"https://api.llmmonitor.com/api/scan",
headers=headers, json=payload
)
print(response.json())
const response = await fetch('https://api.llmmonitor.com/api/scan', {
method: 'POST',
headers: {
'Authorization': `Bearer ${jwt}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ llms: ['chatgpt', 'gemini'], headless: true })
});
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| llms | string[] | Yes | Which LLMs to scan: "chatgpt", "gemini", "claude", "perplexity" |
| headless | boolean | No | Run Selenium in headless mode. Default: true |
Response
{
"status": "started",
"scan_id": "20260411_142530",
"scans_required": 10,
"scans_available": 280,
"prompts": 5,
"llms": ["chatgpt", "gemini"]
}
GET /api/scan/status
Check scan progress. Returns SSE-like log stream status.
curl -X GET "https://api.llmmonitor.com/api/scan/status?scan_id=20260411_142530" \
-H "Authorization: Bearer YOUR_JWT"
Response
{
"scan_id": "20260411_142530",
"status": "running",
"progress": {"completed": 4, "total": 10},
"logs": [
"[14:32:05] [ChatGPT] Sending: What's the best CRM for small teams?",
"[14:32:18] [ChatGPT] Response received — brand: YES"
]
}
Error Responses
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | Invalid or missing JWT token |
| 402 | insufficient_scans | Not enough scans to run the scan |
| 409 | scan_in_progress | A scan is already running |
| 429 | rate_limited | Too many requests — wait and retry |