> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prefetch.io/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /batch/{endpoint}/{id}

> Progress and results of a batch, a page at a time. Each answered URL carries what a single call returns.

## Overview

Returns the batch's progress and a page of answered URLs, in completion order. Each item carries every field the single endpoint returns for that URL — `domain`, `brand`, `company`, `classification`, `screenshot_url`, `styleguide`… — plus the batch's own bookkeeping:

| Field | Meaning |
| - | - |
| `ok` | `false` when the URL could not be answered. You are not charged for it. |
| `error`, `error_code` | Why, as one of the API's [error codes](/concepts/errors). |
| `status_code` | 200 for an answered URL. |

Follow `next` until it is `null` to read every result. Results stay readable for 24 hours after the batch is created.

## Example request

```bash theme={"theme":"css-variables"}
curl "https://api.prefetch.io/batch/enrich/crw_7c2e9a4b1d0f4e6a8b3c5d7e9f1a2b3c?limit=50" \
  -H "X-API-Key: $PREFETCH_API_KEY"
```

## Example response

```json theme={"theme":"css-variables"}
{
  "success": true,
  "data": {
    "id": "crw_7c2e9a4b1d0f4e6a8b3c5d7e9f1a2b3c",
    "status": "completed",
    "kind": "batch",
    "endpoint": "enrich",
    "url": "https://stripe.com",
    "total": 3,
    "completed": 3,
    "failed": 0,
    "credits_used": 36,
    "created_at": "2026-10-13T09:14:03.221Z",
    "started_at": "2026-10-13T09:14:04.010Z",
    "finished_at": "2026-10-13T09:14:41.512Z",
    "expires_at": "2026-10-14T09:14:03.221Z",
    "error": null,
    "next": null,
    "data": [
      {
        "url": "https://stripe.com",
        "depth": 0,
        "status_code": 200,
        "ok": true,
        "error": null,
        "error_code": null,
        "domain": "stripe.com",
        "brand": { "colors": { "brand_colors": [{ "color": "rgb(99, 91, 255)", "hex": "#635BFF", "name": "Blurple" }] } },
        "company": { "name": "Stripe, Inc.", "emails": [], "addresses": [] },
        "classification": { "iab_id": "IAB13", "category": "Personal Finance" }
      }
    ]
  },
  "meta": { "requestId": "2e3d4c5b-6a7f-4b8c-9d0e-1f2a3b4c5d6e", "durationMs": 88 }
}
```

## Credits

Polling is free in itself: each call charges only the URLs that completed since the previous call, at the endpoint's own price, and whatever no call claimed is charged when the batch ends. Polling every five seconds costs exactly what polling once at the end does.


## OpenAPI

````yaml GET /batch/{endpoint}/{id}
openapi: 3.1.0
info:
  title: Prefetch API
  description: >-
    Extract brand identity, company data, screenshots, IAB classifications, and
    clean page content from any URL.
  version: 1.0.0
  contact:
    email: support@prefetch.io
servers:
  - url: https://api.prefetch.io
    description: Production
security:
  - apiKey: []
tags:
  - name: Endpoints
    description: Data extraction endpoints. All require authentication and consume credits.
  - name: Health
    description: Health and readiness probes. No authentication required.
