Pular para o conteúdo principal

Referência

O que você consulta enquanto integra. O caminho, com exemplos, está nos guias: Montar a página de inscrição, Consultar a situação e Portal de prova.

Endpoints​

Base API_BASE/public/v1/admissions, com a chave em Authorization: Bearer wf_.... A chave fixa a instituição: nenhum endpoint recebe organização ou instituição. Todo endpoint pode responder 401 e 403 (Erros); abaixo estão só os erros próprios de cada um.

GET /institution​

A instituição da chave: name, slug, website, logoUrl e primaryColor. Os três últimos podem vir null.

GET /courses​

O catálogo. Só entra curso ativo com matriz vigente. Cada curso traz id, name, area, description, degree, modalities[], curriculums[] (id, modality, workloadHours, durationTerms, termUnit) e hasOpenNotice.

GET /courses/{courseId}​

O curso (id, name, area, description, degree) com blocks[], um por matriz vigente (em geral, uma por modalidade): curriculumId, modality, workloadHours, durationTerms, termUnit e o admissionNoticeId do edital aberto, ou null.

Erros: 404 ADMISSION_NOT_FOUND.

GET /curriculums/{curriculumId}​

A matriz: id, version, modality, courseId, courseName e terms[], cada período com term, termLabel e disciplines[] (id, name, code, module, workloadHours). Responde mesmo sem edital aberto.

Erros: 404 ADMISSION_NOT_FOUND.

O que ?origem= aponta: destination, refusal e origin (Origem e links). Nunca responde erro: link inexistente, inativo ou vencido volta 200, com o motivo em refusal.

GET /notices/{noticeId}/showcase​

O que o edital oferece: applicationFeeAmount, offers[] (id, courseId, campusId, courseName, courseDegree, courseModality, campusName, campusCity, campusState) e journeys[], as formas de ingresso ativas no edital (id, entryFormName, evaluationType, examRequired, chargesFee, examPeriodEnded).

Erros: 404 ADMISSION_NOT_FOUND (edital inexistente, em rascunho ou de outra instituição) · 422 CANDIDACY_NOTICE_NOT_ACCEPTING (fora da janela de inscrição).

GET /notices/{noticeId}/application-fields​

Query journey, obrigatória: o journeys[].id da vitrine. Devolve fields[] e enrollmentDocuments[] (Os campos do formulário).

Erros: 404 ADMISSION_NOT_FOUND · 422 CANDIDACY_NOTICE_NOT_ACCEPTING.

GET /postal-codes/{cep}​

O endereço de um CEP de 8 dígitos, com ou sem hífen: street, district, city e state.

Erros: 404 ADMISSION_NOT_FOUND (CEP inexistente, ou a consulta fora do ar).

POST /applications/draft​

Grava a inscrição como rascunho. Corpo: o corpo do envio, com a forma de ingresso, o aceite e o par CPF + nascimento opcionais. Devolve a inscrição curta, mais rejoined (true quando a chamada gravou num rascunho que já existia, o do token ou o do CPF; false quando criou um) e draftToken (O rascunho sem CPF).

Erros: 404 CANDIDACY_NOTICE_NOT_FOUND · 409 CANDIDACY_NOT_EDITABLE, CANDIDACY_DRAFT_GONE · 422 CANDIDACY_NOTICE_NOT_ACCEPTING, CANDIDACY_ENTRY_FORM_NOT_AVAILABLE, CANDIDACY_IDENTITY_MISMATCH.

POST /applications​

Conclui a inscrição em uma chamada. Mesmo corpo, com a forma de ingresso, o CPF, o nascimento e o dataConsentAt obrigatórios. Devolve a inscrição curta. Nos dois POST, edital ainda em rascunho responde 422 CANDIDACY_NOTICE_NOT_ACCEPTING, com as datas nulas.

