Pular para o conteúdo principal

Dispensa de disciplinas

A análise de dispensa recebe os documentos acadêmicos de um aluno — histórico escolar, ementas das disciplinas cursadas na instituição de origem e o plano de ensino do curso de destino — e devolve, para cada disciplina do destino, se ela pode ser dispensada, por qual disciplina de origem (ou combinação delas), com score de similaridade, motivo de recusa e justificativa.

A análise é assíncrona: o POST devolve a análise criada e o resultado chega depois, por consulta (GET) ou por webhook.

Rotas​

método e rotao que faz
POST /v1/api/credit-transfer-analysesinicia uma análise avulsa, com os arquivos enviados na própria requisição
GET /v1/api/credit-transfer-analyseslista as análises da empresa, mais recentes primeiro
GET /v1/api/credit-transfer-analyses/{creditTransferAnalysisId}status e, quando concluída, o resultado
GET /v1/api/credit-transfer-analyses/{creditTransferAnalysisId}/spreadsheetURL da planilha (.xlsx) do resultado
POST /v1/api/competencies/{competencyId}/participants/{participantId}/credit-transfer-analysesinicia a análise de um participante de projeto, com os documentos que ele já enviou

Todas exigem a x-api-key (ver Autenticação).

Antes do primeiro envio​

A dispensa de disciplinas precisa estar habilitada para a sua empresa. Sem isso, os dois POST respondem 403 com context: "FEATURE_NOT_ENABLED". Peça a habilitação ao seu contato na Dynadok.

Há dois jeitos de usar:

  • Avulsa — você envia os arquivos direto na requisição. Não precisa de projeto, competência nem participante. É o caminho mais curto para integrar.
  • Por participante — os documentos já foram enviados pelo aluno (ou por você) nos slots de uma competência configurada para a dispensa. Ver Análise de um participante.

Os três papéis de documento​

papel (role)documentoquantos
HISTORIChistórico escolar da instituição de origem1 ou mais
ORIGIN_SYLLABUSementas / planos de ensino das disciplinas cursadas na origem1 ou mais
DESTINATION_SYLLABUSplano de ensino (ou matriz) do curso de destinoexatamente 1

Os três papéis são obrigatórios em toda análise.

Iniciar uma análise avulsa​

Requisição multipart/form-data:

campoobrigatórioconteúdo
filessimos arquivos, PDF ou imagem; até 30 por análise e 20 MB por arquivo
rolessimo papel de cada arquivo, na mesma ordem de files — repita o campo uma vez por arquivo, ou envie um único campo com um array JSON (["HISTORIC","ORIGIN_SYLLABUS","DESTINATION_SYLLABUS"])
parametersnãoobjeto JSON com os parâmetros da análise (ver abaixo); o que for omitido usa o padrão
externalIdnãoseu identificador para esta análise (até 200 caracteres), filtrável na listagem

E um header opcional:

headerconteúdo
Idempotency-Keyaté 255 caracteres. Repetir a requisição com a mesma chave devolve a análise criada na primeira vez, sem criar outra nem reprocessar — inclusive quando as duas chegam ao mesmo tempo. Use em todo retry do seu lado.
curl --request POST 'https://api.dynadok.com/v1/api/credit-transfer-analyses' \
--header 'x-api-key: 550e8400-e29b-41d4-a716-446655440000.SUA_CHAVE' \
--header 'Idempotency-Key: matricula-2026-0001' \
--form 'files=@"/caminho/historico.pdf"' \
--form 'roles="HISTORIC"' \
--form 'files=@"/caminho/ementas-origem.pdf"' \
--form 'roles="ORIGIN_SYLLABUS"' \
--form 'files=@"/caminho/matriz-destino.pdf"' \
--form 'roles="DESTINATION_SYLLABUS"' \
--form 'parameters="{\"minScore\":80,\"allowCombination\":true}"' \
--form 'externalId="matricula-2026-0001"'

A resposta traz a análise já criada, normalmente em PROCESSING, com subjects: null. Guarde o _id para consultar depois.

Parâmetros​

parâmetropadrãofaixaefeito
minScore751–100score mínimo de similaridade de conteúdo para aprovar a equivalência
creditHoursTolerance600–100 ou nulla carga horária de origem (ou a soma, numa combinação) precisa ser pelo menos esse percentual da carga horária de destino. null desliga a regra de carga horária
complexityNORMALNORMAL | HIGHmodo de comparação usado pelo motor de análise
allowCombinationfalsebooleanopermite dispensar uma disciplina de destino pela soma de várias disciplinas de origem
minScoreToDisplay500–100equivalências recusadas com score abaixo disso não aparecem no resultado. Equivalência aprovada aparece sempre

Os parâmetros efetivos de cada análise voltam em parameters na resposta.

Acompanhar a análise​

Status​

statussignificado
PENDING_DOCUMENTSsó na análise por participante: algum documento ainda está em processamento; a análise começa sozinha quando ele terminar
QUEUEDcriada, aguardando envio ao motor de análise
PROCESSINGem análise
COMPLETEDconcluída; subjects e summary preenchidos
FAILEDnão concluiu; o motivo está em failure

