Docs/API Reference/POST /v1/snapshot

POST /v1/snapshot

Refine coarse UI geometry (raw_elements) into a ranked, compact element list (elements) for agent decision making.

Overview

This is the API used by the SDK when use_api=true. The SDK/extension collects raw_elements locally, then the server produces elements with ranking + visual cues.

Note on screenshots: this endpoint does not return screenshots. If you request screenshot via the SDK, the screenshot is captured locally by the extension and merged into the SDK’s returned Snapshot object.

Timeouts (important for large pages)

Refinement can take longer on large/heavy pages. If you see client-side timeouts while calling the Gateway:

Example (SDK):

from predicate import snapshot, SnapshotOptions

snap = snapshot(
    browser,
    SnapshotOptions(use_api=True, gateway_timeout_s=60),
)

Prefer the SDK: If you're integrating an agent, use the SDK Quick Start to get action execution + consistent snapshots automatically.

Request Format

curl -X POST https://api.sentienceapi.com/v1/snapshot \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "viewport": { "width": 1920, "height": 1080 },
    "raw_elements": [
      {
        "id": 0,
        "tag": "button",
        "rect": { "x": 100, "y": 200, "width": 150, "height": 40 },
        "styles": { "z_index": "10", "cursor": "pointer" },
        "attributes": { "role": "button", "aria_label": "Sign in" },
        "text": "Sign in",
        "in_viewport": true,
        "is_occluded": false
      }
    ],
    "goal": "Click the Sign in button",
    "options": {
      "limit": 50,
      "filter": { "min_area": 100, "allowed_roles": ["button", "textbox"] }
    },
    "client_metrics": {
      "ready_state": "complete",
      "quiet_ms": 1200,
      "node_count": 2400
    },
    "client_diagnostics": {
      "captcha": {
        "detected": false,
        "confidence": 0.0,
        "evidence": { "text_hits": [], "selector_hits": [], "iframe_src_hits": [], "url_hits": [] }
      }
    }
  }'

Request Parameters

ParameterTypeRequiredDescription
urlstringYesThe URL of the webpage being analyzed
viewportobjectNoViewport dimensions with width and height. If omitted, the server derives it from element bounds.
raw_elementsarrayYesArray of raw element data from browser
goalstringNoOptional goal for intent-aware ranking / ML reranking (when enabled).
optionsobjectNoFiltering and limiting options (limit, filter). limit defaults to 50 and is capped server-side (default cap: 100).

Raw Element Shape (SDK / Extension)

raw_elements is emitted by the Predicate extension. The server is tolerant of extra fields; the schema below shows the common fields used for processing.

{
  "id": 12,
  "tag": "input",
  "rect": { "x": 10, "y": 120, "width": 300, "height": 36 },
  "styles": { "z_index": "0", "cursor": "text" },
  "attributes": {
    "role": "textbox",
    "type_": "email",
    "aria_label": "Email",
    "href": null,
    "nearby_text": "Work email",
    "name": "Email",
    "input_type": "email",
    "value": null,
    "value_redacted": "true",
    "checked": null,
    "disabled": null,
    "aria_checked": null,
    "aria_disabled": null,
    "aria_expanded": null
  },
  "text": "",
  "in_viewport": true,
  "is_occluded": false,
  "iframe_content": [],
  "scroll_y": 0,
  "center_x": 160,
  "center_y": 138,
  "doc_y": 138,
  "group_key": "x0-w3-h0"
}

Response Format

{
  "status": "success",
  "timestamp": "2026-01-23T20:11:02.123Z",
  "url": "https://example.com",
  "viewport": { "width": 1920, "height": 1080 },
  "credits_used": 1,
  "credits_remaining": 123,
  "elements": [
    {
      "id": 0,
      "role": "button",
      "text": "Sign in",
      "importance": 85,
      "visual_cues": { "is_primary": true, "is_clickable": true },
      "bbox": { "x": 100, "y": 200, "width": 150, "height": 40 },
      "in_viewport": true,
      "is_occluded": false,
      "z_index": 10,
      "href": null,
      "nearby_text": null,
      "fused_rank_index": 0,
      "heuristic_index": 3,
      "ml_probability": 0.94,
      "ml_score": 2.1,
      "center_x": 175,
      "center_y": 220,
      "doc_y": 220,
      "group_key": "x0-w3-h0",
      "group_index": 0,
      "in_dominant_group": true,
      "name": "Sign in",
      "value": null,
      "input_type": null,
      "value_redacted": null,
      "checked": null,
      "disabled": null,
      "expanded": null,
      "aria_checked": null,
      "aria_disabled": null,
      "aria_expanded": null
    }
  ],
  "dominant_group_key": "x0-w3-h0",
  "ml_rerank": {
    "enabled": true,
    "applied": true,
    "reason": "goal_provided",
    "candidate_count": 120,
    "top_probability": 0.94,
    "min_confidence": 0.35,
    "is_high_confidence": true,
    "tags": ["onnx_v2"],
    "error": null
  },
  "diagnostics": {
    "confidence": 0.92,
    "reasons": [],
    "metrics": { "ready_state": "complete", "quiet_ms": 1200, "node_count": 2400, "interactive_count": 310, "raw_elements_count": 1200 },
    "captcha": null,
    "requires_vision": null,
    "requires_vision_reason": null
  },
  "modal_detected": false,
  "modal_grids": null
}

