Onto Batch API

Read, score, or extract up to 50 URLs (a list or a whole site) in one call.

Operations 1

POST /v1/batch Process many URLs in one call #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/buildonto-dev:buildonto-dev-batch-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

buildonto-dev-batch-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Onto Read Batch API
  version: 1.0.0
  summary: Turn any URL into clean Markdown, an AIO accuracy score, and hallucination-risk flags.
  description: 'The Onto Read API takes a URL and returns clean Markdown that an LLM can consume directly,

    plus a 0–100 AIO accuracy score and hallucination-risk metadata.


    **Authentication.** All requests use bearer-token auth — pass your API key in the

    `Authorization` header. Get one at app.buildonto.dev/read/keys;

    the Free tier gives you 1,000 credits a month.


    **Endpoints.** `/v1/read`, `/v1/score`, `/v1/read-and-score` and `/v1/extract` work on one

    URL. `/v1/batch` handles up to 50 URLs in one call, `/v1/map` lists a site''s URLs, and

    `/v1/usage` shows your quota and credits. Most agent workflows want `/v1/read-and-score` —

    it returns both the cleaned Markdown and the accuracy metadata in a single round-trip.


    **Credits.** `/v1/read`, `/v1/read-and-score`, `/v1/extract` and `/v1/map` cost 1 credit per

    call; `/v1/batch` costs 1 credit per URL. `/v1/score` and `/v1/usage` are free. Failed

    requests are refunded.


    **Errors.** Every error response shares the same shape with a stable `code` field — branch

    on `code`, not on the human-readable `message`. Extra details, like `retry_after`, sit at

    the top level of the body. See

    the error codes index for the full catalog.'
  contact:
    name: Onto support
    email: founder@buildonto.dev
    url: https://buildonto.dev
  license:
    name: Proprietary
    url: https://buildonto.dev/legal/terms
servers:
- url: https://api.buildonto.dev
  description: Production
security:
- bearerAuth: []
tags:
- name: Batch
  description: Read, score, or extract up to 50 URLs (a list or a whole site) in one call.
