Pular para o conteúdo principal

API de Correção de Redação (ENEM)

API REST do Workfuse para enviar redações e receber a correção no padrão ENEM (5 competências, nota 0–1000, comentários e marcações de gramática). A correção é assíncrona: você envia a redação, recebe um id, e consulta o resultado (ou recebe um webhook quando ficar pronta).

Documentação interativa (Swagger)

Explore e teste os endpoints direto no navegador: API_BASE/public/v1/doc. O contrato OpenAPI cru está em API_BASE/public/v1/openapi.

API_BASE é a URL da API Workfuse do seu ambiente (ex.: https://api.workfuse.com). Todos os caminhos abaixo são relativos a API_BASE/public/v1/correction.

Autenticação

Toda requisição usa uma API key no header Authorization, no formato Bearer:

Authorization: Bearer wf_sua_chave_aqui

A chave é gerada no painel (Configurações → API Keys), tem escopo por módulo (precisa do módulo correction) e identifica a sua instituição — você só acessa as redações enviadas com a sua chave. Detalhes em Autenticação.

Enviar uma redação

POST /essays

curl -X POST "API_BASE/public/v1/correction/essays" \
-H "Authorization: Bearer wf_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{
"userId": "aluno-123",
"proposedTheme": "Os desafios da mobilidade urbana no Brasil",
"content": "Texto completo da redação do aluno...",
"motivationalTexts": [
{ "title": "Texto motivador 1", "content": "..." }
],
"externalId": "redacao-42"
}'
CampoTipoObrigatórioDescrição
userIdstringsimId do aluno no seu sistema (você correlaciona).
proposedThemestringsimTema proposto da redação.
contentstringsimTexto da redação (até 50.000 caracteres).
motivationalTextsarraysimTextos motivadores: { title, content?, images? }. Pode ser [].
titlestringnãoTítulo da redação.
externalIdstringnãoSeu id de referência (eco na consulta).

Resposta 201 — a correção foi enfileirada:

{ "id": "clz...", "processStatus": "PENDING" }

Guarde o id para consultar o resultado.

Código executável (Node, sem dependências): submit-essay — envia a redação e faz polling até concluir.

Consultar uma redação

GET /essays/:id

curl "API_BASE/public/v1/correction/essays/clz..." \
-H "Authorization: Bearer wf_sua_chave_aqui"

Enquanto processa, enemFeedback vem null. Quando conclui (processStatus: SUCCESS), vem a correção completa:

{
"id": "clz...",
"userId": "aluno-123",
"externalId": "redacao-42",
"proposedTheme": "Os desafios da mobilidade urbana no Brasil",
"content": "Texto completo...",
"contentWithGrammarFeedback": "Texto com <span data-content=\"...\">marcações</span>...",
"status": "DONE",
"processStatus": "SUCCESS",
"processErrorMessage": null,
"enemFeedback": {
"competence1Score": 160, "competence1Comment": "...",
"competence2Score": 120, "competence2Comment": "...",
"competence3Score": 160, "competence3Comment": "...",
"competence4Score": 160, "competence4Comment": "...",
"competence5Score": 120, "competence5Comment": "...",
"overallScore": 720,
"overallComment": "...",
"isScoreZeroed": false,
"preliminaryCheckComment": null,
"grammarFeedback": [
{
"message": "Esta conjunção deve ser separada por vírgula.",
"shortMessage": "Separe com vírgulas",
"replacements": ["presentes, mas"],
"offset": 43,
"length": 13
}
]
},
"createdAt": "2026-06-10T20:24:05.734Z",
"updatedAt": "2026-06-10T20:25:12.132Z"
}

Notas do enemFeedback:

  • Cada competência (C1–C5) tem nota (0/40/80/120/160/200) + comentário; overallScore é a soma (0–1000).
  • isScoreZeroed: true quando a redação foi zerada (fuga ao tema, gênero incorreto, etc.) — preliminaryCheckComment explica.
  • contentWithGrammarFeedback é o texto com marcações de gramática em HTML (<span data-content="...">); grammarFeedback[] traz os mesmos itens com offset/length sobre o texto cru.

Listar redações

GET /essays — paginado, escopado à instituição da sua chave.

curl "API_BASE/public/v1/correction/essays?page=1&pageSize=20" \
-H "Authorization: Bearer wf_sua_chave_aqui"
{ "data": [ { "id": "clz...", "processStatus": "SUCCESS", "...": "..." } ],
"pagination": { "page": 1, "pageSize": 20, "pages": 3, "items": 47 } }

Ciclo de vida (processStatus)

PENDING → PROCESSING → SUCCESS
↘ ERROR (processErrorMessage explica)

status é o estado de alto nível para o aluno: SENT (enviada) → DONE (corrigida).

Receber o resultado por webhook

Em vez de fazer polling no GET, registre um webhook (no painel) para receber um POST assinado quando a correção concluir (essay.corrected) ou falhar (essay.failed). Veja Webhooks — exemplo de receiver: nodejs-webhook.

Erros

HTTPQuando
400Corpo inválido (campo faltando / fora do limite).
401API key ausente ou inválida.
403A chave não tem o módulo correction no escopo.
404Redação não encontrada (ou de outra instituição).
500Erro interno.