Sentiment Themes
The recurring themes AI answers raise about a tracked domain, each tagged positive or negative.
curl --request GET \
--url 'https://api.aiclicks.io/api/v1/sentiment/themes?domain_id=8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3&days=30' \
--header 'Authorization: Bearer ak_live_xxx'
import httpx, os
resp = httpx.get(
"https://api.aiclicks.io/api/v1/sentiment/themes",
params={
"domain_id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3",
"days": 30,
},
headers={"Authorization": f"Bearer {os.environ['AICLICKS_API_KEY']}"},
)
resp.raise_for_status()
for t in resp.json()["data"]["items"]:
print(f"{t['occurrences']:>3} {t['sentiment']:<8} {t['name']}")
const url = new URL("https://api.aiclicks.io/api/v1/sentiment/themes");
url.searchParams.set("domain_id", "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3");
url.searchParams.set("days", "30");
const resp = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.AICLICKS_API_KEY}` },
});
const { data } = await resp.json();
for (const t of data.items) {
console.log(`${t.occurrences} ${t.sentiment} ${t.name}`);
}
{
"data": {
"items": [
{
"id": "c5ead2c3-c338-45c3-a526-e6aea946a929",
"name": "Limited functionality and maturity gaps",
"sentiment": "negative",
"occurrences": 8,
"created_at": "2026-06-15"
},
{
"id": "febb61fa-7ff5-45f4-9ba3-f4eb959a7acb",
"name": "Strong, favorable reviews",
"sentiment": "positive",
"occurrences": 5,
"created_at": "2026-06-15"
},
{
"id": "7a9f396a-5f0c-4786-be03-488802a582fb",
"name": "Convenient and intuitive interface",
"sentiment": "positive",
"occurrences": 4,
"created_at": "2026-06-15"
}
]
},
"domain_id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3",
"days": 30,
"model": "all",
"generated_at": "2026-06-17T10:00:11.218Z"
}
{ "detail": "domain_id query parameter is required. List the domains this key can access with GET /api/v1/domains, then pass ?domain_id=<uuid>." }
{ "detail": "Invalid or revoked API key" }
{ "detail": "API access is not enabled for this team. Contact support@aiclicks.io." }
{ "detail": "Domain not found" }
{ "detail": "Too many requests. Please try again later." }
The why behind your sentiment split. Each row is a named theme extracted from AI answers about your brand — e.g. "responsive support" (positive) or "pricing concerns" (negative) — with how many times it came up. Sorted by occurrences descending, so the loudest themes are first.
Theme names are generated in the language the AI answers were written in, so non-English domains return non-English theme names. Use the sentiment field, not the name, for programmatic classification.
domain_id is a required query parameter. Use GET /api/v1/domains to discover which domains the calling key can access.
Sentiment is a paid feature. The endpoint returns 403 unless the domain's team is on a Pro, Business, or Enterprise plan — in addition to the usual API-access requirement.
Authorizations
Your API key formatted as Bearer ak_live_<your-key>. Create one in the dashboard under Settings → Developers.
Optional UUID for log correlation. If omitted, we generate one and echo it back in the response.
Query parameters
UUID of the domain. Find domains via GET /api/v1/domains. Omitting this returns 400.
Look-back window in days, 1–365. Defaults to 30. Counted as an exact window (today - days + 1), not snapped to buckets.
Restrict to themes seen on a single AI channel by generic name — ChatGPT, Perplexity, Gemini, AI Overviews, Claude, Grok, Microsoft Copilot. Defaults to all. Raw model identifiers are also accepted. See Models.
Response
The list payload.
One row per theme, sorted by occurrences descending. Archived and renamed themes follow dashboard state — a theme renamed in the UI returns its custom name here.
Echo of the requested domain.
Echo of the requested window.
Echo of the requested model filter (all when unset).
ISO-8601 timestamp of when the server produced (or cached) this response.
Response headers
| Header | Description |
|---|---|
X-Cache | HIT or MISS. Indicates whether the response came from cache. |
X-Request-Id | Unique request id. Echoes incoming if you set one. |
X-RateLimit-Limit | Max requests per minute for this key. |
X-RateLimit-Remaining | Requests remaining in current minute. |
X-RateLimit-Reset | Unix epoch seconds when the window resets. |
Caching
Cached for 1 hour per (domain_id, days, model). Newly completed analyses appear after the TTL expires.
Related
GET /api/v1/sentiment/overview— the positive/negative split these themes roll up into.GET /api/v1/sentiment/theme-sources— the URLs AI answers cited when raising these themes.
Errors
domain_id query parameter missing. Body points you at /api/v1/domains.
Missing, malformed, or revoked API key.
Team's developer_access flag is off, the domain belongs to a team your API key is not scoped to, your allowed_domains allowlist excludes it, or the team's plan doesn't include sentiment (requires Pro, Business, or Enterprise).
domain_id is malformed, does not exist, or your user is not a member of its team.
Rate limit exceeded. Inspect the Retry-After header for how long to wait.
Empty result
If no sentiment themes exist in the window, the response is a successful 200 with an empty list:
{
"data": { "items": [] },
"domain_id": "8f1d3c0a-2f9b-4c11-9b80-7a82e1f0c3f3",
"days": 30,
"model": "all",
"generated_at": "2026-06-17T10:00:11.218Z"
}