---
title: "Perceive Batch"
method: POST
path: "/v2/perceive/batch"
tags: ["v2", "v2-perceive"]
---

# Perceive Batch

`POST /v2/perceive/batch`

## Request

- Base URL: `https://api.enconvert.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.enconvert.com/v2/perceive/batch`
- Auth: none declared

Bulk perception: <= 10 URLs inline (200), larger queued (202).

Gate order matters: nothing is persisted until every gate passed —
a 403/402/422 must leave zero rows behind.

## Headers

- `X-API-Key` string, nullable
- `authorization` string, nullable

## Request body

- PerceiveBatchRequest: POST /v2/perceive/batch (Task F.8, no-GCP revision). ``urls`` share one ``options`` block; each URL becomes a full PerceiveRequest. The plan's batch_limit gates the count; 1000 is a schema-level backstop above every plan limit.
  - `urls` string[], required
  - `options` PerceiveOptionsBase: Per-render options shared by /v2/perceive and the batch endpoint. ``extra="forbid"``: an unknown key is a 422 naming the field, never a silent no-op. The 2026-08-06 QA cycle filed 22 findings against a ``content_only`` parameter this API never had, because the schema silently swallowed it — an unknown key MUST fail loudly.
    - `outputs` string[]
    - `only_main_content` boolean: When true (default), the markdown output and the main_content extract strip site chrome (navigation, header, footer, sidebars, cookie banners, hidden nodes) behind a fidelity guard that falls back to the full page when stripping would remove too much real content. When false, the full page content is kept with no stripping.
    - `truncate_data_arrays` boolean, nullable: Collapse long runs of numeric literals (raw embedding vectors, tensor dumps in notebook output cells) to a leading sample plus a count. Unset (the default) follows only_main_content: on when the page is being curated, off when the caller asked for the page as-is. Set true/false to control it explicitly.
    - `allow_degraded` boolean: Deprecated and ignored. A content-free anti-bot block now always returns 200 with is_blocked=true, the render-quality deductions and no artifacts (it is not billed). Sending true adds a deprecation warning to the response.
    - `direct_download` boolean: When true, the response body IS the artifact bytes (no second fetch to a signed URL). Requires exactly one artifact-producing output. Not available on the batch endpoint (use output_mode='zip' there).
    - `extract` string[]
    - `schema` object, nullable: JSON schema for structured extraction (Tier-3 LLM path lands in Sprint F.6; accepted and stored today).
    - `wait_for` string, nullable: CSS selector (optionally 'css:...') or 'js:<expr>' to await after navigation.
    - `wait_timeout_ms` integer
    - `js_code` string, nullable
    - `viewport` PerceiveViewport
      - `width` integer
      - `height` integer
    - `headers` object, nullable
    - `cookies` object[], nullable
    - `auth` PerceiveAuth
      - `username` string, required
      - `password` string, required
    - `proxy_url` string, nullable: Business+; not yet available (422).
    - `geolocation` object, nullable: Not yet available (422).
    - `action_chain` object[], nullable: Not yet available (422).
    - `cache_mode` 'enabled' | 'bypass' | 'refresh'
    - `pdf_options` PdfOptions
      - `page_size` string
      - `page_width` number, nullable
      - `page_height` number, nullable
      - `orientation` string
      - `margins` PdfMargins
        - `top` number
        - `bottom` number
        - `left` number
        - `right` number
      - `scale` number
      - `grayscale` boolean
      - `header` PdfHeaderFooter
        - `content` string
        - `height` number
      - `footer` PdfHeaderFooter
        - `content` string
        - `height` number
    - `block_resources` string[]
    - `respect_robots` boolean
    - `mobile` boolean
  - `output_mode` 'manifest' | 'zip'

## Response `200`

Successful Response

- PerceiveBatchResponse: Shared by POST (inline 200 / queued 202) and the status GET. ``items`` carry one PerceiveResponse per URL: fully populated on the inline path and on status polls; empty on the initial 202 (poll the status endpoint with ``job_id``). ``zip`` appears once a ``output_mode="zip"`` batch has bundled its artifacts.
  - `job_id` string, required
  - `status` 'queued' | 'processing' | 'completed' | 'failed' | 'partial' | 'canceled', required
  - `output_mode` 'manifest' | 'zip'
  - `total` integer, required
  - `completed` integer
  - `failed` integer
  - `pending` integer
  - `zip` OutputArtifact: A rendered output stored in Spaces, addressed by signed URL only.
    - `url` string, nullable: Pre-signed download URL (15 min).
    - `object_key` string, required
    - `size_bytes` integer
    - `content_type` string
    - `expires_in` integer
  - `items` PerceiveResponse[]
    - `operation_id` string, required
    - `status` 'queued' | 'processing' | 'completed' | 'failed', required
    - `url` string, required
    - `url_final` string, nullable
    - `content_hash` string, nullable
    - `status_code` integer, nullable: HTTP status of the final main-document response (e.g. 200, 404). None when the engine could not observe it.
    - `render_quality` number, nullable: 0.0-1.0; populated by the F.7 scorer.
    - `deductions` object: Named render-quality deductions that fired for this render (e.g. {'http_error': 0.7}). Empty on a clean render.
    - `is_blocked` boolean: True when the scorer judged the render an anti-bot challenge or WAF block page. A block with no page content behind it returns 200 with this flag set and outputs={}.
    - `billed` boolean: Whether this operation consumed one op from the monthly quota. False for blocked reads and for renders whose deductions include http_error or login_wall; cache hits bill.
    - `options_echo` object, nullable: Echo of the request options the server honoured (secrets redacted to booleans), so a caller can verify what was actually applied.
    - `cache_hit` boolean
    - `outputs` object
    - `structured` object, nullable
    - `extraction_tier` 'heuristic' | 'css' | 'llm', nullable
    - `tokens` PerceiveTokens
      - `input` integer
      - `output` integer
    - `cost_cents` number
    - `duration_ms` integer, nullable
    - `error` string, nullable
    - `warnings` string[]
  - `warnings` string[]

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/enconvert/apis/conversion-api.md) · [All operations](https://skmtc.dev/enconvert/apis/conversion-api/llms.txt) · [OpenAPI document](https://skmtc.dev/enconvert/apis/conversion-api/revisions/b8c820393569?raw)
