Guia do Desenvolvedor de Integração da API da Web FormRead

Como funciona a API do FormRead

A API do FormRead é dividida em duas partes: uma API REST para gerenciar formulários (criar, atualizar, excluir e armazenar dados) e um iframe incorporável para edição de formulários e leitura de documentos digitalizados. A API sozinha não processa nem lê formulários — a leitura é feita inteiramente através do iframe.

  • API REST (esta página): Use-a para criar, atualizar, excluir e obter metadados de formulários. A API armazena os dados do seu formulário e retorna os tokens necessários para incorporar o iframe.
  • Iframe (visualizador incorporado): Use-o para editar modelos de formulários, fazer upload de documentos digitalizados e extrair resultados (OMR, OCR, BCR). Toda a leitura de formulários e extração de dados acontece dentro do iframe.
Procurando processamento servidor a servidor?

Se você não precisa de uma interface visual e quer apenas enviar imagens e receber resultados como JSON, confira a API de processamento do lado do servidor.

Fluxo de integração típico
  1. Autentique-se com um token Bearer (gerado a partir do painel).
  2. Use o endpoint POST /api/forms para criar um formulário e obter o iframe_token.
  3. Incorpore o iframe em sua página usando o iframe_token para permitir que os usuários editem formulários e digitalizem documentos.
  4. Escute os eventos do iframe (editForm, getResults, rowResult) para receber os dados do formulário e os resultados extraídos, depois armazene-os em seu sistema.

Autenticação

Para usos corporativos, a API pode ser usada gerando um token Bearer Auth.

Faça login no FormRead painel e acesse a opção API Token:

FormRead dashboard menu with the API Tokens option highlighted

Crie os tokens de API para permitir que serviços de terceiros se autentiquem com nosso aplicativo em seu nome:

Creating a new FormRead API token with permission checkboxes

Copie o token gerado em local seguro (será mostrado apenas uma vez):

The generated FormRead API Bearer token shown once — copy and store it securely

Criar novo formulário

POST /api/forms

Headers

Name Value
Authorization Bearer YOUR_API_TOKEN
Accept application/json

Request

curl --location --request POST 'https://formread.org/api/forms' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'form_name="new form"' \
  --form 'custom_css="{ingest custom css to edit FormRead View}"'

Response

{
  "id": 8,
  "form_name": "new form",
  "iframe_token": "6ifvCyEcjB3D5SGqtFmJ5eg0sPYNQfLoWCEgv7bb",
  "created_at": "2022-02-28T21:22:55.000000Z",
  "updated_at": "2022-02-28T21:22:55.000000Z"
}

A variável custom_css permitirá inserir regras CSS para editar a aparência da visualização FormRead e adicionar texto personalizado, como por exemplo:

#app-title::after{
  content: 'Your Tittle';
  color: white;
}
#app-subtitle::after{
  content: 'Your Custom sub-tittle Your Custom sub-tittle Your Custom sub-tittle';
  color: white;
}
#upload-from-cam{
  display: none;
}
#upload-from-system{
  background: lightblue;
}
#upload-from-csv{
  display: none;
}
#app > div.bg-gray-50.h-screen.overflow-auto > div > div{
  background-color: black;
}

Obter formulário por ID

GET /api/forms/{form_id}

Request

curl --location --request GET 'https://formread.org/api/forms/8' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN'

Response

{
  "id": 8,
  "form_name": "adsf",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2022-02-28T21:22:55.000000Z",
  "updated_at": "2022-03-01T01:40:19.000000Z"
}

Editar um formulário

Depois que um formulário é Criada ou Lido (GET) ele pode ser exibido em um Iframe usando o iframe_token fornecido na resposta (este token varia, portanto, certifique-se de Lido (GET) seu formulário antes de renderizar o iframe)

Crie também um script que escute os eventos do iframe como no exemplo abaixo:

<!DOCTYPE html>
<html style="height: 100%">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body style="height: 100%">

<iframe src="https://formread.org/{lang}/api/forms/{form_id}/edit/{iframe_token}/{read_only}"
        style="height: 100%; width: 100%"></iframe>

<script>
    window.addEventListener('message', function (e) {
        // if (e.origin !== 'https://formread.org') return;

        console.log(e.data.method)

        if (e.data.method === "editForm") {
            let formData = e.data.formData // data used to saved your form
            let schema = JSON.parse(e.data.schema)
            console.log(schema)
            console.log(formData)
        }
        if (e.data.method === "getResults") {
            let results = JSON.parse(e.data.results)
            console.log(results)
        }
        if (e.data.method === "rowResult") {
            let rowResult = JSON.parse(e.data.rowResult)
            console.log(rowResult)
        }
    });
</script>
</body>
</html>

Parâmetros de URL do iframe

Parâmetro Descrição
lang Defina a variável lang para exibir os comandos do aplicativo no idioma desejado. Atualmente, oferecemos suporte para inglês (en), francês (fr), espanhol (es), português brasileiro (pt) ou cazaque (kk)
read_only Variável read_only pode ser definido para 1 para desabilitar a edição de formulário ou 0 para permitir a edição de formulário

Eventos do iframe

Quando os usuários clicam no botão salvar, o <code class="language-plaintext">editarFormulário</code> método será acionado, lá você tem acesso a 2 variáveis:

  • formData variável conterá os atributos de formulário codificados que podem ser enviados usando o Atualizarpara salvar as alterações feitas em seu formulário:
  • o schema variável permitirá que você saiba os campos criados até agora:
    {
      "file_name": {
        "type": "text"
      },
      "BCR-0": {
        "type": "text"
      },
      "OCR-1": {
        "type": "text"
      },
      "OMR-2-0": {
        "type": "select",
        "options": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "questionIndex": "0"
      },
      "OMR-2-1": {
        "type": "select",
        "options": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "questionIndex": "1"
      },
      "OMR-2-2": {
        "type": "select",
        "options": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "questionIndex": "2"
      }
    }

    O schema A variável serve apenas para você exibir alguns alertas para seus usuários, caso você esteja exigindo a criação de campos de área obrigatórios:

Quando um usuário clica nos resultados do download, o getResults método será acionado, lá você obterá os dados do resultado em um JSON formato para que você possa armazená-los em seu sistema

Além disso, você pode obter os resultados linha por linha com o rowResult método, que será acionado toda vez que uma página for processada

Atualizar formulário

PUT /api/forms/{form_id}

Request

curl --location --request POST 'https://formread.org/api/forms/8?_method=PUT' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'form_data="eyJ2dWV4X3N0YXRlIjp7ImZvcm1OYW1lIjoiYWRzZiIsImZvcm1zIjp7f
                     Swic2VsZWN0ZWRGb3JtSWQiOiIiLCJmb3JtUmVhZEFyZWFzIjp7IkJDUi
                     0wIjp7ImNvbHVtblBvc2l0aW9uIjoxLCJ3aWR0aCI6MC4xMTQ5NTA0NTM
                     0MDUzNTE2NCwiaGVpZ2h0IjowL...' \
  --form 'custom_css="{ingest custom css to edit FormRead View}"'

Response

{
  "id": 8,
  "form_name": "adsf",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2022-02-28T21:22:55.000000Z",
  "updated_at": "2022-03-01T02:30:14.000000Z"
}

Excluir formulário

DELETE /api/forms/{form_id}

Request

curl --location --request DELETE 'https://formread.org/api/forms/8' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN'

Response

1

Exemplo completo: integrando o fluxo de correção

Aqui está um exemplo de ponta a ponta mostrando como um professor pode desenhar um formulário, digitalizar provas e enviar os resultados corrigidos para o seu próprio backend — tudo a partir de uma única página que integra o iframe do FormRead.

