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

# List fillable AcroForm fields

> Accepts template bytes as JSON Base64 (`pdf`) or multipart field `pdf`, or `templateId` XOR `pdf` for a stored blank template (same store as `GET /v1/templates/:id`). Same `x-api-key` as render. Does not apply plan `bodyBytes` to live `pdf` bytes. Stays request/response and unmetered. Sits on plan `ratePerMin` and `concurrency` (same post-auth limiters as fill). Burst is 429 `rate_limited`. Returns every fillable field (`name`, `kind`, `required`, options, current `/V`, `widgets`) plus skipped import names and `warnings`. A name with more than one widget lists every `{page,rect}`. Cloned placements also get a `multi_widget` warning: one fill-by-name value paints every placement. Radio options are not that warning. A PDF with no widgets inspects to `fields: []` plus reason `no_widgets`. If the PDF has no widgets, make it a form in studio first. Does not store the PDF. Does not spend a unit. Does not write a filled PDF. Does not accept `values`. A template with no `/AcroForm`, `/NeedAppearances`, a password, XFA, or a document signature or certification is rejected (`no_acroform`, `need_appearances` (`PdfNeedAppearancesUnsupportedError`), `encrypted_pdf` (`PdfEncryptionUnsupportedError`), `xfa_unsupported` (`PdfXfaUnsupportedError`), or `signed_pdf` (`PdfSignedPdfUnsupportedError`)). Not a second verb on `POST /v1/render`.



## OpenAPI

````yaml /openapi.json post /v1/inspect
openapi: 3.1.0
info:
  title: Blink PDF API
  description: >-
    Render Markdown into accessible, PDF/UA-conformant PDFs over HTTP. Send
    Markdown plus optional document metadata, fonts, page layout, viewer hints,
    and per-block style overrides to `POST /v1/render`, or use a structured
    template such as `POST /v1/templates/sandwich-document/render`. Fill by name
    is a separate verb: template (PDF bytes or stored id) plus `{ name: value }`
    returns a filled PDF. Inspect the field list at `POST /v1/inspect`, dry-run
    at `POST /v1/validate-fill`, and fill at `POST /v1/fill`. `POST /v1/fill`
    streams the PDF and does not keep the output. Stored templates live at
    `/v1/templates` (store, get, list, update, delete, download). Names are ISO
    fully qualified names, or the unique `/T` when there is only one. Omitted
    names stay unchanged. `false` is a value. Unknown names reject the request.
    The filled PDF never includes `/NeedAppearances`. A PDF with no widgets
    inspects to `fields: []` plus reason `no_widgets`; make it a form in studio
    first. Fill is request/response: plan `bodyBytes` and a 120 second produce
    ceiling. No job id. Fill is not a second verb on `POST /v1/render`.
    Authentication is via an `x-api-key` header. Unknown routes return HTTP 404
    with body `{ "error": "not_found" }`.
  version: 1.5.0
  contact:
    name: Blink PDF Support
    email: support@blinkpdf.io
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.blinkpdf.io
    description: Production
security: []
tags:
  - name: Discovery
    description: Machine-readable API entry point
  - name: Health
    description: Liveness probes
  - name: Render
    description: Markdown-to-PDF rendering
  - name: Fonts
    description: Hosted font catalog and Google Fonts capability discovery
  - name: SandwichDocument
    description: >-
      Sandwich documents — a first-page header (logo, professional identity,
      subject/context data) and a last-page footer (signature, name) wrapping a
      Markdown body
  - name: Fill
    description: Fill an AcroForm by name
  - name: Templates
    description: Stored AcroForm template library
