AI Visibility API
Base path: `/api/ai-reach/`
All endpoints require Authorization: Bearer <token>.
Queries#
List queries#
Returns all active and paused queries for the authenticated tenant.
Response
Create query#
Request body
| Field | Type | Required | Description |
|---|---|---|---|
query_text | string | yes | Natural-language query, max 1000 chars. Must be unique per tenant. |
category | string | no | Grouping label (brand awareness, product discovery, etc.) |
tags | string[] | no | Free-form tags |
providers | string[] | no | Subset of chatgpt,perplexity,claude,gemini,grok. Empty = all. |
is_active | boolean | no | Default true |
schedule | string | no | hourly, daily, or weekly. Default daily. |
Response 201 Created — the created AIQuery object.
Get / Update / Delete query#
PATCH supports all fields except id, created_at, updated_at.
Run query immediately#
Enqueues run_ai_query Celery task immediately. Returns before execution completes.
Response 200
Get query results#
Returns the 50 most recent execution results for this query (all providers).
Response
Dashboard#
Get aggregated metrics#
Returns rolled-up metrics across all queries for the authenticated tenant.
Response
When no results exist, all numeric fields return 0 or null and arrays are empty.
ClickHouse Table#
segmentation.ai_visibility_snapshots
| Column | Type | Description |
|---|---|---|
tenant_id | String | Tenant ID |
query_id | String | AIQuery PK (as string) |
provider | LowCardinality(String) | Provider ID |
mention_rate | Float32 | 0–1 |
avg_position | Float32 | 1-based; 0 if not mentioned |
share_of_voice | Float32 | 0–1 |
sentiment_score | Float32 | 0–1 |
mentioned_skus | String | JSON array of matched product SKUs |
is_simulated | UInt8 | 1 if adapter returned stub data |
captured_date | Date | Date of execution |
ReplacingMergeTree on captured_date. ORDER BY (tenant_id, query_id, provider, captured_date).
Competitors#
List competitors#
Response
Create competitor#
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Primary brand name. Must be unique per tenant. |
brand_aliases | string[] | no | Alternate names matched case-insensitively in AI responses. |
domain | string | no | Brand domain (display only). |
is_active | boolean | no | Default true. Inactive competitors are excluded from tracking. |
Response 201 Created — the created Competitor object.
Get / Update / Delete competitor#
Competitor Comparison#
Cross-query position comparison#
For each query that has results, returns the tenant's average position alongside each registered competitor's average position.
Response
win_rate per query competitor entry: fraction of results where tenant was mentioned and outranked that competitor (or competitor was not mentioned).
Win rate summary#
Aggregate win/loss/tie counts per competitor across all queries. Sorted by win rate descending.
Response
Win conditions:
- Win — tenant mentioned and outranks competitor, or competitor not mentioned at all
- Loss — competitor mentioned and outranks tenant, or tenant not mentioned
- Tie — both at same position
Alert Rules#
List alerts#
Response — paginated list of CompetitorAlert objects.
Create alert#
Request body
| Field | Type | Required | Description |
|---|---|---|---|
alert_type | string | yes | sov_jump, rank_drop, or new_competitor |
competitor | integer | no | Competitor ID. Required for sov_jump. |
threshold | float | no | sov_jump: SOV delta (e.g. 0.1 = 10%). rank_drop: worst allowed position (e.g. 5). Default 0.1. |
webhook_url | string | no | POST target when alert fires. Payload is JSON with alert_type, message, and context fields. |
is_active | boolean | no | Default true. |
Alert types:
| Type | Trigger | Threshold meaning |
|---|---|---|
sov_jump | Competitor's 7-day avg SOV increased vs prior 7 days | SOV delta (0–1) |
rank_drop | Tenant's 3-day avg position exceeds threshold | Worst allowed position (integer) |
new_competitor | Reserved for future detection | — |
Get / Update / Delete alert#
ClickHouse Tables#
segmentation.ai_visibility_snapshots — tenant-level visibility per query/provider/date.
segmentation.competitor_snapshots — competitor-level metrics per query/provider/date.
| Column | Type | Description |
|---|---|---|
tenant_id | String | Tenant ID |
query_id | String | AIQuery PK |
provider | LowCardinality(String) | Provider ID |
competitor_name | String | Competitor primary name |
position | Float32 | 1-based mention position; 0 if not mentioned |
sov | Float32 | Share of voice for this competitor in this result |
sentiment_score | Float32 | 0–1 |
is_mentioned | UInt8 | 1 if found in AI response |
captured_date | Date | Date of execution |
ReplacingMergeTree on captured_date. ORDER BY (tenant_id, query_id, provider, competitor_name, captured_date).