FormRead Server-Side Processing API

Server-Side Form Processing

The FormRead Server-Side API lets you send a scanned form image and receive structured results (OMR, OCR, BCR) directly as JSON. No browser, no iframe — just a simple HTTP request from your backend to ours.

  • Send an image, get results back as JSON in a single request
  • Supports OMR (bubble detection), OCR (text extraction), and BCR (barcode/QR reading)
  • Form configuration is loaded automatically from the form you set up in the dashboard
When to Use This API

Use the server-side API when you need automated, server-to-server processing without any user interface — for example, processing batches of scanned forms from a folder, integrating with your existing backend pipeline, or building automated grading systems.

If you need a visual interface where users can set up forms, review results, and do QA — use the Iframe Integration API instead.

Autenticación

Para usos empresariales, la API se puede usar generando un token de autenticación "Bearer".

Inicie sesión en el panel de FormRead, y acceda a la opción API Token:

FormRead dashboard menu with the API Tokens option highlighted

Cree los tokens de API para permitir que los servicios de terceros se autentiquen con nuestra aplicación en su nombre:

Creating a new FormRead API token with permission checkboxes

Process a Form Image

Send a scanned form image to be processed. The form must already be set up with read areas (OMR, OCR, BCR) via the dashboard or iframe. The API uses the saved form configuration to process the image.

POST /api/forms/{form_id}/process

Headers

Name Value
Authorization Bearer YOUR_API_TOKEN
Accept application/json
Content-Type application/json or multipart/form-data

With file upload:

curl --location 'https://formread.org/api/forms/123/process' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'image=@"/path/to/scanned-form.jpg"'

With image URL:

curl --location 'https://formread.org/api/forms/123/process' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{"image_url": "https://example.com/scanned-form.jpg"}'

Response

{
  "success": true,
  "results": {
    "OMR-0-0": "A",
    "OMR-0-1": "C",
    "OMR-0-2": "B,D",
    "OCR-1": "John Smith",
    "BCR-2": "1234567890"
  },
  "omr_details": {
    "OMR-0": {
      "questions": [
        [
          {"left": 0.12, "top": 0.22, "width": 0.02, "height": 0.02, "blackPixelsRatio": 0.72},
          {"left": 0.15, "top": 0.22, "width": 0.02, "height": 0.02, "blackPixelsRatio": 0.15}
        ]
      ]
    }
  },
  "anchor_error": false,
  "processing_time_ms": 450
}

Response Fields

Field Type Descripción
success boolean Whether the processing completed successfully
results object Key-value pairs of area results. Keys are area names (e.g., OMR-0-0, OCR-1, BCR-2)
omr_details object Detailed bubble-level data for OMR areas including positions and fill ratios
anchor_error boolean True if the form sheet could not be aligned (e.g., corners not detected)
processing_time_ms integer Processing time in milliseconds

Image Input Options

You can provide the image in three ways. Use exactly one:

Parámetro Type Descripción
image file File upload (multipart/form-data)
image_url string Public URL to the image
image_base64 string Base64-encoded image data
Note

The form configuration (read areas, thresholds, anchors) is automatically loaded from the form you set up in the FormRead dashboard. You do not need to send any configuration in the request.

Batch Processing

To process multiple images of the same form in one request, pass a comma-separated list of URLs in the image_url field. Results are returned as an array in the same order.

Request

curl --location 'https://formread.org/api/forms/123/process' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{"image_url": "https://example.com/a.jpg,https://example.com/b.jpg,https://example.com/c.jpg"}'

Response

{
  "results": [
    {
      "id": "0",
      "image_url": "https://example.com/a.jpg",
      "success": true,
      "results": { "OMR-0-0": "A", "OCR-1": "John Smith" },
      "anchor_error": false,
      "processing_time_ms": 430
    },
    {
      "id": "1",
      "image_url": "https://example.com/b.jpg",
      "success": true,
      "results": { "OMR-0-0": "B", "OCR-1": "Jane Doe" }
    },
    {
      "id": "2",
      "image_url": "https://example.com/c.jpg",
      "success": false,
      "error": "Failed to fetch image from URL: 404"
    }
  ],
  "total": 3
}

Batch Parameters