paths:
  /v1/inspect:
    post:
      tags:
        - Fill
      summary: List fillable AcroForm fields
      description: >-
        Accepts template bytes as JSON Base64 (`pdf`) or multipart field `pdf`,
        or `templateId` XOR `pdf` for a stored blank template (same store as
        `GET /v1/templates/:id`). Same `x-api-key` as render. Does not apply
        plan `bodyBytes` to live `pdf` bytes. Stays request/response and
        unmetered. Sits on plan `ratePerMin` and `concurrency` (same post-auth
        limiters as fill). Burst is 429 `rate_limited`. Returns every fillable
        field (`name`, `kind`, `required`, options, current `/V`, `widgets`)
        plus skipped import names and `warnings`. A name with more than one
        widget lists every `{page,rect}`. Cloned placements also get a
        `multi_widget` warning: one fill-by-name value paints every placement.
        Radio options are not that warning. A PDF with no widgets inspects to
        `fields: []` plus reason `no_widgets`. If the PDF has no widgets, make
        it a form in studio first. Does not store the PDF. Does not spend a
        unit. Does not write a filled PDF. Does not accept `values`. A template
        with no `/AcroForm`, `/NeedAppearances`, a password, XFA, or a document
        signature or certification is rejected (`no_acroform`,
        `need_appearances` (`PdfNeedAppearancesUnsupportedError`),
        `encrypted_pdf` (`PdfEncryptionUnsupportedError`), `xfa_unsupported`
        (`PdfXfaUnsupportedError`), or `signed_pdf`
        (`PdfSignedPdfUnsupportedError`)). Not a second verb on `POST
        /v1/render`.
      operationId: inspectForm
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                pdf:
                  type: string
                  format: byte
                  description: >-
                    AcroForm PDF bytes, Base64-encoded. Does not store the PDF.
                    Does not spend a unit. XOR with `templateId`.
                templateId:
                  type: string
                  description: >-
                    Stored template id from `POST /v1/templates`. XOR with
                    `pdf`. Same store as `GET /v1/templates/:id`. Unknown,
                    deleted, or foreign is 404.
            examples:
              byBytes:
                summary: Template bytes
                value:
                  pdf: <Base64>
              byTemplateId:
                summary: Stored template id
                value:
                  templateId: <id>
          multipart/form-data:
            schema:
              type: object
              additionalProperties: false
              properties:
                pdf:
                  type: string
                  format: binary
                  description: >-
                    AcroForm PDF file part. Does not store the PDF. Does not
                    spend a unit. XOR with `templateId`.
                templateId:
                  type: string
                  description: >-
                    Stored template id from `POST /v1/templates`. XOR with
                    `pdf`. Same store as `GET /v1/templates/:id`. Unknown,
                    deleted, or foreign is 404.
      responses:
        '200':
          description: >-
            Fillable fields plus skipped import names and `warnings`. A name
            with more than one widget lists `widgets`. Cloned placements also
            include `multi_widget`; radio options do not. Or `fields: []` plus
            reason `no_widgets` when the PDF has no widgets. Names are the keys
            fill accepts
          content:
            application/json:
              schema:
                type: object
                required:
                  - fields
                  - skipped
                  - warnings
                properties:
                  fields:
                    type: array
                    description: Fillable terminals. `name` is the fill-by-name key.
                  skipped:
                    type: array
                    description: Import-omitted names (`signature`, `pushbutton`, …).
                  warnings:
                    type: array
                    description: >-
                      Always present. `multi_widget` when a name has more than
                      one placement.
                  reason:
                    type: string
                    const: no_widgets
                    description: >-
                      Present when `fields` and `skipped` are both empty. Make
                      it a form in studio first.
        '400':
          description: Missing or invalid template bytes, or both `pdf` and `templateId`
        '401':
          $ref: '#/components/responses/Responses.Unauthorized'
        '404':
          description: No stored template with that `templateId` for this account
        '413':
          $ref: '#/components/responses/Responses.PayloadTooLarge'
        '422':
          description: >-
            Template rejected: `no_acroform`, `need_appearances`
            (`PdfNeedAppearancesUnsupportedError`), `encrypted_pdf`
            (`PdfEncryptionUnsupportedError`), `xfa_unsupported`
            (`PdfXfaUnsupportedError`), or `signed_pdf`
            (`PdfSignedPdfUnsupportedError`)
        '429':
          $ref: '#/components/responses/Responses.RateLimited'
        '503':
          $ref: '#/components/responses/Responses.ServiceUnavailable'
      security:
        - apiKey: []