paths:
  /v1/batch:
    post:
      tags:
      - Batch
      summary: Process many URLs in one call
      operationId: batch
      description: 'Read, score, or extract many URLs in one call — an explicit list (`urls`) or a whole

        site (`site`, pages discovered the same way as `/v1/map`). `mode` picks the per-URL

        operation. Costs 1 credit per URL, whatever the mode. At most 50 URLs are used; extras

        are dropped. A page that can''t be read comes back with `ok: false` and an `error`; it

        never fails the batch, and its credit is refunded. Markdown is capped at 12,000

        characters per page — call `/v1/read` for the full page.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                urls:
                  type: array
                  items:
                    type: string
                    format: uri
                  description: Explicit list of URLs. Use this OR `site`. Only the first 50 valid URLs are used.
                site:
                  type: string
                  format: uri
                  description: Base URL whose pages are auto-discovered. Use this OR `urls`.
                mode:
                  type: string
                  enum:
                  - read
                  - read-and-score
                  - extract
                  default: read-and-score
                  description: An unknown value falls back to `read-and-score`.
                limit:
                  type: integer
                  minimum: 1
                  maximum: 50
                  default: 25
                  description: Site mode only — max pages to discover.
            examples:
              list:
                summary: Explicit URL list
                value:
                  urls:
                  - https://stripe.com/pricing
                  - https://stripe.com/docs
                  mode: read-and-score
              site:
                summary: Whole site, extract mode
                value:
                  site: https://stripe.com
                  limit: 25
                  mode: extract
      responses:
        '200':
          description: Batch processed
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  mode:
                    type: string
                    enum:
                    - read
                    - read-and-score
                    - extract
                  source:
                    type: string
                    enum:
                    - urls
                    - site
                  requested:
                    type: integer
                  succeeded:
                    type: integer
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        url:
                          type: string
                        ok:
                          type: boolean
                        error:
                          type: object
                          description: Present only when `ok` is false.
                          properties:
                            code:
                              type: string
                            message:
                              type: string
                        title:
                          type: string
                        aio_score:
                          type: integer
                          description: Absent for PDF and plain-text URLs.
                        grade:
                          type: string
                        hallucination_risk:
                          type: string
                          enum:
                          - low
                          - medium
                          - high
                        reduction_percent:
                          type: number
                        markdown:
                          type: string
                        structured:
                          type: object
                        counts:
                          type: object
                  cache:
                    type: object
              example:
                status: success
                mode: read-and-score
                source: urls
                requested: 2
                succeeded: 2
                results:
                - url: https://stripe.com/pricing
                  ok: true
                  aio_score: 88
                  grade: Good
                  hallucination_risk: low
                  reduction_percent: 96.4
                  markdown: '# Stripe pricing…'
                cache:
                  hit: false
                  ttl_seconds: 3600
        '400':
          $ref: '#/components/responses/BatchInvalidRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  responses:
    BatchInvalidRequest:
      description: 'Multiple causes:

        - `INVALID_REQUEST` — body isn''t JSON, has neither `urls` nor `site`, or `urls` holds no valid http(s) URLs

        - `INVALID_URL` — `site` can''t be parsed or points at a private or internal host

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            request:
              value:
                status: error
                code: INVALID_REQUEST
                message: '"urls" contained no valid HTTP(S) URLs.'
            site:
              value:
                status: error
                code: INVALID_URL
                message: 'Could not parse site URL: stripe'
    PaymentRequired:
      description: Paid plans only — monthly plan credits AND bought credits are both used up. Free gets `RATE_LIMITED` instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: error
            code: PAYMENT_REQUIRED
            message: Monthly plan quota exceeded and credit balance is empty. Top up credits in the dashboard to continue.
            plan_limit: 10000
            credits_remaining: 0
    Unauthorized:
      description: Missing, malformed, or revoked Bearer token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: error
            code: UNAUTHORIZED
            message: Missing or invalid API key
    RateLimited:
      description: 'Multiple causes:

        - `RATE_LIMITED` — monthly plan credits used up (Free only; paid plans spill into bought credits)

        - `CONCURRENT_LIMIT` — too many requests running at once for your plan; retry after 1 second

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            monthly:
              value:
                status: error
                code: RATE_LIMITED
                message: Monthly quota exceeded
                retry_after: '2026-10-01T00:00:00.000Z'
            concurrent:
              value:
                status: error
                code: CONCURRENT_LIMIT
                message: Too many concurrent requests for your tier (5/5 in flight). Retry in a moment.
                in_flight: 5
                limit: 5
                retry_after: 1
  schemas:
    ErrorResponse:
      type: object
      required:
      - status
      - code
      - message
      properties:
        status:
          type: string
          enum:
          - error
        code:
          type: string
          description: Stable error code — branch on this, not on `message`.
        message:
          type: string
          description: Human-readable message; wording may change without notice.
        retry_after:
          oneOf:
          - type: integer
            description: Seconds to wait before retrying (CONCURRENT_LIMIT). Always 1.
          - type: string
            format: date-time
            description: When monthly credits reset — the end of the current UTC month (RATE_LIMITED).
        plan_limit:
          type: integer
          description: Your plan's monthly credits (PAYMENT_REQUIRED).
        credits_remaining:
          type: integer
          description: Bought credits left, always 0 (PAYMENT_REQUIRED).
        in_flight:
          type: integer
          description: Requests running for your account right now (CONCURRENT_LIMIT).
        limit:
          type: integer
          description: Your plan's concurrency limit (CONCURRENT_LIMIT).
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: onto_sk_live_…
      description: 'Pass your API key as `Authorization: Bearer {your_key}`. Get a key at

        [app.buildonto.dev/read/keys](https://app.buildonto.dev/read/keys).

        '