Erros: 404 CANDIDACY_NOTICE_NOT_FOUND · 409 CANDIDACY_NOT_EDITABLE, EXAM_PERIOD_ENDED, CANDIDACY_CUTOFF_MISSING · 422 CANDIDACY_NOTICE_NOT_ACCEPTING, CANDIDACY_CONSENT_REQUIRED, CANDIDACY_ENTRY_FORM_NOT_AVAILABLE, CANDIDACY_IDENTITY_MISMATCH, CANDIDACY_MISSING_ANSWERS, ENEM_SCORE_INVALID.

GET /applications/{id}​

A inscrição inteira, pelo número que o envio devolveu.

Erros: 404 CANDIDACY_NOT_FOUND, também para o rascunho que ainda não tem CPF.

GET /applications​

As inscrições de uma pessoa na instituição, em { "data": [...] }, da alterada mais recentemente para a mais antiga. Cada linha é a inscrição com journey e timeline vazias.

Query
candidateCpf11 dígitos, com os verificadores corretos
candidateEmailcomparado inteiro, sem diferenciar maiúsculas. Pode trazer pessoas diferentes que usam o mesmo e-mail
admissionNoticeIdopcional; estreita para um edital

Informe candidateCpf ou candidateEmail, nunca os dois. Sem inscrição, { "data": [] }. O rascunho sem CPF não aparece.

Erros: 400 (nenhum dos dois, os dois juntos, ou um deles inválido).

GET /exam-candidates​

Quem pode fazer a prova: inscrições em avaliação, no vestibular com prova exigida e com tentativa restante, de editais abertos ou encerrados. Query admissionNoticeId, opcional. Cada linha traz applicationId, candidateName, candidateCpf, candidateEmail, admissionNotice (id, name), entryFormName, courseName, attemptsUsed e attemptLimit. Nunca traz a nota.

POST /applications/{id}/exam-attempts​

A nota de uma tentativa. Corpo: attemptNumber (inteiro de 1 a 2147483647) e score (0 a 10, até duas casas). Devolve applicationId, outcome (APPLIED · DUPLICATE · DISCARDED), status, attemptsUsed e attemptLimit. A ordem das respostas está em Portal de prova.

Erros: 404 CANDIDACY_NOT_FOUND · 409 CANDIDACY_NOT_UNDER_REVIEW, EXAM_NOT_REQUIRED · 422 SCORE_OUT_OF_SCALE, SCORE_PRECISION_EXCEEDED.

Corpo do envio​

Vale para POST /applications e para POST /applications/draft.

CampoTipoObrigatórioDescrição
admissionNoticeIdstringsimo edital
admissionOfferIdstringsima oferta escolhida, que carrega curso e polo
admissionNoticeEntryFormIdstringno envioa forma de ingresso (journeys[].id da vitrine)
candidateNamestringsimnome completo, até 200 caracteres
candidateEmailstringsime-mail, até 254 caracteres
candidatePhonestringsimtelefone, até 32 caracteres. Não normalizamos: com ou sem máscara, com ou sem +55, ele volta como foi enviado
candidateCpfstringno enviosó dígitos, 11 posições, com os verificadores corretos. No rascunho pode faltar, junto com candidateBirthDate
candidateBirthDatedatano envioAAAA-MM-DD, ou data e hora ISO com fuso (Z ou ±hh:mm), e vale o dia escrito. Não futura, não antes de 1900, de quem tem 14 anos ou mais. Vem junto com o CPF: um sem o outro responde 400
dataConsentAtdatano envioquando o candidato aceitou o tratamento de dados. Sem ele, o envio responde 422
secondChoiceOfferIdstringnãoa 2ª opção de curso, quando o edital a oferece
formAnswersobjetonãoas respostas, com a fieldKey como chave (Os campos do formulário)
captureLinkIdstringnãoo link de captação por onde a pessoa chegou
captureOriginIdstringnãoa origem, quando o endereço nomeou uma sem link salvo
draftTokenstringnãoa chave do rascunho ainda sem CPF, que o POST /applications/draft devolveu

O rascunho sem CPF e o draftToken​