Cenário

Um professor abre seu aplicativo, desenha uma folha de respostas "Matemática 101 - Prova parcial", imprime, digitaliza as provas preenchidas e clica em "Baixar resultados". Sua página escuta os eventos do iframe, envia o layout e as respostas corrigidas ao seu próprio backend, que então as encaminha para o FormRead.

Passo 1 — Criar o formulário pelo seu servidor

No seu backend, crie um formulário para o professor. Você recebe um id e um iframe_token — são os valores que você passará para a URL do iframe no próximo passo.

# From YOUR backend (never from the browser)
curl --location --request POST 'https://formread.org/api/forms' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'form_name="Math 101 - Midterm"'
{
  "id": 42,
  "form_name": "Math 101 - Midterm",
  "iframe_token": "6ifvCyEcjB3D5SGqtFmJ5eg0sPYNQfLoWCEgv7bb",
  "created_at": "2026-04-20T10:00:00.000000Z",
  "updated_at": "2026-04-20T10:00:00.000000Z"
}

Salve o id e o iframe_token junto ao registro do professor no seu próprio banco de dados. Você os usará para renderizar o iframe no modo de edição no passo 2.

Passo 2 — Abrir o iframe em modo de edição

Seu backend renderiza uma página contendo o iframe do FormRead com read_only=0, para que o professor possa desenhar as bolhas OMR, as áreas OCR e os códigos de barras na folha. Quando ele clica em "Salvar" dentro do iframe, o evento editForm é disparado — o navegador encaminha o formData bruto para o seu próprio backend. O navegador nunca chama o FormRead diretamente.

<!-- /design-form page rendered by YOUR backend.
     read_only = 0 → editable mode -->
<iframe id="formread-frame"
        src="https://formread.org/en/api/forms/42/edit/6ifvCyEcjB3D5SGqtFmJ5eg0sPYNQfLoWCEgv7bb/0"
        style="width:100%; height:100vh; border:0"></iframe>

<script>
    // The browser ONLY talks to your own backend. Never to FormRead.
    const FORM_ID = 42;

    window.addEventListener('message', async function (e) {
        if (e.origin !== 'https://formread.org') return;

        // Teacher clicked "Save" inside the iframe
        if (e.data.method === 'editForm') {
            await fetch(`/api/forms/${FORM_ID}/layout`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ form_data: e.data.formData })
            });
        }
    });
</script>

Passo 3 — Persistir o layout pelo seu backend

Seu backend recebe a string formData e a encaminha ao FormRead via PUT, usando o seu token Bearer (que nunca sai do servidor). É isso que salva permanentemente a configuração do formulário para que o mesmo possa ser reutilizado depois na digitalização das provas.

# Inside your backend handler for POST /api/forms/42/layout
# $formData is the raw string your browser posted.
curl --location --request POST 'https://formread.org/api/forms/42?_method=PUT' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form "form_data=${formData}"
{
  "id": 42,
  "form_name": "Math 101 - Midterm",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2026-04-20T10:00:00.000000Z",
  "updated_at": "2026-04-20T10:15:42.000000Z"
}
O iframe_token muda a cada atualização

Cada atualização de um formulário retorna um novo iframe_token. Sempre busque o mais recente pelo seu backend pouco antes de renderizar o iframe — não o fixe no código nem o armazene em cache por muito tempo.

Passo 4 — Obter o iframe_token atual

Mais tarde, quando o professor estiver pronto para digitalizar as provas, seu backend consulta o formulário por id para obter o iframe_token mais recente.

# From YOUR backend, right before rendering the scan page
curl --location --request GET 'https://formread.org/api/forms/42' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN'
{
  "id": 42,
  "form_name": "Math 101 - Midterm",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2026-04-20T10:00:00.000000Z",
  "updated_at": "2026-04-20T10:15:42.000000Z"
}

Passo 5 — Reabrir o iframe em modo somente leitura para digitalizar

