Skip to main content
GET
Get scan status / result

Authorizations

Authorization
string
header
required

Partner API key as a Bearer token: Authorization: Bearer gsk_live_.... Live keys (gsk_live_) run real scans; test keys (gsk_test_) run request validation then return deterministic sandbox mocks (sandbox: true, nothing persisted, no rate-limit consumption). Keys are issued per partner and are revokable.

Path Parameters

id
string<uuid>
required

The scan_id returned by the create endpoint.

Response

A scan payload — status "completed" (final), "preliminary" (mid-run snapshot; keep polling until completed) or "failed" (terminal, with a required error block; the SAME payload the scan.failed webhook carries). A 200 does not by itself mean the scan succeeded — check status, or the presence of error, before reading any score field. Test keys always return a completed mock echoing the requested id.

The single scan result contract. Returned by POST (sync completion), GET status polls, and inside both webhook events — partners always see this one shape regardless of entry point. Sandbox (test-key) responses add a top-level sandbox: true extension field.

scan_id
string<uuid>
required

Stable scan identifier.

tier
enum<string>
required

Effective tier of the scan. A request for both packages reports as "full" (the run includes the Full-tier surfaces). See the request tier field for how this can differ from the tier you requested (EXPX-1582 billing-follows-what-ran).

Available options:
basic,
full
status
string
required

Scan lifecycle status. "completed" = final result. "preliminary" = mid-run snapshot: geo_score/band are computed live from the observations collected so far (best-effort, may change). "failed" = terminal: no result will be produced (the scan is not billed and does not consume your monthly allowance) — the body is a PartnerScanFailedOutput and its required error block carries the machine-readable reason, on the status endpoint and the scan.failed webhook alike. Other values (e.g. "processing") mirror internal lead state.

Examples:

"completed"

"preliminary"

"processing"

"failed"

company
object
required
generated_at
string<date-time> | null
required

When the final result was assembled. Null while the scan is in flight.

llms_used
string[]
required

Provider IDs dispatched for this scan. NOTE: these are provider IDs, not request slugs — the request slug "chatgpt" appears here as "openai"; all other slugs are identical to their provider ID.

prompts_count
integer
required

Number of prompts run per provider.

geo_score
number | null
required

Overall GEO visibility score (0-100). On a preliminary payload this is a live mid-run computation and may change in the final result. Null until at least one provider has reported.

band
string | null
required

Qualitative band derived from geo_score (e.g. "emerging").

competitors
object[]
required

At most 10 eligible competitor groups on newly generated results, strongest first. Eligibility, grouping and priority scores use the full assessed pool and all observation denominators before this presentation limit. Fewer than 10 may qualify; all accepted member scopes within each returned group are retained. competitor_quality counts describe the full assessment, not this list length. Previously saved deliveries remain unchanged and may contain more than 10 groups.

coverage
object
required

Per-scan provider request/response coverage — how much of what was requested actually reported a real (non-errored) observation. Present on BOTH preliminary and final output. While status is "preliminary", providers_missing reads as "still pending"; once status is "completed" it reads as "failed" (the run is done, so anything still missing never arrived). All values are provider IDs (see llms_used), not request slugs.

revision
integer
required

Delivery revision identifying the payload generation. 1 = preliminary (or a final with no prior preliminary delivery); 2 = final after a preliminary was already delivered. Deduplicate deliveries on (scan_id, revision) — the same scan_id can legitimately arrive twice with different revisions.

score_confidence
enum<string>
required

Provider coverage behind geo_score; competitor_quality separately reports identity and relevance. The scan achieved. "high" — the scan covered the full set of surfaces the score is calibrated on. "reduced" — coverage was partial; treat the score as indicative and consider re-scanning. "low" — significant coverage gaps; the score should not be relied on. See coverage.providers_missing for exactly which requested surfaces did not report. On a preliminary payload this reflects what has reported so far and can only improve in the final revision.

Available options:
high,
reduced,
low
meta
object
required
competitor_quality
object

Business identity and competitor eligibility, separate from provider coverage. New-version unavailable or unresolved assessments never return unassessed competitors. Legacy results preserve historical lists and are explicitly unassessed. Preliminary results may have no assessment yet.