O primeiro passo da página da Workfuse pede só nome, celular, e-mail e curso, e já grava o rascunho: é o que deixa a instituição falar com quem começou e não terminou. Sem CPF não há chave natural, então a resposta traz um draftToken.

RegraO que significa para você
guarde o draftToken na sessão do seu site e mande-o em toda chamada seguintesem ele, cada chamada abre um rascunho novo
ele vale até o CPF chegara chamada que traz CPF e nascimento devolve draftToken: null; daí em diante a chave é edital + CPF. Não reenvie o token velho numa chamada sem CPF: ela abre um rascunho novo
o CPF já tem inscrição neste editalcom o nascimento conferindo, a chamada cai nela, e o rascunho do token deixa de existir. Com o nascimento errado, 422 CANDIDACY_IDENTITY_MISMATCH, e o rascunho continua
o rascunho sem CPF não é consultávelGET /applications/{id} responde 404 e a busca por CPF ou e-mail não o acha. A secretaria o vê no painel
o primeiro rascunho sem CPF não é idempotenterepetir a chamada sem o token (um retry por tempo esgotado, por exemplo) abre um segundo rascunho. Repita só com o draftToken em mãos
o token não é o idsão 32 bytes aleatórios que só quem criou o rascunho recebe. Não o mostre a outra pessoa

Os campos do formulário​

GET /notices/{noticeId}/application-fields diz quais campos o edital pede e com que exigência. O que cada um é, e para onde vai no corpo, é fixo:

fieldKeyRótuloVai emValores
FULL_NAMENome completocandidateNametexto
MOBILE_PHONECelularcandidatePhonetexto
EMAILE-mailcandidateEmailtexto
COURSE · CAMPUSCurso · PoloadmissionOfferIda oferta carrega os dois
ENTRY_FORMForma de ingressoadmissionNoticeEntryFormIdjourneys[].id da vitrine
CPFCPFcandidateCpf11 dígitos
BIRTH_DATEData de nascimentocandidateBirthDateAAAA-MM-DD
SECOND_COURSE_OPTION2ª opção de cursosecondChoiceOfferIdoutra oferta da vitrine
RGRGformAnswers.RGtexto, como está no documento, com 5 a 13 dígitos, não todos iguais
GENDERSexoformAnswers.GENDERmale · female · other
MARITAL_STATUSEstado civilformAnswers.MARITAL_STATUSSINGLE · MARRIED · DIVORCED · WIDOWED · OTHER
SPECIAL_NEEDSPossui necessidade especial?formAnswers"true" · "false"
SPECIAL_NEEDS_DESCRIPTIONDescrição da necessidade especialformAnswerstexto; obrigatório quando SPECIAL_NEEDS é "true"
POSTAL_CODE · NUMBER · COMPLEMENTCEP · Número · ComplementoformAnswerso resto do endereço vem de GET /postal-codes/{cep}
ENEM_SCORE · ENEM_YEARNota do ENEM · Ano do ENEMformAnswersnúmero. A nota vai de 0 a 1000, com até duas casas, e é obrigatória na forma Nota do ENEM
PREVIOUS_INSTITUTION · PREVIOUS_COURSEInstituição anterior · Curso anteriorformAnswerstexto
CLASS_SECTION · REFERRAL_CODE · PHONE · SOCIAL_NAME · HOW_DID_YOU_HEARTurma · Código de indicação · Telefone · Nome social · Como você conheceu a instituição?formAnswerstexto
GUARDIAN_NAME · GUARDIAN_CPF · GUARDIAN_PHONENome · CPF · Telefone do responsávelformAnswerstexto

O que a nossa página confere antes de chamar a API​

A API recusa com 400 o que fere o formato ou a regra do próprio campo, e com 422 o que fere a regra do edital. A página da Workfuse confere mais cedo, no campo, para o erro de digitação não custar uma chamada. Vale copiar:

CampoRegra da nossa páginaA API cobra?
Nome completoao menos duas palavras com 2 letras ou mais ("Maria e Silva" passa)só não vazio, até 200
E-maila mesma expressão da APIsim
Celular11 dígitos com DDD de 11 a 99, e o 3º dígito é 9só não vazio, até 32
CPFos dois verificadores fechamsim
Data de nascimentodata real, não futura, não antes de 1900, 14 anos ou maissim, com folga de fuso: a API aceita quem está a até dois dias do 14º aniversário. Corte os 14 anos na sua página, pelo calendário da pessoa
RGde 5 a 13 dígitos, não todos iguais; letras do órgão emissor livressim
CEP8 dígitosnão

?origem= no endereço do seu site resolve para um link salvo ou para uma origem do cadastro. GET /links/{slug} diz qual:

{
"destination": "https://faculdade-horizonte.example",
"refusal": null,
"origin": {
"captureLinkId": "cmu4sh98y00dqp0mbio5wjxgf",
"admissionNoticeId": "cmu4sh97w00chp0mb551lq2jq",
"captureOriginId": "cmu4sh97s00ccp0mbcuul1pi8",
"campusId": null,
"campaignCode": "PANFLETO-CENTRO"
}
}

Repasse captureLinkId (ou captureOriginId, quando não há link salvo) na primeira chamada, a que cria a inscrição: o primeiro POST /applications/draft, ou o envio quando não há rascunho. A origem é gravada quando a inscrição nasce, e as chamadas seguintes não a mudam. refusal vale NOT_FOUND, INACTIVE ou EXPIRED quando o link não leva a uma inscrição: mande a pessoa para destination (o site da instituição, ou o catálogo de cursos) em vez de seguir. A origem que fica na inscrição segue esta ordem:

origem do link salvo → origem do endereço → origem padrão do edital → desconhecida

A inscrição​

O que GET /applications/{id} devolve: a inscrição inteira, como o candidato a vê na área dele, mais o CPF em claro e os ids que o seu sistema guarda.

CampoO que traz
id · statuso número e uma das treze situações
admissionNoticeId · noticeName · admissionOfferId · admissionNoticeEntryFormIdo edital (id e nome), a oferta e a forma de ingresso. A forma é null no lead
courseName · campusName · campusCity · journeyNameos nomes do curso, do polo e da forma
secondChoiceCourseNamea 2ª opção, quando houve
examRequiredse a forma tem prova neste edital
journey[]as etapas, futuras incluídas: kind, position, state (DONE · CURRENT · FUTURE · HALTED), owner (CANDIDATE · INSTITUTION), exam, evaluation e document
journey[].examsó na etapa EVALUATION com prova: { url, opensAt, closesAt }. A url é o Endereço da prova com applicationId=<id> acrescentado, e só vem dentro da janela, com tentativa sobrando; as datas vêm null quando o edital não as define
journey[].evaluationsó na etapa EVALUATION do vestibular e do ENEM: score e source (INTEGRATION · MANUAL · ENEM), cutoffScore, scale, shortfall, result (PENDING · BELOW_CUTOFF · APPROVED · REJECTED · EXPIRED), attemptsUsed, attemptLimit, attemptsRemaining, decidedBy, decidedAt, manualScoredAt e examPeriodEnded
journey[].documentsó na etapa EVALUATION da Transferência Externa e da 2ª Graduação: kind (UNDERGRADUATE_TRANSCRIPT · UNDERGRADUATE_DIPLOMA), situation (IN_REVIEW · APPROVED · RESUBMISSION_REQUESTED · REJECTED, ou null sem envio), fileName, uploadedAt, note, illegible, resubmissionRequestedAt, uploadOpen, noticeDueOn e dueOn (dias AAAA-MM-DD). O arquivo nunca vem, e o envio é só do candidato, na área dele: por isso, nesta porta, uploadOpen vem sempre false. Para saber se o candidato ainda deve enviar, leia situation (null ou RESUBMISSION_REQUESTED) com dueOn
feePolicy · feeAmountCHARGED ou EXEMPT, e o valor congelado na inscrição
candidateName · candidateEmail · candidatePhone · candidateBirthDateo que a pessoa declarou
candidateCpfos 11 dígitos, em claro
createdAt · updatedAtquando foi criada e a última gravação. O updatedAt muda com a situação e os dados; o link da prova e examPeriodEnded são calculados na leitura e não o movem
timeline[]fromStatus, toStatus, actorKind (CANDIDATE · PARTNER · STAFF · SYSTEM), reason e at. reason é o motivo: o texto que a secretaria escreveu, ou o motivo automático (como a aprovação pela nota); actorKind diz de que lado veio a mudança, sem dizer quem

