Skip to main content

Overview

Searchable exposes three programmatic surfaces. Pick the one that fits your use case:

MCP (AI assistants)

30+ read tools for Claude, Cursor, and other MCP clients — the richest way to query your data.

REST API

Fetch audits & issues and generate shareable reports with an API key — see the interactive reference + playground.

Ingest API

Send AI-bot traffic events from any language or platform.
API access requires a paid Searchable plan — API keys can’t be created on the Free plan.

Authentication

Create an API key in Settings → Workspace → Integrations in your Searchable dashboard. Keys start with sea_ and are shown only once — store it securely. Send it as a Bearer token on every request:

Scopes

Each key carries one or more scopes. Read endpoints require read (the default); write endpoints require write. A key can also be bound to a single project. A project-bound key only works against that project; leave a key unbound to use it across all projects you can access.

Fetch audits + issues

Retrieve the latest audit per page, when each was last completed, and optionally the open issues for each page.

Share of voice & competitors

Brand vs competitor share of voice, and the project’s real/tracked competitor roster (also available as the get_share_of_voice and get_competitors MCP tools). All four endpoints accept the same filter family: days, platform, topicId, unbranded/branded, country/locationId.
Two things to know on the competitors endpoints: the list view’s mentions is an all-time count that ignores days and the filters (mirrors the in-app Competitors list), and the detail view carries two distinct metrics — the top-level citations counts inline citations on responses that mention the competitor (any domain), while history[].domainSources counts source URLs (pages the engines consulted for generation, not inline citations) on the competitor’s own domain.

AI Traffic API

First-party AI-traffic measurement — crawler visits and AI-referral sessions sourced from the tracker/CDN pipeline (also available through the single consolidated get_ai_traffic MCP tool).
overview, bots, and correlation accept optional groupBy=platform|botCategory|botName. Omitting it preserves the legacy response. botCategory adds byCategory; botName adds byBot with botId, botName, botVendor, and botCategory; and correlation’s platform option adds the per-page byPlatform split. Existing byPlatform arrays on overview and bots remain present for every grouping. These arrays classify crawl requests only — correlation does not attribute a referral session to a particular crawler. The public crawler category set is:
  • ai_training — model-training collection, such as GPTBot and ClaudeBot
  • ai_search — AI retrieval/search fetching, such as OAI-SearchBot, Claude-SearchBot, and PerplexityBot
  • ai_assistant — a distinct user-triggered assistant fetch, such as ChatGPT-User, Claude-User, and Perplexity-User
  • ai_agent — autonomous agents acting on a user’s behalf
  • search_engine — conventional search indexing
The underlying registry currently also stores ad_inventory, ad_landing, and agentic-commerce. Those categories are dashboard-hidden and filtered out of these public crawler aggregates. The registry column is free text, so the stored set can grow; if a new category becomes dashboard-visible, it becomes an additive public output value. That makes ai_training → ai_search → ai_assistant available as a per-page crawl funnel. ai_search is evidence of retrieval/search crawling, not proof that the page appeared as a citation in an answer; use the citation/visibility APIs for that outcome. bots returns a paginated per-page crawler-activity list — items[] and pagination (limit/offset/returnedCount/hasMore/nextOffset; totalCount is always null since the ranking query doesn’t cheaply support an exact cross-platform total). referrals returns a daily AI-referral session timeseries by platform plus window totals. top-cited-pages requires an explicit platform (one of openai, anthropic, google, perplexity, microsoft) and returns 400 without one. platform and groupBy are validated strictly: an unrecognized value returns 400 invalid_argument listing the supported keys, never a silent empty result. AI Traffic endpoints return 409 { code: "traffic_not_connected", message, howToFix } when the project lacks the source required by that report — howToFix links straight to AI Traffic → Setup in the dashboard. Connect a source there, then retry.

Shopping visibility

AI shopping/product visibility (Peec-parity) — products surfaced in AI shopping/product-carousel responses (also available as the get_shopping_visibility MCP tool, view=summary|timeseries, or pass productId for detail).
productId is the product’s raw title (the id returned by the list endpoint above) — percent-encode it in the URL. The detail endpoint returns occurrences, vendor/pricing rows, a real per-platform breakdown, and up to 50 recent responses that surfaced the product. Requires a plan with Shopping Analytics (Scale or higher) — returns 403 { requiresUpgrade: true } if the workspace’s plan doesn’t include it and the project has data to fetch (an empty project still returns available:false first).