Renderize o iframe novamente — desta vez com read_only=1 no final da URL. O professor não pode mais editar o layout, apenas enviar digitalizações. O navegador encaminha rowResult (progresso por folha) e getResults (download final) para o seu backend.

<!-- /scan-exams page. Note read_only = 1 at the end of the URL. -->
<iframe id="formread-frame"
        src="https://formread.org/en/api/forms/42/edit/po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6/1"
        style="width:100%; height:100vh; border:0"></iframe>

<script>
    const FORM_ID = 42;

    window.addEventListener('message', async function (e) {
        if (e.origin !== 'https://formread.org') return;

        // Live progress while each sheet is processed
        if (e.data.method === 'rowResult') {
            const row = JSON.parse(e.data.rowResult);
            console.log('Processed', row.file_name);
        }

        // Teacher clicked "Download results"
        if (e.data.method === 'getResults') {
            const results = JSON.parse(e.data.results);

            await fetch('/api/grades/bulk', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ form_id: FORM_ID, results })
            });
        }
    });
</script>

Passo 6 — Tratar os resultados no seu backend

O evento getResults entrega um array com uma entrada por prova processada. As chaves seguem o padrão {TipoÁrea}-{ÍndiceÁrea}[-{ÍndicePergunta}]. Abaixo está o que o navegador enviaria para o seu endpoint /api/grades/bulk:

[
  {
    "file_name": "student_001.jpg",
    "BCR-0": "20260420-001",
    "OCR-1": "Alice Johnson",
    "OMR-2-0": "3",
    "OMR-2-1": "7",
    "OMR-2-2": "9"
  },
  {
    "file_name": "student_002.jpg",
    "BCR-0": "20260420-002",
    "OCR-1": "Ben Carter",
    "OMR-2-0": "3",
    "OMR-2-1": "6",
    "OMR-2-2": "9"
  }
]
Mantenha o token no servidor

Nunca exponha seu token Bearer em código visível no navegador. Todas as chamadas de criação, atualização e leitura à API do FormRead passam pelo seu próprio backend — o navegador só vê o iframe_token, que é restrito a um único formulário.

Perguntas frequentes

O que é a API de integração por iframe do FormRead?

É uma API REST somada a um iframe integrável. Seu backend gerencia os formulários pelos endpoints REST; o iframe é exibido dentro do seu aplicativo web para que os usuários possam desenhar formulários, enviar digitalizações e conferir resultados sem sair da sua interface.

O iframe_token expira ou muda?

O iframe_token é regenerado sempre que o formulário é atualizado. Busque sempre o valor mais recente pelo seu backend (GET /api/forms/{id}) imediatamente antes de renderizar o iframe — não o armazene em cache por muito tempo.

Qual a diferença entre read_only=0 e read_only=1?

read_only=0 abre o iframe no modo de edição para que o usuário desenhe o formulário (colocando bolhas OMR, áreas OCR e códigos de barras). read_only=1 o abre apenas no modo de digitalização — o usuário pode enviar folhas preenchidas e baixar os resultados, mas não pode alterar o layout.

Posso manter meu token de API no navegador?

Não. O token Bearer deve permanecer no seu servidor. Todas as chamadas de criação, atualização e leitura à API REST do FormRead devem passar pelo seu próprio backend. O navegador só precisa do iframe_token, que é restrito a um único formulário.

Como recebo os resultados digitalizados?

O iframe envia mensagens com window.postMessage. Escute method="getResults" para receber o array completo de resultados (uma entrada por folha digitalizada) e method="rowResult" para mostrar o progresso por folha durante a digitalização.

Link da coleção do postman

Abrir a coleção do Postman

Pronto para Experimentar o FormRead?

Crie, leia e processe formulários OMR com facilidade. Comece a extrair dados de seus formulários hoje mesmo!

Nenhum cartão de crédito necessário para começar