Na lista de GET /applications, journey e timeline vêm vazias.

A inscrição curta​

O que os dois POST devolvem: id, status, admissionNoticeId, admissionOfferId, admissionNoticeEntryFormId, feePolicy, feeAmount, createdAt e updatedAt. O rascunho acrescenta rejoined e draftToken.

As treze situações​

statusNa telaFinal
DRAFTRascunho
SUBMITTEDConcluída
FEE_PENDINGTaxa pendente
UNDER_REVIEWEm avaliação. Na Transferência Externa e na 2ª Graduação, com o documento: Avaliação · Aguardando envio, Em análise ou Reenvio de documento solicitado
DOCUMENTS_PENDINGDocumentos pendentes
APPROVEDAprovada
CALLEDConvocada
SENT_TO_ENROLLMENTEncaminhada à matrícula
ENROLLEDMatriculadasim
REJECTEDReprovadasim
ABSENTAusente na provasim
CANCELLEDCanceladasim
EXPIREDExpiradasim

As cinco finais não mudam mais: desfazer é uma inscrição nova.

As seis etapas da jornada​

journey[].kind usa o mesmo vocabulário em toda a plataforma, e a ordem é do edital:

REGISTRATION · DOCUMENTS · EVALUATION · PAYMENT · CALL · ENROLLMENT

Cadastro, documentos, avaliação, pagamento, convocação e matrícula. As etapas que a inscrição percorre dependem da forma de ingresso, e duas regras do edital ajustam: edital sem taxa pula PAYMENT, e "liberar a avaliação só após o pagamento" põe PAYMENT antes de EVALUATION.

Erros​

O corpo do erro​

A forma depende de onde a recusa nasce:

QuandoHTTPCorpo
regra de negócio404 409 422{ "errorCode": "...", "message": "...", "details": {...} }. details só vem em alguns códigos
validação do formato400{ "success": false, "error": { "name": "ZodError", "message": "..." } }. message é uma string JSON com a lista de problemas: faça JSON.parse e leia o path de cada item
chave ausente ou inválida401{ "error": "...", "code": "API_KEY_MISSING" } ou "API_KEY_INVALID"
chave sem o módulo no escopo403{ "error": "...", "code": "MODULE_NOT_IN_KEY_SCOPE" }
módulo não contratado pela organização403{ "error": "CAPABILITY_NOT_ENABLED", "code": "admission.selection", "message": "..." }

Reconheça o erro pelo código, nunca pelo texto de message.

Por status​

HTTPQuando
400corpo ou query fora do formato: CPF, e-mail, campo faltando, CPF sem nascimento (ou o contrário), draftToken fora do formato, e a data de nascimento ou o RG fora da regra da tabela
401chave ausente, inválida, desabilitada ou revogada
403a chave não tem o módulo de Processo seletivo no escopo, ou a organização não contratou o módulo
404curso, matriz, edital ou inscrição não encontrados na instituição da chave, e também o edital em rascunho (na vitrine e no formulário), a forma inativa no edital e o rascunho que ainda não tem CPF
409a inscrição já foi concluída, outra chamada deu CPF ao rascunho do token no mesmo instante, o período de prova terminou, a forma ficou sem nota de corte, ou a nota chegou a uma inscrição fora de avaliação. O duplo clique simultâneo não cai aqui: os dois recebem 200
422fora da janela do edital (ou edital ainda em rascunho, no envio), consentimento faltando, dados que não conferem, campo obrigatório vazio, forma desabilitada na instituição, nota fora da escala