Análise que fica mais de 3 horas em QUEUED/PROCESSING, ou mais de 24 horas em PENDING_DOCUMENTS, é encerrada como FAILED.

Prefira o webhook ao polling. Se fizer polling, use um intervalo de dezenas de segundos — a análise leva minutos, não segundos.

Consultar​

curl 'https://api.dynadok.com/v1/api/credit-transfer-analyses/6500a1b2c3d4e5f600000010' \
--header 'x-api-key: 550e8400-e29b-41d4-a716-446655440000.SUA_CHAVE'

Exemplo de análise concluída (valores ilustrativos):

{
"code": 200,
"message": "OK",
"timestamp": 1761148800000,
"data": {
"_id": "6500a1b2c3d4e5f600000010",
"status": "COMPLETED",
"source": "API_STANDALONE",
"trigger": "API",
"externalId": "matricula-2026-0001",
"competencyParticipantId": null,
"destinationCompetencyDocumentId": null,
"parameters": {
"minScore": 80,
"creditHoursTolerance": 60,
"complexity": "NORMAL",
"allowCombination": true,
"minScoreToDisplay": 50
},
"summary": { "destinationSubjects": 2, "exempted": 1, "exemptedByCombination": 0 },
"failure": null,
"createdAt": "2026-10-22T15:00:00.000Z",
"updatedAt": "2026-10-22T15:06:10.000Z",
"startedAt": "2026-10-22T15:00:02.000Z",
"completedAt": "2026-10-22T15:06:10.000Z",
"outdatedAt": null,
"subjects": [
{
"name": "Cálculo I",
"period": 1,
"workloadHours": 80,
"mandatoryPractice": false,
"exempted": true,
"exemptedBy": "EQUIVALENCE",
"equivalences": [
{
"originSubject": {
"name": "Cálculo Diferencial e Integral I",
"period": 1,
"workloadHours": 72,
"institution": "Universidade de Origem",
"course": "Engenharia Civil"
},
"score": 92,
"approved": true,
"rejectionReason": null,
"justification": "Conteúdo programático equivalente: limites, derivadas e integrais."
}
],
"combination": null
},
{
"name": "Física Experimental",
"period": 2,
"workloadHours": 60,
"mandatoryPractice": true,
"exempted": false,
"exemptedBy": null,
"equivalences": [
{
"originSubject": {
"name": "Física Geral",
"period": 2,
"workloadHours": 30,
"institution": "Universidade de Origem",
"course": "Engenharia Civil"
},
"score": 81,
"approved": false,
"rejectionReason": "CREDIT_HOURS",
"justification": "Conteúdo compatível, mas carga horária insuficiente."
}
],
"combination": null
}
]
}
}

Como ler o resultado​

  • summary resume: quantas disciplinas de destino (destinationSubjects), quantas dispensadas (exempted) e quantas delas por combinação (exemptedByCombination).
  • Cada item de subjects é uma disciplina do destino. exempted diz se ela foi dispensada; exemptedBy diz como: EQUIVALENCE (uma disciplina de origem equivale) ou COMBINATION (várias somadas, só com allowCombination: true).
  • equivalences lista as disciplinas de origem comparadas, com score (0–100), approved, justification e, quando recusada, rejectionReason.
  • combination, quando houve tentativa de combinação, traz originSubjects, score, approved e rejectionReason do conjunto.
  • mandatoryPractice: true indica disciplina de prática obrigatória no destino.
  • Campos que o motor não conseguiu extrair do documento vêm null (nome, período, carga horária, instituição, curso).
rejectionReasonsignificado
CONTENTconteúdo insuficiente: score abaixo de minScore
CREDIT_HOURScarga horária de origem abaixo de creditHoursTolerance
ORIGIN_ALREADY_USEDa disciplina de origem já foi usada para dispensar outra
REUSE_LIMITatingido o limite de reaproveitamento da disciplina de origem

Falha​

Em FAILED, failure traz code e uma message em português, pronta para exibir:

failure.codesignificado
UNREADABLE_FILEalgum arquivo não pôde ser lido
MULTIPLE_DOCUMENTS_IN_FILEum arquivo contém mais de um documento
PROCESSING_ERRORfalha no processamento ou prazo esgotado — tente de novo

Planilha​

curl 'https://api.dynadok.com/v1/api/credit-transfer-analyses/6500a1b2c3d4e5f600000010/spreadsheet' \
--header 'x-api-key: 550e8400-e29b-41d4-a716-446655440000.SUA_CHAVE'
{
"code": 200,
"message": "OK",
"timestamp": 1761148800000,
"data": {
"url": "https://...",
"expiresAt": "2026-10-29T15:10:00.000Z"
}
}

A planilha é gerada na primeira chamada e reaproveitada nas seguintes. A url é assinada e vale 7 dias (expiresAt); depois disso, chame a rota de novo para obter outra. Antes de a análise concluir, a rota responde 409 com context: "ANALYSIS_NOT_COMPLETED".

Listar análises​

GET /v1/api/credit-transfer-analyses pagina com page e perPage (máx. 100), mais recentes primeiro, com filtros opcionais externalId, status e competencyParticipantId. Cada item traz o mesmo objeto da consulta sem subjects — use summary para a visão geral e consulte por id para o detalhe. O formato da paginação está em Envelope e erros.

curl 'https://api.dynadok.com/v1/api/credit-transfer-analyses?externalId=matricula-2026-0001' \
--header 'x-api-key: 550e8400-e29b-41d4-a716-446655440000.SUA_CHAVE'

Webhook​

Ao terminar, a análise dispara um evento para os webhooks da empresa:

eventoquando
CREDIT_TRANSFER_ANALYSIS_COMPLETEDanálise concluída (status: COMPLETED)
CREDIT_TRANSFER_ANALYSIS_FAILEDanálise falhou (status: FAILED)

data é o mesmo objeto de GET /v1/api/credit-transfer-analyses/{id}:

{
"event": "CREDIT_TRANSFER_ANALYSIS_COMPLETED",
"data": { "_id": "6500a1b2c3d4e5f600000010", "status": "COMPLETED", "externalId": "matricula-2026-0001", "subjects": [] }
}
Análise avulsa só chega em webhook da empresa toda

A análise avulsa não pertence a projeto nenhum. Um webhook restrito a projetos nunca recebe esses eventos dela, sem erro nem aviso. Configure um webhook sem restrição de projeto. A análise por participante chega tanto no webhook da empresa toda quanto no restrito ao projeto do participante.

Leia Webhooks antes de implementar o endpoint: uma resposta 4xx/5xx do seu lado não gera reenvio.

Análise de um participante​

Quando o aluno é um participante de projeto, a competência pode ser configurada para a dispensa: cada slot de documento recebe um papel (histórico, plano de ensino de origem ou de destino), e os parâmetros da análise ficam no slot do plano de ensino de destino. Essa configuração é feita na plataforma.

Com o slot de destino em modo automático (o padrão), a análise começa sozinha quando o plano de ensino de destino termina de processar — não é preciso chamar a API. O gatilho é só o documento de destino: se nesse momento ainda faltar histórico ou ementa de origem, a análise não começa e nada é avisado. Envie o plano de destino por último ou, se ele chegou antes dos outros, inicie pela rota abaixo — que também serve para o modo manual e para refazer a análise:

curl --request POST 'https://api.dynadok.com/v1/api/competencies/6500a1b2c3d4e5f600000001/participants/6500a1b2c3d4e5f600000002/credit-transfer-analyses' \
--header 'x-api-key: 550e8400-e29b-41d4-a716-446655440000.SUA_CHAVE' \
--header 'Content-Type: application/json' \
--data '{}'

O corpo aceita competencyDocumentId (opcional): o slot do plano de ensino de destino a usar. Só é obrigatório quando a competência tem mais de um slot de destino.

  • Se algum documento ainda está em processamento, a análise fica em PENDING_DOCUMENTS e começa quando ele terminar.
  • Só existe uma análise em andamento por participante e slot de destino; pedir outra responde 409 (ANALYSIS_ALREADY_RUNNING, com o id da análise em extraData.creditTransferAnalysisId).
  • Se o participante reenviar um documento depois da análise, ela ganha outdatedAt preenchido. Reenvio do plano de destino em modo automático dispara uma análise nova (se houver uma em andamento, a nova começa quando ela terminar). Reenvio de histórico ou ementa de origem só marca a análise como desatualizada — refaça pela rota acima.

Para filtrar as análises de um participante, use GET /v1/api/credit-transfer-analyses?competencyParticipantId=....

Erros típicos​

O envelope de erro está em Envelope e erros; o context identifica o caso.

statuscontextquando
403FEATURE_NOT_ENABLEDdispensa não habilitada para a empresa
400ROLES_FILES_MISMATCHquantidade de roles diferente da de files
400TOO_MANY_FILESmais de 30 arquivos
400MISSING_REQUIRED_DOCUMENTSfalta algum dos três papéis; extraData.missingRoles lista quais
400MULTIPLE_DESTINATION_SYLLABUSmais de um DESTINATION_SYLLABUS
400UNSUPPORTED_FILE_TYPEarquivo que não é PDF nem imagem
400UNREADABLE_FILEarquivo que não pôde ser lido; extraData.fileName diz qual
400INVALID_MULTIPART_FIELDroles ou parameters em formato inválido; extraData.field diz qual
400INVALID_DESTINATION_SLOT / DESTINATION_SLOT_REQUIREDpor participante: slot de destino inválido ou não informado quando há mais de um
404—análise, competência ou participante inexistente
409ANALYSIS_ALREADY_RUNNINGpor participante: já há análise em andamento
409ANALYSIS_NOT_COMPLETEDplanilha pedida antes de a análise concluir