the BotScope
API.
Pull your organisation’s LLM-visibility data — projects, scans, layer scores, share of voice and competitor comparisons — over plain HTTPS and JSON. Authenticate with an org-scoped API key.
- Base URL: https://api.botscope.ai/api/v1
- Authenticate with a Bearer API key created in Settings → Developers.
- Every response is JSON, wrapped in { "data": ... }.
- The API is read-only — it never changes your data or spends credits.
- Included on all paid plans. Rate limit: 120 requests/minute per key.
- Machine-readable spec: openapi.json (OpenAPI 3.1).
This reference describes v1. We’ll add endpoints over time; existing responses won’t change shape without a new version.
SECT.01 Authentication.
Create a key in the dashboard under Settings → Developers → Create
key. The full key (prefixed bsk_) is shown once — store it safely; you can’t retrieve it again,
only revoke it. Send it as a Bearer token on every request:
curl -H "Authorization: Bearer bsk_your_key_here" \
https://api.botscope.ai/api/v1/projects A key only reads the organisation it was created in. Treat it like a password — anyone with the key can read your data. Revoking a key from the same page takes effect immediately.
SECT.02 Quickstart.
export BSK="bsk_your_key_here"
export BASE="https://api.botscope.ai/api/v1"
# 1. List your projects
curl -s -H "Authorization: Bearer $BSK" "$BASE/projects"
# 2. Read a project's visibility overview
PID="<a project id from step 1>"
curl -s -H "Authorization: Bearer $BSK" "$BASE/projects/$PID/visibility" SECT.03 Endpoints.
| Method | Path | Description |
|---|---|---|
| GET | /projects | List all projects in your organisation |
| GET | /projects/{id} | A single project’s configuration |
| GET | /projects/{id}/scans | Paginated scan history (newest first) |
| GET | /projects/{id}/visibility | Overall + L1–L4 scores, trends, citations, share of voice |
| GET | /projects/{id}/share-of-voice | Own brand vs competitor mention share |
| GET | /projects/{id}/competitors | Own brand + tracked competitors by median mentions |
| GET | /projects/{id}/categories | Per-category share of voice, providers, trend, top competitors |
| GET | /projects/{id}/responses | Paginated index of raw LLM responses |
| GET | /projects/{id}/responses/{responseId} | One response with brand detections + citations |
| GET | /projects/{id}/ads | How often sponsored ads appear on ChatGPT, with the sample size |
| GET | /projects/{id}/ads/trend | Ad coverage per scan, oldest first |
| GET | /projects/{id}/ads/advertisers | Who is advertising against your prompts, with ad share of voice |
| GET | /projects/{id}/ads/prompts | Which prompts trigger ads, and the advertisers on each |
| GET | /projects/{id}/ads/creatives | Deduplicated ad creatives with first/last seen |
| GET | /projects/{id}/ads/competitor-overlap | Prompts where a tracked competitor is advertising |
| GET | /projects/{id}/products/catalog | The tracked-product catalog (own and competitor models) |
| GET | /projects/{id}/products/mentions | How often tracked models are mentioned in answers, with the sample size |
| GET | /projects/{id}/products/mentions/leaderboard | Models ranked by mentions, with per-model sentiment |
| GET | /projects/{id}/products/mentions/prompts | Which models each prompt recommends |
| GET | /projects/{id}/products/mentions/trend | Product mentions per scan, oldest first |
| GET | /projects/{id}/products/shopping | How often ChatGPT shows its shopping carousel, with the sample size |
| GET | /projects/{id}/products/shopping/trend | Carousel appearance per scan |
| GET | /projects/{id}/products/shopping/products | Carousel products with latest price, rating and merchant link |
| GET | /projects/{id}/products/shopping/brand-share | Carousel placements grouped by product brand |
| GET | /projects/{id}/products/shopping/merchants | Which merchants the carousel sends buyers to |
| GET | /projects/{id}/products/shopping/prompts | Which prompts trigger a shopping carousel |
| GET | /projects/{id}/products/shopping/price-history/{productId} | Displayed price per scan and country for one product |
The ads endpoints cover sponsored placements observed beneath
ChatGPT answers — there is no public ad library for ChatGPT, so this is
built purely from your own scans. They take no provider parameter,
because ads only exist on the scraped ChatGPT interface. Every ad response
carries its sampleSize alongside any rate: ad serving is
contextual and varies between identical prompts, so a coverage figure without
its denominator will mislead. A coverageRate of null means nothing was measured — which is not the same as no ads.
Example response — visibility (numbers are medians across the resolved scans, matching the dashboard):
{
"data": {
"projectId": "1d7367ae-...",
"overall": 34.6,
"overallTrend": 2.1,
"l1": { "layer": "L1", "name": "Entity Recognition", "score": 61.2, "trend": 1.0 },
"l3": { "layer": "L3", "name": "Category Inclusion", "score": 4.93, "trend": 0.2 },
"totalCitations": 59,
"lastScanAt": "2026-05-10T11:36:01.588Z",
"shareOfVoice": { "ownBrandShare": 0.27, "competitors": [] },
"comparedTo": { "kind": "previous_scan", "overall": 32.5 }
}
} SECT.04 Parameters.
Most read endpoints accept a selector for which data to aggregate. With none, they use the latest scan.
| Param | Description |
|---|---|
provider | Filter to one provider, e.g. openai, google_ai_overview. |
scanId | Pin to a specific scan (from the scans list). Takes precedence over a date range. |
from / to | ISO-8601 date window. Both required together. Aggregated across scans in range. |
layer | Responses only — filter to a visibility layer: L1, L2, L3, L4. |
limit | Page size for scans/responses, 1–200 (default 50). Out-of-range values are clamped. |
before | Keyset cursor — pass the previous response’s pagination.nextBefore. |
# One provider
curl -s -H "Authorization: Bearer $BSK" \
"$BASE/projects/$PID/visibility?provider=google_ai_overview"
# A date window (both from & to required)
curl -s -H "Authorization: Bearer $BSK" \
"$BASE/projects/$PID/visibility?from=2026-04-01T00:00:00Z&to=2026-05-31T23:59:59Z"
# A specific scan
curl -s -H "Authorization: Bearer $BSK" \
"$BASE/projects/$PID/visibility?scanId=<scan-id>" SECT.05 Pagination.
List endpoints return a pagination object. When nextBefore is non-null, pass it as before for the next (older) page; null means you’ve reached the end.
{ "data": [ ... ], "pagination": { "limit": 20, "nextBefore": "2026-05-10T09:53:43.562Z" } } SECT.06 Rate limits.
Each key is limited to 120 requests per minute. Every
response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix
epoch second). Exceeding it returns 429 with a Retry-After header.
SECT.07 Errors.
Errors share one shape:
{ "error": { "code": "not_found", "message": "Project not found", "details": null } } | Status | code | When |
|---|---|---|
| 401 | unauthorized | Missing or malformed Authorization header |
| 401 | invalid_api_key | Unknown, revoked, or expired key |
| 403 | feature_not_available | Your plan doesn’t include API access |
| 404 | not_found | Resource doesn’t exist or belongs to another org |
| 422 | validation_error | Invalid query/path parameter (see details) |
| 429 | rate_limited | Per-key rate limit exceeded |
For privacy, a resource in another organisation returns 404, not 403 — the API never discloses whether something you can’t see exists.
SECT.08 MCP server.
Prefer to use BotScope from an AI assistant? We host a remote MCP server that
exposes these endpoints as tools, so Claude and other MCP clients can read
your data directly. Authenticate with the same bsk_ key as a
Bearer header.
URL: https://mcp.botscope.ai/mcp (Streamable HTTP) · …/sse (legacy).
Twenty-six read tools: list_projects, get_project, list_scans, get_visibility, get_share_of_voice, get_competitors, get_categories, list_responses, get_response; ads — get_ad_coverage, get_ad_trend, get_ad_advertisers, get_ad_prompts, get_ad_creatives, get_ad_competitor_overlap; product tracking — get_product_catalog, get_product_mentions, get_product_mention_leaderboard, get_product_mention_prompts, get_product_mention_trend, get_shopping_coverage, get_shopping_trend, get_shopping_products, get_shopping_merchants, get_shopping_prompts and get_shopping_price_history.
Claude Code (one line; replace with a real key):
claude mcp add --transport http botscope https://mcp.botscope.ai/mcp --header "Authorization: Bearer bsk_your_key_here" Cursor / Windsurf / generic mcp.json:
{
"mcpServers": {
"botscope": {
"url": "https://mcp.botscope.ai/mcp",
"headers": { "Authorization": "Bearer bsk_your_key_here" }
}
}
} Questions or feedback? Email [email protected].