O 404 também é recusa de visibilidade, de propósito. Uma inscrição de outra instituição, um edital em rascunho na vitrine e uma forma inativa respondem igual a "não existe": distinguir os casos contaria ao chamador o que a instituição ainda não publicou, ou o que não é dela.

Os códigos​

errorCodeHTTPO que fazer
ADMISSION_NOT_FOUND404curso, matriz, edital ou CEP não encontrados. Confira o id
CANDIDACY_NOTICE_NOT_FOUND404algum id do corpo não vale para este edital: o edital, a oferta (admissionOfferId, secondChoiceOfferId), a forma de ingresso (inexistente ou inativa no edital), o link ou a origem
CANDIDACY_NOT_FOUND404a inscrição não existe na instituição da chave. Na leitura pelo número, também o rascunho que ainda não tem CPF
CANDIDACY_NOT_EDITABLE409a inscrição já foi concluída (details.status). Mostre a situação dela em vez de reenviar
CANDIDACY_DRAFT_GONE409outra chamada deu CPF ao rascunho do draftToken no mesmo instante (outra aba, por exemplo). Siga para o passo do CPF: a chamada com CPF e nascimento acha a inscrição
EXAM_PERIOD_ENDED409o período de prova do vestibular terminou, e a forma não recebe inscrição nova. A vitrine já avisa com journeys[].examPeriodEnded
CANDIDACY_CUTOFF_MISSING409a forma por nota ficou sem nota de corte. Use outra forma, ou tente de novo depois que a instituição definir o corte
CANDIDACY_NOT_UNDER_REVIEW · EXAM_NOT_REQUIRED409a nota chegou a uma inscrição fora de avaliação (details.status) · a forma não aplica prova neste edital
CANDIDACY_NOTICE_NOT_ACCEPTING422o edital não recebe inscrições hoje, ou ainda está em rascunho. details traz opensAt e closesAt da próxima janela, ou null nos dois quando não há próxima
CANDIDACY_CONSENT_REQUIRED422mande dataConsentAt: sem aceite não há como concluir
CANDIDACY_ENTRY_FORM_NOT_AVAILABLE422a forma de ingresso foi desabilitada na instituição. Ofereça outra
CANDIDACY_IDENTITY_MISMATCH422o CPF já tem inscrição neste edital com outra data de nascimento. Peça para a pessoa conferir os dois, sem dizer qual não conferiu
CANDIDACY_MISSING_ANSWERS422falta campo obrigatório; details.missing lista as fieldKey. Na forma Nota do ENEM, inclui o ENEM_SCORE
ENEM_SCORE_INVALID422a nota do ENEM não é um número de 0 a 1000 com até duas casas
SCORE_OUT_OF_SCALE · SCORE_PRECISION_EXCEEDED422a nota da tentativa está fora de 0 a 10 (details traz min e max) · tem mais de duas casas

Limites​

Quantas vezes​

Não há teto de chamadas por CPF nesta API. O que limita a integração é a própria chave: desabilitada ou revogada no painel, toda chamada responde 401 na hora.

Quanto cabe​

Recusa com 400 antes de qualquer regra:

CampoTeto
candidateName200 caracteres
candidateEmail254 caracteres
candidatePhone32 caracteres
formAnswers29 chaves (o catálogo inteiro), 32 KB serializados e 32 níveis de aninhamento

Nenhum dos três tetos de formAnswers é alcançado por um envio real.

Swagger​

RecursoURL
Swagger interativoAPI_BASE/public/v1/doc
Contrato OpenAPI (JSON)API_BASE/public/v1/openapi

Clique em Authorize e cole só a chave (wf_...): o Swagger acrescenta o Bearer, e Bearer wf_... no campo responde 401. Mais em Referência da API.