components:
  responses:
    Responses.Unauthorized:
      description: >-
        Missing or invalid `x-api-key` (must be a valid, enabled `bp_*` key;
        documentation endpoints and health are exempt)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error.Unauthorized'
          examples:
            unauthorized:
              $ref: '#/components/examples/Error.Unauthorized'
    Responses.PayloadTooLarge:
      description: >-
        Serialized JSON request body exceeds the caller's plan tier limit
        (`getTechnicalLimits`: free 128 KiB, pro 2 MiB, business 5 MiB).
        Enforcement uses the UTF-8 byte length of `JSON.stringify(body)` after
        parse, so a missing or incorrect `Content-Length` header cannot bypass
        the cap.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error.PayloadTooLarge'
          examples:
            payloadTooLarge:
              $ref: '#/components/examples/Error.PayloadTooLarge'
    Responses.RateLimited:
      description: >-
        Rate or concurrency limit exceeded (post-auth per-tier limits from
        `getTechnicalLimits`: free 10/min + 1 concurrent, pro 120/min + 10
        concurrent, business 600/min + 40 concurrent; a high pre-auth per-IP
        flood shield also exists but is sized above every plan rate and never
        binds first for plan traffic). Post-auth tier rate and concurrency
        blocks both return `error: rate_limited` but use different `detail`
        strings; audit rows distinguish `rate_limited` vs `concurrency_limited`.
        Tier-specific responses may include upgrade guidance in `detail`. The
        response carries `Retry-After` and defensive security headers.
      headers:
        Retry-After:
          schema:
            minimum: 1
            type: integer
          description: Seconds remaining until the rate-limit window resets. Always >= 1.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error.RateLimited'
          examples:
            rateLimited:
              $ref: '#/components/examples/Error.RateLimited'
    Responses.ServiceUnavailable:
      description: >-
        Transient outage: a subscription tier lookup failed
        (`service_unavailable`, fail-closed) or the font catalogue could not be
        read (`font_source_unavailable`). Retry shortly.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error.ServiceUnavailable'
          examples:
            serviceUnavailable:
              $ref: '#/components/examples/Error.ServiceUnavailable'
  schemas:
    Error.Unauthorized:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - unauthorized
    Error.PayloadTooLarge:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - payload_too_large
    Error.RateLimited:
      type: object
      required:
        - error
      description: >-
        Post-auth tier rate exhaustion and post-auth concurrency exhaustion both
        use `error: rate_limited`; distinguish them by `detail` (tier rate vs
        concurrency/plan copy). Render audit rows use separate `status` values
        (`rate_limited` vs `concurrency_limited`).
      properties:
        error:
          type: string
          enum:
            - rate_limited
        detail:
          type: string
    Error.ServiceUnavailable:
      type: object
      required:
        - error
      description: >-
        Transient outage shared by every 503. `font_source_unavailable` is a
        font catalogue read failure (`POST /v1/render`, `GET /v1/fonts`);
        `service_unavailable` is a subscription tier-lookup failure, fail-closed
        (`GET /v1/fonts`). Both are retryable. Each route documents which codes
        it can emit.
      properties:
        error:
          type: string
          enum:
            - service_unavailable
            - font_source_unavailable
        detail:
          type: string
  examples:
    Error.Unauthorized:
      summary: Missing or invalid x-api-key (bp_*)
      value:
        error: unauthorized
    Error.PayloadTooLarge:
      summary: Request body exceeds the configured cap
      value:
        error: payload_too_large
    Error.RateLimited:
      summary: >-
        Per-tier rate limit exceeded (concurrency exhaustion uses the same error
        code with a different detail string)
      value:
        error: rate_limited
        detail: >-
          Tier rate limit exceeded. Retry after the Retry-After interval or
          upgrade for higher sustained throughput.
    Error.ServiceUnavailable:
      summary: Transient tier-lookup or font-catalogue outage
      value:
        error: service_unavailable
        detail: >-
          Subscription tier lookup is temporarily unavailable. Retry the
          request.
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key issued from your Blink PDF account, prefixed `bp_`. Send it in
        the `x-api-key` header on every request. The documentation and health
        endpoints are exempt.

````

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