Overview
The API gives you read-only access to your project’s weekly prompt metrics, raw LLM responses, content item evaluations, and reporting-dashboard aggregates (the same LLM metrics and GA-based series the Reporting page uses). Use it to:- Pull brand mention and citation rates into your own dashboards
- Read the raw LLM responses behind those metrics — useful when briefing a writer
- Track prompt and provider performance over time
- Read prompt metadata (collections, sentiment) alongside visibility metrics
- Export content quality scores (extractability, humanness, and related evaluation fields)
- Automate exports that match Impact and Competitors reporting
Access and authentication
Generate your project token in Settings → API.- One active token per project
- Token is scoped to that project only
- Regenerating immediately invalidates the previous token
Authorization header:
/reports/llm, /reports/ga) also accept a Supabase user JWT for in-app use; see those sections for details.
Response shape
Every endpoint returns one of:/reports/llm and /reports/ga endpoints are exceptions — they return the existing dashboard payloads unchanged for backward compatibility with the in-app Reporting page.
Data freshness
- Prompt metrics are updated weekly
- Weekly windows are Sunday-based
- If you do not pass
week_start, endpoints that need a week return your latest available week
Base URL
Endpoint index
| Resource | Method & path | Notes |
|---|---|---|
| List prompts | GET /prompts | Paginated, filterable |
| Single prompt | GET /prompts/{id} | Metrics + provider breakdown + top citations |
| List responses for a prompt | GET /prompts/{id}/responses | Raw LLM responses, paginated |
| Single response | GET /prompts/{id}/responses/{response_id} | One iteration’s full text |
| Prompt timeseries | GET /prompts/{id}/timeseries | Trend across weeks for one prompt |
| Project timeseries | GET /timeseries | Trend across weeks for the whole project |
| Project providers | GET /providers | Provider breakdown for one week |
| List content items | GET /content-items | Paginated |
| Single content item | GET /content-items/{id} | With latest evaluation |
| LLM report | GET /reports/llm | Visibility & competitor aggregates |
| GA report | GET /reports/ga | GA4 traffic + AI-platform filter |
| Summary | GET /reports/summary | Top-line weekly metrics |
Prompts
List prompts — GET /prompts
Paginated prompt-level metrics for one week. Each row includes collections and average_sentiment from the prompt record.
Query params
| Parameter | Description |
|---|---|
week_start | Optional, YYYY-MM-DD, normalized to Sunday |
provider | Optional AI provider id |
query | Optional, case-insensitive substring match on prompt text |
limit | Optional, default 50, max 100 |
cursor | Optional, opaque cursor from pagination.next_cursor |
Single prompt — GET /prompts/{id}
Detail for a single prompt for one week.
Query params
week_start(optional)
week_startprompt:id,text,intent,search_volume_score,average_sentiment,collections[]mention_rate,first_mention_rate,citation_rate,search_countproviders[]:id,name,mention_rate,first_mention_rate,citation_ratetop_citations[]:url,domain,citation_type,count
404if the prompt does not exist or is not in this project
Responses for a prompt — GET /prompts/{id}/responses
Raw LLM output for each iteration recorded against this prompt during the week. Useful for content briefs — you can see exactly what each provider said.
Query params
| Parameter | Description |
|---|---|
week_start | Optional, defaults to the latest week |
provider | Optional AI provider id to filter to one provider |
limit | Optional, default 25, max 100 |
cursor | Optional pagination cursor |
cursor to read every iteration in the week.
Errors
404if the prompt does not exist or is not in this project
Single response — GET /prompts/{id}/responses/{response_id}
A single LLM response by id.
Response data
id,run_id,prompt_idprovider:id,nameresponse_textcreated_at
404if the response does not exist or its prompt is not in this project
Prompt timeseries — GET /prompts/{id}/timeseries
Trend across weeks for one prompt.
Query params
from_week_start(optional, defaults to 12 weeks ago)to_week_start(optional, defaults to latest week)provider(optional)
- At most
52weeks per request
prompt_idseries[]: each point hasweek_start,mention_rate,first_mention_rate,citation_rate,prompt_count,search_count
Project-level
Project timeseries — GET /timeseries
Same shape as /prompts/{id}/timeseries but aggregated across every prompt in the project.
Query params
from_week_start,to_week_start,provider(all optional)
series[]: as above
Providers — GET /providers
Per-provider breakdown for one week.
Query params
week_start(optional)
week_startproviders[]:id,name,prompt_count,search_count,mention_rate,first_mention_rate,citation_rate,owned_citations,social_citations,earned_citations,competitor_citations
Content
List content items — GET /content-items
All content items in the project, paginated, with the latest evaluation per item.
Query params
limit(optional, default50, max100)cursor(optional)
content_items[]:id,title,url,created_at,updated_at,evaluationevaluationisnullif there is no row inexecuting_contentitemevaluation, otherwise an object with:score,content_quality,audience_alignment,seo_optimization,engagement_potential,eeat,extractability,humanness_score,prompt_focus,created_at,updated_atand (when present)llm_justifications
Single content item — GET /content-items/{id}
Response data
Same shape as one element of content_items[] above.
Errors
404if the item does not exist or is not in this project
Reports
The three reporting endpoints power the in-app Reporting page. Periods use 7 / 30 / 365 calendar days for week / month / year.Authentication
- Project API token:
Authorization: Bearer tp_.... Do not passproject_id. - Logged-in user (Supabase JWT):
Authorization: Bearer <access_token>plusproject_idin the query string. The user must have access to that project.
LLM report — GET /reports/llm
Full LLM-side reporting: weighted mention rate, citation rate, sentiment, competitor tables and weekly series, citation bucket breakdown, optional experiments. Returns the same payload the in-app Reporting page consumes (with a top-level meta object).
Query params
| Parameter | Description |
|---|---|
project_id | Required for user JWT; omit with API token |
start_date, end_date | YYYY-MM-DD inclusive window |
period | week | month | year (default month; ignored when start_date and end_date are set) |
collections | Comma-separated tag names |
tag_ids | Comma-separated tag UUIDs |
intent / intents | Comma-separated intent values |
llm_provider / provider_ids | Comma-separated AI provider UUIDs |
location / locations | Comma-separated location strings |
include_experiments | true/false (default true) |
skip_competitors | true/false (default false) |
page, page_size | Pagination for the weekly series slice (defaults 0, 50, max 500) |
company_id | Optional |
target_type, target_id | Optional experiment filter |
GA report — GET /reports/ga
GA4 traffic with platform-filtered series. Calls the fetch-google-analytics pipeline, then returns the full analytics payload plus filtered_daily rows (traffic_raw, ai_sessions) using the same platform rules as the Reporting UI. Requires GA4 connected for the project.
Query params
| Parameter | Description |
|---|---|
project_id | Required for user JWT; omit with API token |
start_date, end_date | YYYY-MM-DD; both required together if you override period |
period | week | month | year (default month) |
page_path | Optional; restricts GA to one landing path |
platforms | Comma-separated UI platform ids (e.g. chatgpt,google-serps). Omit or empty = all traffic |
fetch-google-analytics (e.g. 401 with authError: true).
Summary — GET /reports/summary
Top-line metrics for one week.
Query params
week_start(optional, normalized to Sunday)provider(optional, AI provider id)
week_starttotals:prompt_count,search_count,mention_rate,first_mention_rate,citation_ratecitations:owned,social,earned,competitorproviders[]:id,name,mention_rate,first_mention_rate,citation_rate
Rate and timeout limits
- Prompts list, responses list, and content items list are capped at
100rows per request - Timeseries is capped at
52weeks - Requests may return
429if rate or time budgets are exceeded
Errors
Common status codes:400invalid input401missing or invalid token404not found (prompt, response, or content item)405method not allowed429rate or timeout guardrail500unexpected server error
Migrating from the previous API (May 2026)
The earlier flat endpoints were replaced with this REST hierarchy in May 2026. The old paths now return404. If you have an integration written against the previous shape, update the paths as follows:
| Old path | New path |
|---|---|
GET /prompt?id= | GET /prompts/{id} |
GET /prompt-timeseries?id= | GET /prompts/{id}/timeseries |
GET /prompt-timeseries (no id) | GET /timeseries |
GET /prompt-providers | GET /providers |
GET /content-item?id= | GET /content-items/{id} |
GET /report | GET /reports/llm |
GET /ga-report | GET /reports/ga |
GET /summary | GET /reports/summary |
/reports/llm and /reports/ga, which preserve the dashboard payload for in-app use) now returns the standard envelope:
prompts, content_items, series, etc. at the top level, those now live under data. Pagination cursors that were nested under page.has_more / page.next_cursor are now under pagination.has_more / pagination.next_cursor.