Parameter Type Default Description
image_url string One or more public image URLs. Comma-separated for batch mode.
details boolean false Include omr_details (per-bubble positions and fill ratios) in each batch result. Omitted by default to keep responses small.
Batch behavior
  • Batch mode is only available with image_url. File uploads and image_base64 are single-image only.
  • A failed URL does not fail the whole batch — that item gets "success": false and an error field; the rest continue.
  • Results preserve the submitted order via id (0-indexed).
  • omr_details is always returned in single-image mode; in batch mode it requires "details": true.

Batch with omr_details

curl --location 'https://formread.org/api/forms/123/process' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "image_url": "https://example.com/a.jpg,https://example.com/b.jpg",
    "details": true
  }'

Limits

Limit Value Behavior
Requests per minute 60 Per API token. Exceeding returns HTTP 429.
Per-request timeout 60s Requests exceeding 60 seconds are terminated with an error.

A 429 response looks like this:

{
  "message": "Too Many Attempts."
}

A batched request counts as one call regardless of how many URLs it contains.

Sizing batches
  • Per batch: measure processing_time_ms on a sample single-image response, then pack a batch that comfortably finishes under 60 seconds.
  • Across batches: pace requests so you stay under 60 per minute.
  • Image size: downsize client-side to the smallest dimensions that still yield correct results. This is the biggest lever on per-image time.

Supported Area Types

Type Descripción Result Format
OMR Optical Mark Recognition — detects filled bubbles on answer sheets "A", "B,C"
OCR Optical Character Recognition — extracts printed or handwritten text "John Smith"
BCR Barcode/QR Code Recognition — reads barcodes and QR codes "1234567890"

Code Examples

Here are complete examples in Python and JavaScript for processing a form image:

Python

import requests

API_URL = "https://formread.org/api/forms/{form_id}/process"
TOKEN = "YOUR_API_TOKEN"

with open("scanned-form.jpg", "rb") as f:
    response = requests.post(
        API_URL.format(form_id=123),
        headers={
            "Accept": "application/json",
            "Authorization": f"Bearer {TOKEN}",
        },
        files={"image": f},
    )

data = response.json()
print(data["results"])
# {"OMR-0-0": "A", "OMR-0-1": "C", "OCR-1": "John Smith"}

Node.js

const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');

const form = new FormData();
form.append('image', fs.createReadStream('scanned-form.jpg'));

const response = await axios.post(
  'https://formread.org/api/forms/123/process',
  form,
  {
    headers: {
      ...form.getHeaders(),
      'Accept': 'application/json',
      'Authorization': 'Bearer YOUR_API_TOKEN',
    },
  }
);

console.log(response.data.results);
// { 'OMR-0-0': 'A', 'OMR-0-1': 'C', 'OCR-1': 'John Smith' }

Preguntas frecuentes

¿Qué hace la API de procesamiento del lado del servidor?

Envías una imagen de un formulario escaneado con un solo HTTP POST y recibes los resultados estructurados OMR (burbujas), OCR (texto) y BCR (códigos de barras/QR) en JSON — sin navegador ni iframe.

¿Cómo autentico las peticiones?

Pasa tu token de acceso personal como token Bearer en el header Authorization: Authorization: Bearer TU_TOKEN_API. Genera el token desde la sección de tokens de API de tu panel de FormRead.

¿Puedo procesar varias imágenes en una sola petición?

Sí. Pasa una lista de URLs públicas separadas por comas en el campo image_url. Los resultados vuelven en un arreglo respetando el orden de envío, y una URL fallida solo falla su propio elemento — el resto continúa.

¿Cuáles son los límites de tasa y tamaño?

Hasta 60 peticiones por minuto por token de API, con un timeout de procesamiento de 60 segundos por petición. Una petición por lotes cuenta como una sola llamada sin importar cuántas URLs contenga.

¿Necesito enviar la configuración del formulario en cada petición?

No. La configuración del formulario — áreas de lectura, umbrales y anclas — se carga automáticamente desde el formulario que configuraste en el panel de FormRead. Tu petición solo necesita la imagen y el id del formulario en la URL.

¿Listo para probar FormRead?

¡Cree, lea y procese formularios OMR con facilidad. Comience a extraer datos de sus formularios hoy mismo!

No se requiere tarjeta de crédito para comenzar