Ads

Sponsored ads surfaced in AI answers — who is advertising, the actual ad creatives, ad-heavy prompts, and the frequency trend (also available as the get_ads MCP tool, view=advertisers|creatives|prompts|timeseries).
/ads/advertisers is offset-paginated ({limit, offset, returnedCount, totalCount, hasMore, nextOffset}); pass an advertiser’s advertiserKey into /ads/creatives or /ads/timeseries to drill into one advertiser. /ads/creatives also accepts promptId and a free-text search; /ads/prompts accepts sortBy (promptText|adUnits|coveragePct|engines|totalResponses) + sortDir. All windows follow days (default 30, max 365). Ad data appears once tracked prompts surface sponsored ad units. promptId takes a prompt ID, not prompt text — an unrecognized ID matches nothing rather than erroring, so an empty result can mean an unresolved filter as well as no captured data. These endpoints take no topic or location filters; use the get_ads MCP tool for those.

Brand profile & domain authority

The knowledge-base brand profile plus AI-observed brand facts, and the domain’s Moz authority history (also available via the get_brand_profile MCP tool, which takes include: "domain_authority" for the Moz block).
domain-authority returns the latest Moz snapshot (domainAuthority, pageAuthority, spamScore, linkingRootDomains, fetchedAt) plus history[] over days (default 365, max 1095 — snapshots are roughly monthly). It reads the app-maintained cache only and never triggers a live Moz fetch: latest is the newest snapshot regardless of the window, and latest: null means the app hasn’t fetched DA for this project yet.

Prompt catalog

The project’s prompt configuration — what it monitors, what’s paused, and what the AI has suggested but nobody has reviewed yet (also available as the list_prompts MCP tool). This is configuration data, not performance: for per-prompt visibility scores use /visibility/prompts.
status selects the slice: tracked (default — actively monitored), untracked (paused), all (both), or suggested — the pending review queue of AI-proposed prompts (from research runs and the agent) that nobody has accepted or rejected yet, each with the reason it was proposed and its source. Accepted suggestions graduate into the tracked catalog and leave the queue. topicId restricts any slice to one topic; limit (default 50, max 200) + offset paginate with the standard pagination shape.

Prompt answers

Raw, per-response AI-answer data for one prompt (Profound-parity) — platform, response date, response text, brand/competitor mentions, and the source URLs the engine consulted (sources[] — pages used for generation, not inline citations), one entry per AI response (also available as the get_prompt_answers MCP tool).
limit is clamped to 1–50 (default 10); ?limit=0 clamps to 1, it never silently falls back to the default. pagination follows the standard {limit, offset, returnedCount, totalCount, hasMore, nextOffset} shape (see Pagination). Returns 404 if promptId doesn’t exist or belongs to a different project.

Generate a shareable report

Generate and publish a report, and get back its public share URL. Also available as the generate_report MCP tool (requires the write scope and an explicit confirm: true); this REST endpoint is the direct path.
POST requires the write scope and a plan that includes report sharing. GET /reports?limit=20&offset=0 (requires only the read scope) lists previously generated reports for the project, newest first — { reports: [{id, reportType, title, status, shareUrl, createdAt}], pagination }. It lists every currently-public report in the project (any project member’s, not just reports the calling key’s user created); drafts and unshared reports are excluded — a report saved with status: "draft" won’t appear until published, and one that’s later unshared drops off too.

Period comparison

GET /visibility, GET /visibility/topics, GET /share-of-voice, and GET /sentiment answer “vs last period” in one call — pass compare=previous_period or compare=previous_year:
Windows are whole UTC calendar days and never overlap: previous_period spans the same number of calendar days as the current window and ends the day before the current window’s first day; previous_year is the current window’s calendar days shifted back exactly 365 days. The comparison.dateRange in the response is exactly the range the previous-period query ran over. The response gains an additive comparison block — nothing else changes shape:
delta is current minus previous for every metric computable on both sides — a metric that can’t be compared is absent, never a fabricated 0. On /share-of-voice, competitor rows additionally carry previousSov / sovDelta inline (matched by entity display name — the share-of-voice entity identity); on /visibility/topics, each topic row carries comparison.previousMentionedPercentage / mentionedPercentageDelta. On the MCP get_visibility tool, compare works with group_by=summary and platform; prompt and location return invalid_argument rather than silently ignoring it.

