Get a Visibility Scan Preview
Read the full structured Visibility Scan Preview — brand identity, both visibility scores, LLM analysis, persona archetypes, category prompts.
Authentication: Required — partner accounts only (same partner gate as the trigger endpoint). Partner-originated scans are always private (isPublic is false), so reportUrl is the white-labeled partner URL, never a public /brand/preview/<slug> page. Fetching a preview is read-only, so it works even for accounts in read-only mode (only triggering a scan is refused).
Read the structured Visibility Scan Preview by uuid (returned from Trigger a Visibility Scan Preview) or by slug. Returns a curated projection of the scan — brand identity, both visibility scores, the LLM analysis (summary + observations + recommendations), persona archetypes, category prompts with per-platform mention estimates, and post ideas — surfaced as expanded JSON so an outreach-email template can pluck whichever fields it needs without us having to redesign the response shape per template change. Internal and operational columns (lead-capture details, hosting/preview linkage, source flags, the partner-team binding that white-labels a partner-originated report, and the resolved local-business listing context — Yelp / Google Business Profile — used to ground the scan) are deliberately omitted; the field guide below is the complete contract.
Poll this endpoint every 5–15 seconds after triggering until status is "complete" (or "failed").
Note: the deprecation warning (and Deprecation / Warning / X-Pendium-Warning headers) for a now-ignored isPublic: true is returned by the trigger (POST) response only — this read endpoint does not repeat it.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
uuid | string | One of uuid or slug | UUID returned from the trigger endpoint. Resolves any scan you own (or any public scan). |
slug | string | One of uuid or slug | Brand slug (e.g. acme). Resolves a public completed report, or — since this endpoint is partner-only — one of your own partner-originated reports by its historical slug. Each business gets its own slug — for directory-listing seed URLs (e.g. a Yelp business page) the slug is anchored per listing, not per domain, so two businesses on the same platform never collide. |
Authorization: non-admin callers can read scans they own or any public scan. Admin keys see anything.
Example
Response — status: complete
createdAt, completedAt, and updatedAt are ISO 8601 UTC timestamps. completedAt is null until status is "complete".
Shareable URLs
| Field | What it is |
|---|---|
reportUrl | The canonical visibility-scan report to send a prospect. Because this endpoint is partner-only and partner scans are private, this is the white-labeled partner URL — the team's verified custom domain when set, otherwise https://pendium.ai/partner/<slug>/visibility-scan-preview/<uuid>. |
previewUrl | The UUID-keyed report URL — available the moment the scan exists, before a slug resolves. |
agentSiteUrl | The brand's agent site preview (/agent-site/preview/<uuid>) — a rich, ready-to-launch site built from the same scan. null unless the scan produced one (local-business / Yelp / GBP scans). Send this when you want to show the prospect their site, not the report. Plain public URL — no partner white-label wrapping. |
Field guide
| Field | What it is | Use it for |
|---|---|---|
brand.name | LLM-inferred brand name from the seed URL | Subject lines, salutations |
brand.competitorNames | 5–10 real competing brands in this space | Competitor-comparison hooks |
scores.overallScore (0–100) | Overall AI visibility across category queries | The headline number for outreach |
scores.visibilityLevel | excellent/good/moderate/low/invisible | Plain-English score band |
scores.knowledgeScore (0–100) | How well AI agents know this brand by name | Direct-brand awareness signal |
scores.knowledgeLevel | strong/partial/thin/unknown | Plain-English knowledge band |
analysis.summary | 2–3 sentence narrative (the most interesting finding) | Email body lede |
analysis.observations | 3–6 specific findings | Bullet points |
analysis.recommendations | 3–5 prioritized content recommendations | The "what to do about it" pitch |
brandDirectSentiment.notableFacts | Things AI agents would surface about the brand | Personalization hooks |
brandDirectSentiment.riskFlags | Things AI agents might be getting wrong | "Here's what's wrong" angles |
metaAnalysis.scoreSlideHeadline | LLM-generated headline for this brand's score | Reusable outreach copy |
personas[] | Persona archetypes the brand's customers map to | Audience segmentation |
prompts[] | Real category prompts customers ask AI, with per-platform (ChatGPT/Claude/Gemini/AIOverviews) mention estimates | "We tested these prompts and you're invisible" angle |
postIdeas[] | LLM-generated content stubs (pitch, blog title, first sentence, hero image) | Content-strategy upsell |
reportUrl | Shareable link to the rendered report. Resolved server-side from the scan owner's account: agency-partner accounts get a white-labeled link — the team's verified custom domain (https://reports.youragency.com/visibility-scan-preview/<uuid>) when one is set, otherwise /partner/<slug>/… — rendering under the agency's branding; all other accounts get the Pendium-hosted /visibility-scan-preview/<uuid> link (or the canonical /brand/preview/<slug> once the scan is public). The caller doesn't choose this. | The CTA link in your outreach |
Response — status: pending or analyzing
The same shape, with brand/scores/analysis populated as the LLM streams in. failureMessage is null. Poll every 5–15 seconds.
Response — status: failed
Most failures happen because the seed URL doesn't represent a real, active business (parked domain, error page, login wall). Re-trigger with a different URL.
Response — not found / forbidden
If the UUID doesn't exist, or it's a private scan owned by another user, you'll get a 404: