Available Endpoints
This page lists all endpoints that support API key authentication. Most endpoints use your property API key; everything under /api/v1/ — report generation, AIVPS, PQS, and coverage — uses your organization API key. For interactive documentation and testing, visit the API Reference.
The API Reference shows all endpoints, but only the ones listed below support external API key access. Other endpoints are for internal application use only.
AI Placement Value Score (AIVPS)
Programmatically score one or more publisher domains against the AI Placement Value Score (AIVPS) layers — organic authority, AI citation accessibility, and AI training influence. Use this to rank placement opportunities, monitor AI-era authority of partner and competitor domains, and feed SEO/PR workflows that already track traditional authority metrics.
These endpoints use an organization-level API key, not your property API key. The two are not interchangeable. Generate a key under Organization Settings → API Key. A single organization key authorizes AIVPS scoring across every domain your organization queries.
Score Publishers
Compute the full AIVPS for one or more publisher domains. If the domain is unknown to Spyglasses, a publisher record is auto-created and enriched asynchronously in the background — the first call may return "confidence": "estimated" while enrichment finishes.
Headers:
x-api-key: Your organization's AIVPS API key (required)Content-Type: application/json
Body (primary use case — score a batch against a brand):
domain(string) ordomains(array, 1–25) — supply exactly one. Domains are normalized (protocol/www/trailing slash stripped).brandContext.propertyId(optional) — must reference a Property owned by the authenticated organization. Enables category-relevance scoring and AI training influence uplift. Omit if you don't have brand context.baseline(optional) — enables Bring-Your-Own-Baseline mode. See below.
Response:
If any individual domain fails (for example, a missing baseline value in BYOB mode), that domain appears in errors[] and the rest of the batch still succeeds.
Score Publishers with Bring-Your-Own-Baseline (BYOB)
If your team already tracks organic authority with Ahrefs DR, Moz DA, SEMrush AS, Majestic TF, or a custom score, you can supply that baseline and have Spyglasses apply only the AI layers on top. The response's aipvsByob.compositeScore is computed as normalizedBaseline × aiImpactMultiplier.
Body:
baseline.source— one ofahrefs_dr,moz_da,semrush_as,majestic_tf,dataforseo,custom.baseline.values— map of domain → baseline value. Must contain an entry for every domain you pass in.baseline.customMin/customMax— required whensourceiscustom; values are linearly rescaled to 0–100.
Response (adds an aipvsByob block per result; standard aipvs is still included for reference):
Get AI Impact Multiplier
Returns just the raw AI impact multiplier (0.40–1.00) plus the ACA and ATI layers for one or more domains. Use this when you want to combine Spyglasses' AI layers with a baseline you compute yourself at call time — the most portable form of the AIVPS signal.
Headers:
x-api-key: Your organization's AIVPS API key (required)Content-Type: application/json
Body:
Response:
AI Placement Quality Score (PQS)
Programmatically score placements against the AI Placement Quality Score factors — document position, chunk containment, placement type, editorial control, link attribute, and sentiment multiplier. When a publisher domain is supplied, the response also includes the publisher's AIPVS and a combined Total Placement Value (AIPVS × PQS / 100).
The PQS API supports both scoring modes:
- Prospective (synchronous) — score a hypothetical placement from user-supplied inputs. Returns the full score in the POST response.
- Retrospective (async, polling) — score an existing placement at a live URL. The POST creates a placement and enqueues the background job; the client polls a GET endpoint for the result.
All PQS endpoints use an organization-level API key, the same key used for the AIVPS endpoints above. Generate one under Organization Settings → API Key.
Score a Prospective Placement
Compute the PQS for a hypothetical placement given its scoring inputs. Use this to rank placement offers, run "what-if" scenarios before negotiating, or integrate PQS into your own media planning tools.
Headers:
x-api-key: Your organization's API key (required)Content-Type: application/json
Body:
placementType(required) — one ofdedicated_article,roundup_top,roundup_top_third,roundup_middle_third,roundup_bottom_third,passing_mention,sidebar_widget_biobox,quote_onlyeditorialControl(required) — one offull_authorship,collaborative,quoted,mentioned,unpredictablelinkAttribute(required) — one ofdofollow,nofollow,sponsored,ugc,no_linkassumedPosition(optional, default0.15) — the fraction of the document (0.0–1.0) where you expect the brand mention to land.0.05= first 10%,0.5= middle,0.95= footer.publisherDomain(optional) — when supplied, the publisher's AIPVS is computed and combined with the PQS for a Total Placement Value.brandContext.propertyId(optional) — must reference a Property owned by the authenticated organization. Narrows AIPVS category relevance and training influence uplift.
Response:
Notes:
pqs.subScores.chunkis always0.7for prospective placements. Actual chunk containment can only be computed from real content, so the API treats prospective placements as "partial" containment by default. Retrospective scoring (via the web UI) computes the real value.pqs.sentimentMultiplieris always1.0for prospective placements. Sentiment analysis requires real content around the mention.aipvsandtotalPlacementValuearenullwhenpublisherDomainis omitted or the AIPVS lookup fails.pqs.effectiveWeightsmatchesdefaultWeightsin prospective mode. Retrospective mode (web UI only) redistributes the editorial weight proportionally across the other four signals.
Example — run a lift preview: Fire several requests with the same publisher and editorial control but different placement positions / link attributes to quantify how much better terms would be worth. This is exactly what the "What if you negotiated better terms?" panel in the web UI does.
Score a Retrospective Placement (asynchronous)
Score an existing placement at a live URL. Spyglasses fetches the page, locates the brand mention (using the property's name and aliases), auto-detects the link attribute, classifies placement type and sentiment with an AI model, and computes the PQS. The pipeline typically takes 15–30 seconds and runs as a background job, so this endpoint returns a placement ID immediately — you poll for the result.
Headers:
x-api-key: Your organization's API key (required)Content-Type: application/json
Body:
url(required) — the live URL to score. Must be publicly accessible.propertyId(required) — the Property whose brand name and aliases should be used to locate the mention in the content. Must belong to the authenticated organization.title(optional) — a human-readable label for the placement. Auto-extracted from the page's<title>/og:title/h1if omitted.placementType/editorialControl/linkAttribute(optional) — all three are auto-detected from the page during scoring. Only supply them if you want to override the auto-detection.
Response (HTTP 202):
The returned id is the placement's unique identifier. Use it with the polling endpoint below.
Poll a Placement's Status and Result
Fetch the current state of a placement created via the retrospective endpoint (or any placement owned by the authenticated organization). Poll at roughly 3-second intervals until status is completed or failed.
Headers:
x-api-key: Your organization's API key (required)
Response while scoring is still in progress (HTTP 200):
statusis eitherpending(queued, not yet running) orrunning(actively being scored).- Keep polling until
statuschanges tocompletedorfailed.
Response when scoring has completed (HTTP 200):
Notes:
- In retrospective mode, the editorial weight is redistributed proportionally across the other four signals (
effectiveWeights.editorial= 0) because the editorial decision has already been made. ThedefaultWeightsfield shows the original distribution for reference. pqs.inputsreflects the auto-detected values after scoring, not necessarily what you passed in the create request. If the scorer detected a different link attribute or placement type, those take precedence.pqs.brandMentionshows which alias matched and where it was located in the tokenized content.keyMessagePullThrough.matchesis always one entry per configured key message (even below-threshold "closest match" entries); thematchedflag indicates whether each crossed the threshold.totalPlacementValueisnullwhen the publisher couldn't be looked up or hasn't been enriched yet.
Response when scoring has failed (HTTP 200):
Common failure modes:
- "No brand mention found in content" — the scorer couldn't locate any occurrence of the Property's name or aliases in the page. Check the URL is correct and add the exact form of the brand name used in the article to the Property's aliases.
- "The URL returned 404 — check that it's correct and publicly accessible." — the page no longer exists or isn't publicly available.
- "The URL returned 403 — the site is blocking our crawler." — the site is blocking the Spyglasses fetcher via WAF or bot protection. Try a different page on the same site.
- "Could not extract readable content from the page." — the page is JavaScript-rendered, paywalled, or has an unusual layout that prevents content extraction.
Polling example (JavaScript):
AI Visibility Reports
Generate an AI Visibility Report — how a brand appears across ChatGPT, Gemini, Claude, Perplexity, and Google AI Overviews — for one property, or for a list of prospects at once. Use this to run a report from a CRM trigger, a pitch workflow, or a nightly job, instead of clicking through the app.
Reports are generated in the background and take a few minutes. Every endpoint here returns immediately and hands you an id to poll.
These endpoints use an organization-level API key, not your property API key. Generate one under Organization Settings → API Key. One organization key works across every property in the organization.
Credits, and why the API is stricter than the app
Every report costs credits. Before anything starts, the full cost must already be sitting in your organization's credit balance:
- The API never bills overage and never triggers an automatic top-up. An integration that runs unattended must not be able to run up a bill.
- If the balance is short, the call returns
402and nothing is created or charged. - In the app, a subscriber can acknowledge overage and continue. There is no equivalent on the API — buy credits in the app and retry.
- Organizations on contractual (enterprise) billing are not balance-checked at all. Their usage is recorded and invoiced under their agreement rather than drawn from a credit balance, so these endpoints do not return
402for them.
A 402 looks like this:
Generate a Report
Start a report for one property you already track.
Headers:
x-api-key: Your organization's API key (required)Content-Type: application/json
Body:
propertyId(required) — the property to report on. Must belong to the authenticated organization.locationCity/locationRegion/locationCountry(optional) — location context for this run. Each falls back to the property's own default when omitted.notifyEmail(optional) — who to email when the report finishes.
Response (HTTP 202):
publicUrl is the shareable report link. It works as soon as generation finishes — no login required — so you can put it straight into a CRM field or a pitch email.
If a report is already in flight (HTTP 200): when the property already has a report that is running, or finished but not yet purchased, that report is returned instead and nothing new is started or billed. The body is the same shape; the status code is 200 rather than 202. This is the same rule the app applies, and it means a retrying integration cannot double-bill.
Errors:
| Status | error | Meaning |
|---|---|---|
400 | validation detail | Missing or malformed propertyId |
401 | API key is required / Invalid API key | No x-api-key header, or it matches no organization |
402 | INSUFFICIENT_CREDITS | The full cost is not available. No overage on the API |
404 | Property not found | No such property in your organization. A property owned by someone else is answered 404, not 403, so the endpoint cannot be used to probe which ids exist |
500 | Failed to create AI report | Server error; safe to retry |
Poll a Report
Fetch a report's current status. Generation takes a few minutes — poll every 30 seconds or so rather than continuously.
Headers:
x-api-key: Your organization's API key (required)
Response (HTTP 200):
pending/running— still generating; keep polling.complete/partial— readable atpublicUrl.failed— it will not finish.
Errors:
| Status | error | Meaning |
|---|---|---|
401 | API key is required / Invalid API key | No x-api-key header, or it matches no organization |
404 | AI report not found | No such report in your organization. A report owned by someone else is answered 404, the same as one that does not exist |
Generate Reports for a List of Prospects
Start one report per row. Each row creates a prospect property in your organization and runs its report. This is the API form of the app's bulk import, and carries the same limits: a single batch accepts at most 20 rows, and rows whose domain is unparseable or already tracked in the organization are dropped.
Bulk generation is available on active Agency plans, the same gate as the in-app bulk import. Other plans get 403.
Headers:
x-api-key: Your organization's API key (required)Content-Type: application/json
Body:
rows(required, at least 1) — one entry per prospect.valueis a bare domain (tracked as a brand) or a product URL with a path (tracked as that product).rows[].locationCity/locationRegion/locationCountry(optional) — location context for that row's report.notifyEmail(optional) — who to email when the batch finishes.
The projected cost is rows × the report credit cost, and the whole of it must be available before anything starts. A short balance returns 402 with a projectedCredits field alongside the usual requiredCredits and availableBalance, and no property or report is created.
Response (HTTP 202):
total is the number of rows accepted. rejected lists every row that was dropped, with its position in the array you sent, why it was dropped (bad_domain, or duplicate when the organization already tracks that domain), and a message you can show a user. rejected is [] when everything was accepted.
Errors:
| Status | error | Meaning |
|---|---|---|
400 | NO_VALID_ROWS / IMPORT_LIMIT_EXCEEDED | Nothing survived validation, or more rows than a single import allows |
401 | API key is required / Invalid API key | No x-api-key header, or it matches no organization |
402 | INSUFFICIENT_CREDITS | The full projected cost is not available. No overage on the API |
403 | plan message | Bulk generation is not available on this organization's plan |
500 | Failed to start the batch | Server error; safe to retry |
Poll a Batch
Track a batch's progress and collect each row's report link as it becomes available.
Headers:
x-api-key: Your organization's API key (required)
Response (HTTP 200):
Entries appear in reports[] as the background job works through the rows, so a row with null fields early on will fill in on a later poll. status on the batch stays running until every row has finished or failed.
Errors:
| Status | error | Meaning |
|---|---|---|
401 | API key is required / Invalid API key | No x-api-key header, or it matches no organization |
404 | Batch not found | No such batch in your organization. A batch owned by someone else is answered 404, the same as one that does not exist |
Coverage Groups
A coverage group is a named list of earned-media placement URLs for one property — a PR team's coverage for a client. These endpoints let an automation feed placements into a group as they are won, instead of pasting them into the app in batches.
For a step-by-step walkthrough of wiring this to Zapier, n8n, or a social-listening tool, see Automating Coverage Tracking.
These endpoints use an organization-level API key, not your property API key. Generate one under Organization Settings → API Key. One organization key works across every client property in the organization.
List Coverage Groups
Return a property's coverage groups with their item counts. Call this once when setting up an automation to find the groupId you'll feed.
Headers:
x-api-key: Your organization's API key (required)
Response:
The property must belong to the authenticated organization, or the call returns 403.
Add Placement URLs to a Coverage Group
The automation entry point. Append one URL or a batch of up to 1000.
Headers:
x-api-key: Your organization's API key (required)Content-Type: application/json
Body (single URL — the usual shape for a real-time trigger):
Body (batch — for a nightly export or a backfill):
url(string) orurls(array, 1–1000) — supply exactly one.score(boolean, defaulttrue) — whether to create and score a Placement for each new URL. See "Controlling scoring cost" below.
Response:
added— item rows created.duplicates— submitted URLs the group already had. Safe and free: re-posting the same URL costs nothing.invalid— rejected lines, each with avalueand areason.placementsLinked— URLs that already had a scored placement for this property and were linked immediately, at no cost.scoringQueued— whether placement scoring was dispatched for the new items.
Notes:
- URLs are matched on a normalized form, so
www, trailing slashes, tracking parameters, and fragments all collapse to the same item. This is what makes the endpoint safe to call from a trigger that may fire more than once for the same story. - YouTube links are expanded to their equivalent
watch,youtu.be, andshortsforms automatically, because AI platforms cite the same video under any of them. - A URL that already has a placement for this property is linked rather than rescored.
Controlling scoring cost
By default each newly added URL gets a Placement created and scored — the page is fetched, the brand mention located, the placement type and sentiment classified, and the PQS computed. That is the same work the app does when you paste URLs in, and it is the expensive step.
Pass score: false to skip it. Classification and project-goal backfill still run, so citations still attribute correctly; you just don't get a PQS until you run Score placements on the group in the app, which is idempotent and only scores what's missing. Use this when bulk-loading a large historical archive where per-placement quality scores aren't the point.
Read a Coverage Group
Return a group with a page of its items, each carrying its publisher, classification, and linked placement. Use this to read scores back into your workflow after ingestion.
Headers:
x-api-key: Your organization's API key (required)
Query Parameters:
limit(optional, default100, max500) — items per pageoffset(optional, default0)
Response:
Items are newest-first. placement is null until the scoring job creates one, then carries status pending → running → completed, with pqsScore populated on completion. Poll this endpoint if your workflow needs the score.
Get Citations Earned by a Coverage Group
The read side of the loop: which of the group's URLs are actually being cited by AI assistants, in which answers, on which platforms. Scoped to the property's own tracked prompts and reports.
Headers:
x-api-key: Your organization's API key (required)
Query Parameters:
platform(optional) — filter to a single AI platformcitationType(optional) — one ofcited_inline,evaluated_source,search_result,unclassified,allurl(optional) — filter to a single placement URLstartDate/endDate(optional) —YYYY-MM-DD, inclusivelimit(optional, max1000) /offset(optional)
The response contains a funnel, a cited-vs-uncited comparison across the group's URLs, and per-citation hits with the prompt, platform, and the surrounding answer text.
This is the endpoint to poll for a "notify me when a placement gets cited" automation — filter by startDate to the period since your last run.
Property Information
Get Property Details
Retrieve information about your property using your API key.
Headers:
x-api-key: Your API key (required)
Response:
AI Visibility Rankings
Get AI Visibility Rankings
Retrieve prioritized grounding search opportunities from your most recent AI report.
Headers:
x-api-key: Your API key (required)
Parameters:
propertyId: Your property ID (from/api/me)
Historical Metrics
Get Brand Consistency History
Retrieve brand consistency score trends over time.
Headers:
x-api-key: Your API key (required)
Parameters:
id: Your property ID
Get Discovery Metrics History
Retrieve discovery query performance trends over time.
Headers:
x-api-key: Your API key (required)
Parameters:
id: Your property ID
Get Grounding Search Metrics History
Retrieve grounding search ranking trends over time.
Headers:
x-api-key: Your API key (required)
Parameters:
id: Your property ID
Query Parameters:
onlyGaps: Set to"true"to filter to gap opportunities only
Get Competitor Share of Voice
Retrieve share of voice data for competitors from your most recent AI report.
Headers:
x-api-key: Your API key (required)
Parameters:
id: Your property ID
Get AI Visibility Rankings (Alternative)
Alternative endpoint for AI visibility rankings data.
Headers:
x-api-key: Your API key (required)
Parameters:
id: Your property ID
AI Traffic Analytics
Get AI Timeline with Trends
Retrieve AI traffic timeline data with comparison to previous period.
Headers:
x-api-key: Your API key (required)Content-Type: application/json
Body:
Get AI Conversion Metrics
Retrieve AI conversion metrics showing bot visits vs human visits.
Headers:
x-api-key: Your API key (required)Content-Type: application/json
Body:
Get AI Traffic Summary
Retrieve AI traffic summary with breakdowns by category and referrer.
Get AI Traffic Timeline
Retrieve AI traffic timeline data for charts.
Get AI Traffic Timeline by Intent
Retrieve AI traffic timeline segmented by page intent.
Get AI Overview Visits
Retrieve visits from Google AI Overviews, Featured Snippets, and People Also Ask.
Get Bot Types
Retrieve list of AI visitor bot types for filtering.
Agent Analytics
Get Agent Data by Category
Retrieve analytics data for agents grouped by category.
Headers:
x-api-key: Your API key (required)Content-Type: application/json
Body:
Get Agent Data by Subcategory
Retrieve analytics data for agents grouped by subcategory.
Get Agent Data by Bot Type
Retrieve analytics data for agents grouped by bot type.
Get Agent Data by Location
Retrieve analytics data for agents grouped by location.
Get Agent Data by Pages
Retrieve analytics data for agents grouped by page path.
Get Live Agent Data
Retrieve real-time agent data for a property.
Get Blocked Requests Statistics
Retrieve statistics about blocked vs allowed requests.
Recrawl Analytics
Get Site Recrawl Summary
Retrieve site-wide recrawl frequency statistics.
Headers:
x-api-key: Your API key (required)Content-Type: application/json
Body:
Get Page Recrawl Frequency
Retrieve recrawl frequency statistics for each page.
Get Bot Recrawl Frequency
Retrieve recrawl frequency statistics for each crawler bot.
Get Bot Page Recrawl Frequency
Retrieve recrawl frequency for pages crawled by a specific bot.
Internal-Only Endpoints
The API Reference shows additional endpoints that are for internal application use only. These endpoints use session-based authentication and are not supported for external API access.
If you need access to data not available through the endpoints listed above, please contact us to discuss your requirements.