Mentions
Query the long-running brand-mentions database built by our crawler, or force an on-demand fan-out across all four providers when you need fresh data for a brand we haven't indexed yet.
Legacy endpoint. This documents an older surface kept for back-compat with existing integrations. New integrations should use /v1/check instead — see the quickstart for the modern API.
Pricing at a glance
GET /v1/mentions/search— flat 10¢ per call. Pure Postgres read, no LLM calls.POST /v1/mentions/crawl— flat $2.00 (200¢) per call. Live 4-provider fan-out with web_search ON, results indexed into the mentions DB for future searches.
GET /v1/mentions/search
/v1/mentions/search— Query the brand-mentions database (10¢ flat)Ask "what have the LLMs been saying about brand since date?". The crawler writes rows on a schedule; this endpoint is the read side. Use it when you need historical trends or you're checking a brand we likely already cover. If the query returns zero rows, we include up to 3 "did you mean?" suggestions via pg_trgm fuzzy match on the brand catalog.
Query parameters
| Field | Type | Description |
|---|---|---|
brandrequired | string | The brand name to search for. Lowercased + whitespace-collapsed server-side before matching. 1–120 chars. |
provideroptional | 'openai' | 'anthropic' | 'gemini' | 'perplexity' | Optional — filter to mentions sourced from a single provider. |
sinceoptional | string (ISO 8601) | Optional lower bound on snapshot_at. Only mentions captured at or after this time are returned. |
limitoptional | number | Max rows to return. 1–100. Default: 50 |
Search response
| Field | Type | Description |
|---|---|---|
request_idoptional | string | Unique id for this call (use in support requests). |
queryoptional | { brand, normalized_brand, provider, since, limit } | Echo of the parsed query, including the normalized_brand actually looked up. |
mentionsoptional | Mention[] | Rows newest first by snapshot_at, up to `limit`. |
suggestionsoptional | Suggestion[] | Up to 3 fuzzy-matched alternative brand names. Only populated when `mentions` is empty. |
usageoptional | { billable_units, latency_ms, cost_cents } | Per-call cost. cost_cents is always 10 for this endpoint. |
Top-level fields
Mention object
| Field | Type | Description |
|---|---|---|
idoptional | number | Row id in brand_mentions (stable, auto-incrementing). |
brandoptional | string | The brand as it appeared in the provider response. |
provideroptional | 'openai' | 'anthropic' | 'gemini' | 'perplexity' | Which LLM surfaced this mention. |
modeloptional | string | Exact model version that produced the answer. |
promptoptional | string | The crawl prompt used when the snapshot was taken. |
prompt_categoryoptional | string | null | Optional bucket the prompt was tagged with. |
snapshot_atoptional | string (ISO 8601) | When the crawl ran. |
contentoptional | string | null | Provider response excerpt (up to 500 chars). |
rankoptional | number | null | Position of the brand in the provider's answer (0-indexed). Lower is better. |
sentimentoptional | 'positive' | 'neutral' | 'negative' | null | Classified tone of the mention. |
contextoptional | string | null | Surrounding sentence snippet. |
citationsoptional | Citation[] | URLs cited in the provider's answer. Always an array. |
raw_response_idoptional | string | null | Links back to the original /v1/ask response (if retained). |
Suggestion object
| Field | Type | Description |
|---|---|---|
brandoptional | string | Suggested brand display name. |
normalized_brandoptional | string | Normalized form used for matching. |
categoryoptional | string | null | Brand category if known. |
similarityoptional | number | pg_trgm similarity score, 0–1 (4 decimals). |
Search example
curl "https://api.mentionsapi.com/v1/mentions/search?brand=Supabase&provider=openai&limit=10" \
-H "Authorization: Bearer $MENTIONSAPI_KEY"POST /v1/mentions/crawl
/v1/mentions/crawl— On-demand 4-provider brand crawl ($2.00 flat)Flat 200¢ per call
Crawl fires a live fan-out to all four providers with web_search enabled, extracts brand mentions from each response, and writes them to the mentions database. Use it when you need fresh data and /v1/mentions/search returned empty or stale results. Auto-adds the brand to the catalog so scheduled crawls pick it up going forward.
Crawl request body
| Field | Type | Description |
|---|---|---|
brandrequired | string | The brand to crawl. 1–120 chars. Lowercased + trimmed on insert into brand_catalog. |
promptoptional | string | Custom crawl prompt. Default: "What are the best alternatives, competitors, or similar services to \"<brand>\"? List at least 10…". 1–2000 chars. |
categoryoptional | string | Optional category tag written to brand_catalog alongside the brand. 1–60 chars. |
Crawl response
| Field | Type | Description |
|---|---|---|
request_idoptional | string | Unique id for this crawl call. |
brandoptional | string | Brand display name, trimmed. |
normalized_brandoptional | string | Lowercased, whitespace-collapsed form. |
promptoptional | string | The prompt actually used (custom or the default template). |
mentionsoptional | CrawlMention[] | Only mentions of the queried brand (subset of all inserted rows). Each has brand, provider, model, snapshot_at, rank, sentiment, context, content_excerpt. |
total_mentions_foundoptional | number | Total rows inserted into brand_mentions across every brand the LLMs surfaced (includes competitors, not just the queried brand). |
providersoptional | ProviderResult[] | ProviderError[] | Raw per-provider outputs, same shape as /v1/ask — includes content, model, tokens, latency_ms, citations, or an error object on failure. |
usageoptional | { billable_units, latency_ms, cost_cents } | cost_cents is always 200 for a successful crawl. |
Crawl example
curl https://api.mentionsapi.com/v1/mentions/crawl \
-H "Authorization: Bearer $MENTIONSAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"brand": "Supabase",
"category": "postgres-hosting"
}'TypeScript SDK
import { MentionsAPIClient } from "@mentionsapi/sdk";
const client = new MentionsAPIClient({ apiKey: process.env.MENTIONSAPI_KEY! });
// Read the mentions database (10¢ per call).
const hits = await client.mentionsSearch({
brand: "Supabase",
provider: "openai",
limit: 20,
});
// Empty? Kick off a fresh crawl ($2.00), then re-read.
if (hits.mentions.length === 0) {
await client.mentionsCrawl({ brand: "Supabase" });
const retry = await client.mentionsSearch({ brand: "Supabase" });
console.log(retry.mentions);
}Pagination
GET /v1/mentions/search returns up to limit rows (max 100), newest first by snapshot_at. Cursor-based pagination is not yet available — iterate by narrowing the since window (e.g. re-query with since = oldest_row.snapshot_at after processing a page). We plan to ship next_cursor in a future release.
Python
import os
import httpx
BASE = "https://api.mentionsapi.com"
headers = {"Authorization": f"Bearer {os.environ['MENTIONSAPI_KEY']}"}
# Search (10¢)
r = httpx.get(
f"{BASE}/v1/mentions/search",
params={"brand": "Supabase", "limit": 20},
headers=headers,
)
r.raise_for_status()
data = r.json()
if not data["mentions"]:
# Kick off an on-demand crawl ($2.00)
httpx.post(
f"{BASE}/v1/mentions/crawl",
json={"brand": "Supabase"},
headers=headers,
timeout=60.0,
).raise_for_status()Errors
| Field | Type | Description |
|---|---|---|
invalid_requestoptional | 400 | Malformed query or body — missing brand, out-of-range limit, empty normalized brand, etc. |
invalid_api_keyoptional | 401 | Bearer token missing, malformed, or revoked. |
insufficient_creditsoptional | 402 | Your credit balance is below the call price (10¢ for search, 200¢ for crawl). Response includes balance_cents and required_cents. |
rate_limitedoptional | 429 | Tier rate limit exceeded. Honor the Retry-After header. |
internal_erroroptional | 500 | Database query failed (search) or an unexpected server-side failure. Retry, or contact support with the request_id from the response body. |
See the full error reference for payload shape and retry guidance.
Response headers
| Field | Type | Description |
|---|---|---|
X-RateLimit-Limitoptional | number | Your account's rate-limit ceiling for the current window. |
X-RateLimit-Remainingoptional | number | Calls remaining in the current window before 429s begin. |
Retry-Afteroptional | number (seconds) | Sent on 429 responses. Sleep at least this long before retrying. |
The unique call identifier is returned in the JSON body as request_id.