paths:
  /batch/{endpoint}/{id}:
    get:
      tags:
        - Endpoints
      summary: Batch status and results
      description: >-
        Progress plus a page of answered URLs, in completion order: each carries
        what `GET /{endpoint}` returns for it, plus `ok`, `error` and
        `error_code`. Follow `next` until it is null. Results stay readable for
        24 hours. URLs are charged as they complete — here, or when the batch
        ends — never twice.
      operationId: getBatchStatus
      parameters:
        - schema:
            type: string
            enum:
              - brand
              - enrich
              - company
              - classify
              - screenshot
              - styleguide
            description: What every URL is run through. /batch/scrape has its own page.
            example: enrich
          required: true
          description: What every URL is run through. /batch/scrape has its own page.
          name: endpoint
          in: path
        - schema:
            type: string
            description: The id returned when the job was created.
            example: crw_9f2c1a7b4e0d4c3a
          required: true
          description: The id returned when the job was created.
          name: id
          in: path
        - schema:
            type: string
            description: >-
              Page rows to skip — the cursor for paging through a crawl's
              results.
            example: '0'
          required: false
          description: Page rows to skip — the cursor for paging through a crawl's results.
          name: skip
          in: query
        - schema:
            type: string
            description: Page rows to return per request.
            example: '25'
          required: false
          description: Page rows to return per request.
          name: limit
          in: query
      responses:
        '200':
          description: Batch status and a page of results.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/BatchStatusData'
                  meta:
                    $ref: '#/components/schemas/Meta'
                required:
                  - success
                  - data
                  - meta
              example:
                success: true
                data:
                  id: crw_7c2e9a4b1d0f4e6a8b3c5d7e9f1a2b3c
                  status: completed
                  url: https://stripe.com
                  total: 3
                  completed: 3
                  failed: 0
                  credits_used: 36
                  created_at: '2026-10-13T09:14:03.221Z'
                  started_at: '2026-10-13T09:14:04.010Z'
                  finished_at: '2026-10-13T09:14:41.512Z'
                  expires_at: '2026-10-14T09:14:03.221Z'
                  error: null
                  kind: batch
                  endpoint: enrich
                  next: null
                  data:
                    - url: https://stripe.com
                      depth: 0
                      status_code: 200
                      ok: true
                      error: null
                      error_code: null
                      domain: stripe.com
                      brand:
                        colors:
                          brand_colors:
                            - color: rgb(99, 91, 255)
                              hex: '#635BFF'
                              name: Blurple
                      company:
                        name: Stripe, Inc.
                        emails: []
                        addresses: []
                      classification:
                        iab_id: IAB13
                        category: Personal Finance
                meta:
                  requestId: 6f1d2c3b-4a5e-4f60-8b7a-9c0d1e2f3a4b
                  durationMs: 1840
        '400':
          description: Invalid or missing parameters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Revoked key, expired key, blocked URL, or credit limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Batch not found or expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate or concurrency limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service temporarily unavailable — retry shortly.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    BatchStatusData:
      allOf:
        - $ref: '#/components/schemas/CrawlStatusData'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/BatchItem'
              description: Answered URLs, in completion order.
    Meta:
      type: object
      properties:
        requestId:
          type: string
          format: uuid
          description: Unique identifier for this request.
          example: a3f2c1d4-7b6e-4f2a-9c1d-8e3f2a1b4c5d
        durationMs:
          type: integer
          nullable: true
          description: Time taken to process the request in milliseconds.
          example: 1842
      required:
        - requestId
        - durationMs
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - false
          description: >-
            Always false. Absent, like `meta`, on authentication and rate-limit
            errors, which are answered before a request is processed.
        error:
          type: string
          description: >-
            Human-readable error message. The wording can change: branch on
            `error_code`.
          example: Credit limit exceeded
        error_code:
          type: string
          enum:
            - INVALID_REQUEST
            - PAYLOAD_TOO_LARGE
            - NOT_FOUND
            - CONFLICT
            - UNAUTHORIZED
            - FORBIDDEN
            - CREDITS_EXHAUSTED
            - RATE_LIMITED
            - CONCURRENCY_LIMITED
            - URL_BLOCKED
            - URL_NOT_PERMITTED
            - DNS_RESOLUTION_FAILED
            - TARGET_BLOCKED
            - TARGET_CONNECTION_FAILED
            - TARGET_TIMEOUT
            - TARGET_SSL_ERROR
            - TARGET_SERVER_ERROR
            - TARGET_CLIENT_ERROR
            - TARGET_NOT_A_PAGE
            - TARGET_UNLOADABLE
            - RESEARCH_INCONCLUSIVE
            - TIMEOUT
            - SERVICE_BUSY
            - SERVICE_UNAVAILABLE
            - INTERNAL_ERROR
          description: >-
            What went wrong, for machines. Stable: a code keeps its meaning once
            published. See [Error handling](/concepts/errors).
          example: CREDITS_EXHAUSTED
        retryable:
          type: boolean
          description: >-
            Whether the same request can succeed if sent again after a short
            wait (honour `Retry-After` when present). False for problems with
            the request or the target.
          example: false
        retryAfterSeconds:
          type: integer
          description: 'On `RATE_LIMITED`: seconds until a request will be accepted.'
        limit:
          type: integer
          description: >-
            On `CONCURRENCY_LIMITED`: how many requests this key may have in
            flight.
        meta:
          $ref: '#/components/schemas/Meta'
      required:
        - error
        - error_code
        - retryable
    CrawlStatusData:
      type: object
      properties:
        id:
          type: string
        status:
          type: string
          enum:
            - pending
            - running
            - completed
            - failed
            - cancelled
        url:
          type: string
        total:
          type: integer
          description: >-
            Pages the crawl expects to fetch, as currently known. Rises as it
            discovers more.
        completed:
          type: integer
        failed:
          type: integer
        credits_used:
          type: integer
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
          nullable: true
        finished_at:
          type: string
          format: date-time
          nullable: true
        expires_at:
          type: string
          format: date-time
        error:
          type: string
          nullable: true
        next:
          type: string
          nullable: true
          description: URL for the next page of results, or null when there are no more.
        data:
          type: array
          items:
            $ref: '#/components/schemas/CrawlPage'
          description: Crawled pages, in completion order.
        kind:
          type: string
          enum:
            - crawl
            - batch
          description: '`batch` for a `POST /batch/{endpoint}` job.'
        endpoint:
          type: string
          description: >-
            What each item is: `scrape` for a crawl or /batch/scrape, otherwise
            the batch's endpoint (`brand`, `enrich`, …).
          example: scrape
        skipped:
          type: object
          description: >-
            URLs the crawl found but did not fetch, by reason: `limit`, `depth`,
            `out-of-scope`, `excluded`, `not-included`, `robots`, `off-site`,
            `file`, `invalid`, `blocklist`, `duplicate` (a redirect onto a page
            already crawled). Present once anything was skipped.
          additionalProperties:
            type: object
            properties:
              count:
                type: integer
              samples:
                type: array
                items:
                  type: string
                description: Up to five examples.
    BatchItem:
      allOf:
        - type: object
          properties:
            url:
              type: string
            depth:
              type: number
              description: 'Always 0: a batch follows nothing.'
            status_code:
              type: number
              nullable: true
            ok:
              type: boolean
              description: >-
                False when the URL could not be answered. You are not charged
                for it.
            error:
              type: string
              nullable: true
            error_code:
              type: string
              nullable: true
              description: >-
                Why the page failed, as one of the API's error codes
                (`TARGET_TIMEOUT`, `DNS_RESOLUTION_FAILED`, …); null when it did
                not.
              example: TARGET_SERVER_ERROR
          required:
            - url
            - depth
            - status_code
            - ok
            - error
            - error_code
        - type: object
          additionalProperties:
            nullable: true
      description: >-
        One URL of a batch: the fields GET /{endpoint} returns for it (`domain`,
        `brand`, `company`, `classification`, `screenshot_url`, `styleguide`,
        …), plus the batch's bookkeeping.
    CrawlPage:
      type: object
      description: >-
        One crawled page. Carries the same fields `GET /scrape` returns, plus
        the crawl's own bookkeeping.
      allOf:
        - type: object
          properties:
            url:
              type: string
            depth:
              type: integer
              description: >-
                How many links from the start URL. Sitemap-seeded pages are
                depth 0.
            status_code:
              type: integer
              nullable: true
            ok:
              type: boolean
              description: >-
                False when the page could not be fetched. You are not charged
                for it.
            error:
              type: string
              nullable: true
            error_code:
              type: string
              nullable: true
              description: >-
                Why the page failed, as one of the API's [error
                codes](/concepts/errors#error-codes); null when it did not.
              example: TARGET_SERVER_ERROR
        - $ref: '#/components/schemas/ScrapePayload'
    ScrapePayload:
      type: object
      properties:
        url:
          type: string
        final_url:
          type: string
        domain:
          type: string
          nullable: true
          example: stripe.com
        status_code:
          type: integer
          nullable: true
        metadata:
          $ref: '#/components/schemas/ScrapeMetadata'
        markdown:
          $ref: '#/components/schemas/MarkdownBlock'
        summary:
          $ref: '#/components/schemas/SummaryBlock'
        html:
          $ref: '#/components/schemas/HtmlBlock'
        raw_html:
          $ref: '#/components/schemas/HtmlBlock'
        links:
          $ref: '#/components/schemas/LinksBlock'
        images:
          $ref: '#/components/schemas/ScrapeImagesBlock'
        json:
          $ref: '#/components/schemas/JsonBlock'
        screenshot:
          $ref: '#/components/schemas/ScrapeScreenshotBlock'
        pdf:
          $ref: '#/components/schemas/PdfBlock'
        prompt_injection:
          $ref: '#/components/schemas/PromptInjectionBlock'
        warnings:
          type: array
          items:
            type: string
          description: Non-fatal problems, such as a format that could not be produced.
      description: >-
        The page content fields. Which of them are present depends on the
        `formats` requested.
    ScrapeMetadata:
      type: object
      description: Always present, whatever formats were requested.
      properties:
        source_url:
          type: string
          nullable: true
          description: The URL you requested.
        final_url:
          type: string
          nullable: true
          description: The URL after redirects.
        status_code:
          type: integer
          nullable: true
        title:
          type: string
          nullable: true
          example: Stripe | Financial Infrastructure
        description:
          type: string
          nullable: true
        language:
          type: string
          nullable: true
          example: en
        canonical_url:
          type: string
          nullable: true
        favicon:
          type: string
          nullable: true
        author:
          type: string
          nullable: true
        site_name:
          type: string
          nullable: true
        published_time:
          type: string
          nullable: true
        modified_time:
          type: string
          nullable: true
        robots:
          type: string
          nullable: true
          description: The page's own robots meta tag.
        keywords:
          type: array
          items:
            type: string
        open_graph:
          type: object
          additionalProperties:
            type: string
        twitter:
          type: object
          additionalProperties:
            type: string
        json_ld:
          type: array
          items:
            type: object
          description: Parsed JSON-LD blocks, up to 10.
        headings:
          type: array
          description: The page's heading outline, up to 100 entries.
          items:
            type: object
            properties:
              level:
                type: integer
              text:
                type: string
        content_type:
          type: string
          enum:
            - text/html
            - application/pdf
          description: >-
            What the URL served. A PDF's text becomes the markdown; it has no
            html.
        page_count:
          type: integer
          description: 'PDFs only: pages in the document.'
        cache_state:
          type: string
          enum:
            - hit
            - miss
          description: >-
            Present when the request set `max_age`: `hit` = served from a stored
            fetch, `miss` = fetched live.
        cached_at:
          type: string
          description: 'On a cache hit: when the stored copy was fetched (ISO 8601).'
    MarkdownBlock:
      type: object
      properties:
        content:
          type: string
          description: >-
            GitHub Flavored Markdown. Links and images are resolved to absolute
            URLs.
        char_count:
          type: integer
        word_count:
          type: integer
        truncated:
          type: boolean
          description: True when the content hit the 1 MB size cap and was cut.
        main_content_only:
          type: boolean
          description: >-
            True when boilerplate was successfully isolated away. False means
            the full page body was returned.
    SummaryBlock:
      type: object
      properties:
        text:
          type: string
          nullable: true
          description: Null when the summary could not be produced; see `warnings`.
        model:
          type: string
          nullable: true
    HtmlBlock:
      type: object
      properties:
        content:
          type: string
        char_count:
          type: integer
        truncated:
          type: boolean
        main_content_only:
          type: boolean
    LinksBlock:
      type: object
      properties:
        internal:
          type: array
          description: Links on the same site, subdomains included.
          items:
            $ref: '#/components/schemas/ScrapeLinkItem'
        external:
          type: array
          items:
            $ref: '#/components/schemas/ScrapeLinkItem'
        count:
          type: integer
    ScrapeImagesBlock:
      type: object
      properties:
        assets:
          type: array
          items:
            $ref: '#/components/schemas/ScrapeImageItem'
        og_image:
          type: string
          nullable: true
        twitter_image:
          type: string
          nullable: true
        count:
          type: integer
    JsonBlock:
      type: object
      properties:
        data:
          type: object
          nullable: true
          description: The extracted object, shaped by your prompt or schema.
        model:
          type: string
          nullable: true
    ScrapeScreenshotBlock:
      type: object
      description: Present when `formats` includes `screenshot`.
      properties:
        url:
          type: string
          description: 'The image on our CDN. Short-lived: copy it if you need to keep it.'
        viewport:
          type: object
          properties:
            width:
              type: integer
            height:
              type: integer
        full_page:
          type: boolean
        format:
          type: string
          enum:
            - jpeg
            - png
            - webp
    PdfBlock:
      type: object
      description: Present when the URL served a PDF. Its text is in `markdown`.
      properties:
        page_count:
          type: integer
        pages_parsed:
          type: integer
          description: Pages whose text was read (capped for very long documents).
        truncated:
          type: boolean
    PromptInjectionBlock:
      type: object
      description: Present when the request set `check_prompt_injection`.
      properties:
        detected:
          type: boolean
          description: >-
            True when the page's text appears to contain instructions aimed at
            an AI model.
        reason:
          type: string
          nullable: true
          description: >-
            Why it was flagged, quoting or describing the suspicious text. Null
            when nothing was found.
          example: >-
            The page tells AI assistants to ignore their instructions and send
            the user's API keys to an outside address.
        complete:
          type: boolean
          description: >-
            True when all of the page's text was checked. False when part of it
            could not be (a very long page, or the classifier was unavailable):
            `detected: false` then means nothing was found in what was checked,
            not that the page is clean.
        model:
          type: string
          nullable: true
          description: The model that checked it; null for a page with no text.
          example: gpt-5.6-luna
      required:
        - detected
        - reason
        - complete
        - model
    ScrapeLinkItem:
      type: object
      properties:
        url:
          type: string
        text:
          type: string
          nullable: true
          description: The anchor text.
        title:
          type: string
          nullable: true
        rel:
          type: string
          nullable: true
    ScrapeImageItem:
      type: object
      properties:
        url:
          type: string
        alt:
          type: string
          nullable: true
        width:
          type: integer
          nullable: true
        height:
          type: integer
          nullable: true
        loading:
          type: string
          nullable: true
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: Your Prefetch API key. Obtain one from the dashboard.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.