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.
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.
- Autentique-se com um token Bearer (gerado a partir do painel).
- Use o endpoint
POST /api/formspara criar um formulário e obter oiframe_token. - Incorpore o iframe em sua página usando o
iframe_tokenpara permitir que os usuários editem formulários e digitalizem documentos. - 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:
Crie os tokens de API para permitir que serviços de terceiros se autentiquem com nosso aplicativo em seu nome:
Copie o token gerado em local seguro (será mostrado apenas uma vez):
Criar novo formulário
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
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:
formDatavariá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
schemavariá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
schemaA 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
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
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.
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"
}
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"
}
]
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
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