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

# POST /batch

> Asynchronously scrape up to 50 URLs in one request.

## How it differs from /scrape

`/scrape` is synchronous: one URL, one response, content in the body.
`/batch` is asynchronous: it returns `202` with a `job_id` immediately and
fans out the work to the queue. There is no batch result in the `202` — you
must poll.

Use `/batch` when you already have a list of URLs. Use
[`/crawl`](/en/api-reference/crawl) when you only have a seed and want the
crawler to discover the links.

## Limits

Up to **50 URLs** per request. An empty list or more than 50 URLs is rejected
with `422` before any job is created — you are never billed for a rejected
batch.

The rate limit of this endpoint **scales with your plan** (`free` 10/min,
`starter` 60/min, `growth` 120/min, `scale` 300/min). It is the only endpoint
that does.

## Cost

**1 credit per URL whose `scrape_status` is `success`.** Blocked, failed, or
SSRF-rejected URLs in the batch are not billed, so the final `credits_used`
can be lower than the number of URLs you sent.

## Polling the result

```bash cURL theme={null}
# 1. enqueue
curl -X POST https://api.messora.dev/batch \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"urls": ["https://example.com", "https://messora.dev"], "formats": ["markdown"]}'
# → {"job_id": "550e8400-e29b-41d4-a716-446655440002"}

# 2. poll every 2s until status is SUCCESS or FAILURE
curl https://api.messora.dev/jobs/550e8400-e29b-41d4-a716-446655440002 \
  -H "X-API-Key: YOUR_API_KEY"
```

Each item in `results` carries its own `url`, `scrape_status` and
`credits_used`. See [`GET /jobs/{job_id}`](/en/api-reference/jobs) for the
full status contract.


## OpenAPI

````yaml POST /batch
openapi: 3.1.0
info:
  description: >-
    ## Messora API


    Scraping com evasão anti-bot nativa. Retorna conteúdo limpo (Markdown / JSON
    estruturado / raw HTML).


    **Autenticação:** header `X-API-Key` em todas as rotas.


    **Créditos:** scrape markdown/raw = 1; JSON estruturado = 10; search = 1 por
    resultado; crawl = 1 por página bem-sucedida.
  summary: API de scraping LLM-ready com motor anti-bot nativo.
  title: Messora API
  version: 2.0.0
servers:
  - description: API pública do Messora
    url: https://api.messora.dev
security: []
paths:
  /batch:
    servers:
      - description: API pública do Messora
        url: https://api.messora.dev
    post:
      tags:
        - Scraping
      summary: Scraping de volume assíncrono (até 50 URLs)
      description: >-
        Enfileira scraping em lote de até 50 URLs e retorna `job_id`
        imediatamente. O fan-out acontece de forma assíncrona via Celery.


        - Cobrança por URL com `scrape_status: "success"` — URLs bloqueadas não
        cobram.

        - Use `GET /jobs/{job_id}` para acompanhar o progresso e obter os
        resultados.

        - **Rate limit:** escala com o plano (PLAN_LIMITS) — free 10/min,
        starter 60/min, growth 120/min, scale 300/min.
      operationId: enqueue_batch_batch_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchRequest'
        required: true
      responses:
        '202':
          content:
            application/json:
              example:
                job_id: 550e8400-e29b-41d4-a716-446655440002
              schema:
                $ref: '#/components/schemas/BatchEnqueueResponse'
          description: Lote enfileirado. Usar GET /jobs/{job_id} para polling.
        '401':
          description: X-API-Key ausente
        '403':
          description: API key inválida ou revogada
        '422':
          description: Lista vazia, > 50 URLs ou parâmetros inválidos
        '429':
          description: Rate limit do plano excedido (PLAN_LIMITS por plano)
      security:
        - APIKeyHeader: []
components:
  schemas:
    BatchRequest:
      properties:
        formats:
          default:
            - markdown
          items:
            enum:
              - markdown
              - json
              - raw
            type: string
          title: Formats
          type: array
        urls:
          items:
            format: uri
            maxLength: 2083
            minLength: 1
            type: string
          title: Urls
          type: array
      required:
        - urls
      title: BatchRequest
      type: object
    BatchEnqueueResponse:
      description: 'Resposta 202 de `POST /batch`: só o identificador para polling.'
      properties:
        job_id:
          description: Identificador do job. Consultar em GET /jobs/{job_id}.
          title: Job Id
          type: string
      required:
        - job_id
      title: BatchEnqueueResponse
      type: object
  securitySchemes:
    APIKeyHeader:
      in: header
      name: X-API-Key
      type: apiKey

````