Per-URL metrics rollup

One page’s three AI series in one call — AI-answer activity citing the URL, AI-referral sessions landing on it, and AI-crawler hits fetching it:
url is a full URL or a bare path (resolved against the project’s domain); a query string is kept, so /watch?v=abc and /watch?v=xyz are distinct pages. The citation series reports two distinct numbers — inlineCitations (the AI answer linked the URL in its text) and sourceUses (a model consulted the URL as a source), with daily sourceUses buckets. The two traffic series are scoped to the verified project domain the URL’s host resolves to and return available: false with a reason: traffic_not_connected when the LLM Analytics integration isn’t connected, or external_url for a host outside the project’s verified domains (external pages get cited too, so the citation series still answers). A citation-lookup failure likewise degrades just that series (citation_lookup_failed) rather than reading as a fake zero.

Query visibility, sources & sentiment

For visibility scores, share of voice, sources, sentiment, shopping visibility, AI ads, raw AI answers, AI traffic, and GA4/GSC data, connect the MCP server — it exposes read-only tools over the same data and handles auth for you. It’s the fastest path for read-heavy automation and works directly inside Claude, Cursor, and other assistants.

Send AI-bot traffic

To report request events from your own app or CDN (so crawlers like GPTBot and ClaudeBot show up in your dashboard), use the REST Ingest API. That endpoint uses a separate ingest key (sk_live_…) and a signed edge path — see its page for the full contract.

Rate limiting

Every API key is limited to 600 requests/minute across the REST surface (/api/mcp/*, /api/v1/*, and the Looker Studio connector — MCP tool calls have their own separate concurrency limits, not this budget). Two exceptions: /api/v1/chat and /api/v1/chat/stop don’t count against this budget and don’t emit the rate-limit headers below (/api/v1/chat has its own chat-specific limiter). Every other response carries rate-limit headers, whether it succeeds or errors:
RateLimit/RateLimit-Policy follow the IETF rate-limit header draft (r = remaining, t = seconds until reset, q = quota, w = window in seconds). X-RateLimit-* is kept alongside for clients that read the older convention; X-RateLimit-Reset is an absolute Unix-epoch second. The limiter fails open: if its backing store is briefly unavailable, requests are allowed (never refused for infrastructure reasons) and the rate-limit headers are omitted from those responses — don’t hard-require the headers in client code. Exceeding the limit returns 429 with a Retry-After header (seconds) and a rate_limited problem+json body — see the error reference.

Idempotency

The three mutating POST endpoints — POST /reports, POST /audits, and POST /sitemap/refresh — accept an Idempotency-Key header. Send the same key on a retry (e.g. after a timeout or a dropped connection) and the API replays the original response instead of repeating the side effect (generating a second report, starting a second audit run, or a second sitemap sync):
Notes:
  • Keys are scoped per API key and held for 24 hours.
  • Only a successful (2xx) response is stored — a failed attempt (4xx/5xx) is never replayed, so retrying after a real failure with the same key simply runs the request again.
  • Two concurrent requests with the same key never both execute: the second gets 409 (code: "idempotency_in_flight") with Retry-After: 5 while the first is still running. Wait, then retry with the same key — you’ll receive the first request’s stored response once it completes (or a fresh run if it failed). See the error reference.
  • A stored response body over 100KB is not cached — the request still runs normally, and the response carries X-Idempotent-Skipped: body-too-large instead of X-Idempotent-Replay.
  • Keys are not fingerprinted to the request body: reusing a key with a different body returns the stored response from the first request. Use a fresh key for each distinct operation.
  • No Idempotency-Key header — the request behaves exactly as before; this is fully opt-in.

Error handling

Full reference with remediation for every error code: API Error Reference. Every error body is application/problem+json: alongside the original error string (unchanged, for existing integrations), it now also carries type, title, code, message, and requestId. See the error reference for the full body shape and every code.

API key best practices

Never commit API keys to version control — use environment variables
Scope each key to the minimum it needs (read unless it must write)
Bind a key to a single project when it only ever touches that project
Use separate keys for dev and prod, and rotate them regularly
Revoke compromised keys immediately in Settings → Integrations

Need more?

Higher rate limits, custom endpoints, or a dedicated integration? Contact support@searchable.com.

Next steps

MCP Integration

Connect Claude, Cursor, and other assistants to your Searchable data.

REST Ingest API

Send AI-bot traffic events from any stack.