Response Fields

Top-Level Fields:

FieldTypeDescription
statusstringRequest status: "success" or "error"
urlstringThe URL that was analyzed
timestampstringISO timestamp of processing on the server
viewportobjectViewport dimensions (width, height). Always present (derived if missing in request).
credits_usednumberCredits consumed by this call (currently: 1 per request).
credits_remainingnumberRemaining credits on your account at time of request.
elementsarrayRanked array of refined elements
dominant_group_keystring | nullThe most common group_key (main content group)
ml_rerankobject | nullML reranking metadata (best-effort).
diagnosticsobject | nullRuntime stability/debug info (confidence, reasons, metrics)
modal_detectedboolean | nullTrue when a modal/overlay grid is detected (if modal detection is enabled server-side).
modal_gridsarray | nullArray of modal grid bounds/metadata (only populated when modal_detected is true).
errorstring | nullError message if status is "error"

Element Fields

Each element in the elements array contains:

Core Fields:

FieldTypeDescription
idnumberUnique identifier for clicking/interacting
rolestringSemantic role (button, textbox, link, heading, etc.)
textstringVisible text content (may be empty string)
importancenumberAI importance score (0-1000, higher = more important)
bboxobjectBounding box: x, y, width, height
visual_cuesobjectVisual hints: is_primary, is_clickable, background_color_name
in_viewportbooleanWhether element is visible in current viewport
is_occludedbooleanWhether element is hidden by other elements
z_indexnumberCSS z-index value (default: 0)

ML Reranking Fields (Optional):

FieldTypeDescription
fused_rank_indexnumber | null0-based rank after sorting by importance_fused
heuristic_indexnumber | null0-based rank before ML reranking
ml_probabilitynumber | nullConfidence score from ONNX model (0.0 - 1.0)
ml_scorenumber | nullRaw logit score from ONNX model (for debugging)

Ordinal / Layout Fields (Optional):

FieldTypeDescription
center_xnumber | nullX coordinate of element center (viewport coords)
center_ynumber | nullY coordinate of element center (viewport coords)
doc_ynumber | nullY coordinate in document (center_y + scroll_y)
group_keystring | nullGeometric bucket key for ordinal grouping
group_indexnumber | nullPosition within group (0-indexed, sorted by doc_y)
in_dominant_groupboolean | nullWhether element is in the dominant group (main content area)

State-Aware Assertion Fields (Optional):

FieldTypeDescription
namestring | nullAccessible name/label for controls
valuestring | nullCurrent value for inputs (may be redacted for PII)
input_typestring | nullInput type (text, email, password, etc.)
value_redactedboolean | nullWhether value was redacted for privacy
checkedboolean | nullNormalized checked state for checkboxes/radios
disabledboolean | nullNormalized disabled state
expandedboolean | nullNormalized expanded state
aria_checkedstring | nullRaw ARIA checked string (tri-state)
aria_disabledstring | nullRaw ARIA disabled string
aria_expandedstring | nullRaw ARIA expanded string

Additional Fields (Optional):

FieldTypeDescription
hrefstring | nullHyperlink URL (for link elements)
nearby_textstring | nullNearby static text (best-effort)
diff_statusstring | null"ADDED", "REMOVED", "MODIFIED", "MOVED" (for diff overlay)

Use Cases

When to Use This API

Use /v1/snapshot when you need fine-grained control:

When to Use the SDK

The SDK is recommended for most use cases because it:

Get started with the SDK →

Best Practices

1. Always include viewport dimensions

Accurate coordinates depend on consistent viewport size. Use the same dimensions for snapshots and actions.

2. Filter early to reduce costs

Use options.filter to reduce token costs and improve response times:

{
  "options": {
    "limit": 20,
    "filter": {
      "min_area": 100,
      "allowed_roles": ["button", "textbox", "link"]
    }
  }
}

3. Check occlusion before interacting

Always verify is_occluded: false before attempting to click or type:

if element.is_occluded:
    print(f"Element {element.id} is hidden by another element")
else:
    # Safe to interact
    click(browser, element.id)

4. Sort by importance score

Elements are pre-sorted by importance, but you can re-filter:

# Get only high-importance elements
important_elements = [e for e in elements if e.importance > 70]

Integration Example

Here's how the SDK uses this endpoint internally:

from predicate import PredicateBrowser, snapshot

with PredicateBrowser(api_key="sk_...") as browser:
    browser.page.goto("https://example.com")

    # This calls /v1/snapshot behind the scenes
    snap = snapshot(browser)

    # snap.elements contains the ranked results
    for element in snap.elements[:5]:  # Top 5 most important
        print(f"{element.role}: {element.text} (importance: {element.importance})")

Error Handling

If the request fails, you'll receive an error response:

{
  "status": "error",
  "error": "Invalid JSON payload: ...",
  "error_code": "bad_request",
  "credits_remaining": 123
}

Common errors:

Next Steps