Docs Unnotech
    • Visão geral da API
    • Guia: Originação FGTS
    • Guia: Originação CLT
    • Guia: Quota diária
    • Changelog e avisos de mudança
    • Autenticação
      • Gera um access_token
        POST
    • Originação
      • FGTS
        • Busca applications pelo id externo do consumidor
        • Cria uma solicitação (application) e dispara a cotação
        • Status enxuto da application (para polling)
        • Detalha uma application pelo id
        • Re-cota uma application (ofertas antigas invalidadas)
        • Lê o KYC (pré-preenchido quando disponível na plataforma)
        • Submete o KYC (cadastro completo) exigido antes do aceite
        • Aceita uma oferta e inicia a contratação
      • CLT
        • Busca solicitações pelo id externo do consumidor
        • Cria uma solicitação (application) de consignado CLT
        • Status enxuto da solicitação (para polling)
        • Detalha uma solicitação pelo id
        • Consulta o consentimento do trabalhador
        • Força uma nova verificação do consentimento
        • Consulta a margem consignável por vínculo
        • Simula e monta o menu de ofertas
        • Completa o cadastro do cliente
        • Lê o KYC (pré-preenchido quando disponível)
        • Submete o KYC exigido antes do aceite
        • Aceita uma oferta e inicia a contratação
    • Propostas
      • Lista propostas com filtros e paginação
        GET
      • Detalha uma proposta pelo UUID
        GET
    • Admin
      • Usuários
        • Lista usuários com filtros e paginação
        • Cadastra um novo usuário
        • Remove o usuário dos seus parceiros
        • Detalha um usuário pelo UUID
        • Atualiza um usuário (parcial) — e liga/desliga o acesso dele aos seus parceiros
      • Parceiros
        • Lista parceiros com filtros e paginação
        • Cadastra um novo parceiro
        • Detalha um parceiro pelo UUID
        • Remove um parceiro
        • Atualiza um parceiro (parcial)
        • Ativa ou inativa um usuário dentro do parceiro
      • Grupos
        • Lista grupos disponíveis
    • Esquemas
      • CreateUserRequest
      • CreateUserResponse
      • UserDetail
      • Data
      • CreateUserResponseData
      • BankerizeErrorResponse
      • UserPartnerEntry
      • Address
      • BankAccount
      • CreatePartnerRequest
      • Partner
      • Pix
      • CreatePartnerResponse
      • CreatePartnerResponseData
      • Customer
      • ApiError
      • ApiErrorResponse
      • CreateFgtsApplicationRequest
      • ErrorDetail
      • FieldErrorCode
      • ApiErrorCode
      • ApplicationStatus
      • FgtsInstallment
      • FgtsQuote
      • OfferStatus
      • FgtsApplication
      • QuoteStatus
      • RejectionKind
      • FgtsOffer
      • RejectionReason
      • AcceptFgtsOfferRequest
      • AcceptFgtsOfferResponse
      • AccountType
      • CivilStatus
      • DisbursementMethod
      • FgtsKyc
      • FgtsKycAddress
      • FgtsKycBank
      • Gender
      • PixKeyType
      • TokenRequest
      • TokenResponse
      • CltCustomer
      • OAuth2ErrorResponse
      • AuthorizationStatus
      • Group
      • UserDetailResponse
      • CreateCltApplicationRequest
      • CltCustomerCompleteness
      • UpdatePartnerRequest
      • CltApplication
      • CltEmploymentAlert
      • CltAuthorization
      • CltInstallment
      • PartnerDetail
      • PartnerDetailResponse
      • PageInfo
      • CltEmployment
      • CltQuote
      • SortInfo
      • CltSimulation
      • CustomerField
      • CltIneligibilityReason
      • UsersPage
      • CltOffer
      • ProposalsPage
      • AcceptCltOfferRequest
      • PublicProposalListItem
      • PublicCustomerSummary
      • QuoteBasis
      • AcceptCltOfferResponse
      • PublicDisbursementAccount
      • CltSimulationRequest
      • OfferNotice
      • PublicLoanSummary
      • CltKycAddress
      • CltKycBank
      • PublicProposalDetailResponse
      • CltKyc
      • PartnerListItem
      • PartnersPage
      • ListOfGroupsResponse
      • CltKycEmployer
      • FgtsApplicationList
      • FgtsApplicationStatus
      • UpdateUserRequest
      • UpdateCltCustomerRequest
      • UserListItem
      • PublicProposalDetail
      • CltApplicationList
      • CltApplicationStatus
      • CltMargin

    Guia: Originação CLT

    Crédito consignado CLT, ponta a ponta: obter a autorização do trabalhador, consultar a margem,
    simular, submeter o KYC e contratar.
    Todos os endpoints deste grupo exigem o scope proposals:write na sua api-key — inclusive os GET
    de acompanhamento, porque quem origina precisa acompanhar o que originou. Sem ele a resposta é
    403, mesmo com um token válido. proposals:write é distinto de proposals:read, que dá acesso à
    listagem de propostas já contratadas em /api/v1/proposals.

    Três portões antes do menu#

    No consignado o menu de ofertas não existe de saída. Há três portões em ordem, e cada um é uma
    espera diferente:
    O primeiro portão é o que mais surpreende: ele não depende de você nem da plataforma. Enquanto
    o trabalhador não autorizar, não há margem — e sem margem não há o que simular.

    O fluxo em sete passos#

    1. POST  /applications                     → 202, status AWAITING_AUTHORIZATION
    2. GET   /applications/{id}/status         ↻ até authorization_status virar AUTHORIZED
           (POST /authorization força uma verificação quando você souber que assinou)
    3. GET   /applications/{id}/margin         → vínculos e quanto há em cada um
    4. POST  /applications/{id}/simulations    → 202, cotação em curso
    5. GET   /applications/{id}/status         ↻ até offers_count > 0 (ou NO_OFFERS)
    6. POST  /applications/{id}/kyc            → cadastro completo + conta ou chave Pix
    7. POST  /applications/{id}/offers/{offer_id}/accept → 202, contratação iniciada
    Depois do aceite, siga no GET /status até DISBURSED — ou até um terminal de recusa.

    Os estados e para onde eles vão#

    O caminho central é o de sucesso; as saídas laterais são os desfechos que você precisa tratar.
    Quatro leituras que o desenho torna óbvias:
    Os dois terminais do início são diferentes entre si. AUTHORIZATION_UNAVAILABLE é o CPF sem
    autorização de consulta no Dataprev. NO_MARGIN é margem zerada hoje, que pode mudar no mês
    seguinte.
    NO_OFFERS não é fim de linha. Como o valor é você quem pede, uma nova simulação com outro
    valor — ou com a outra base — pode render menu.
    CONTRACT_REJECTED também volta. Aceitando outra oferta do mesmo menu.
    ENDORSED é a fronteira sem volta. Antes dela, cancelar e tentar outro caminho é viável;
    depois, o CPF está averbado naquele banco.
    Trate estado desconhecido como "em andamento": a lista cresce, e um valor novo não deve quebrar seu
    parser.

    1. Abrir a solicitação. Informe o mínimo.#

    A criação pede cpf, phone e email. name, birth_date e gender são opcionais.
    Isso não é descuido do contrato: cada bancarizadora exige um conjunto diferente para começar, e
    obrigar você a preencher o superconjunto puniria todo mundo pela mais exigente. Quem não tem o que
    precisa fica de fora da cotação, com o motivo em quotes[].reason, e a solicitação segue com as
    demais.
    O bloco customer na resposta diz o que falta:
    "customer": {
      "provided": ["CPF", "PHONE", "EMAIL"],
      "missing_for_more_offers": ["NAME", "BIRTH_DATE", "GENDER"]
    }
    Consulte esse bloco antes de pedir qualquer coisa ao cliente final. Boa parte desses campos vem
    da própria Dataprev junto com a margem, e a lista encolhe sozinha — pedir antes seria retrabalho
    para o seu usuário. O que sobrar você completa com PATCH /applications/{id}/customer.
    A lista nunca diz qual bancarizadora exige o campo: o provider é detalhe interno.
    Informe também o user_uuid do operador que conduz a venda, para que a proposta e a comissão fiquem
    com ele. O campo passa a ser obrigatório em 05/10/2026 — ver
    Vincular a operação ao seu operador.

    2. Esperar a autorização. É o portão que não depende de você.#

    authorization.status tem quatro valores, e dois deles se parecem sem ser:
    StatusO que significaO que fazer
    AUTHORIZEDConsentimento vigenteSeguir para a margem
    NOT_AUTHORIZEDO trabalhador ainda não assinou o termoAguardar — transitório
    NOT_AVAILABLEO CPF ainda não autorizou a consulta no DataprevNada a fazer por aqui — terminal
    PENDINGRegistro em processamentoAguardar
    A plataforma reconsulta sozinha. O POST /applications/{id}/authorization existe para quando você
    souber que o cliente acabou de assinar — mas é limitado por CPF: estourado o limite, responde
    429 com Retry-After. Respeite-o em vez de tentar em laço.

    Onde o trabalhador assina#

    O consentimento é um só: o termo de autorização da plataforma. authorization.consent_url traz
    o endereço da página de aceite — encaminhe o trabalhador para lá.
    A página é servida pela Unno e exibe o termo que ele assina. Um único aceite cobre todas as
    bancarizadoras aderentes ao termo universal, então não há um link por bancarizadora, nem jornada
    diferente por oferta.
    Assinado o termo, a solicitação segue sozinha para MARGIN_QUERY — você não precisa avisar a
    plataforma. O POST /authorization só antecipa a verificação.
    O campo pode vir ausente se o endereço ainda não tiver sido gerado; nesse caso reconsulte com
    POST /applications/{id}/authorization.

    3. Consultar a margem. Um CPF pode ter mais de uma.#

    GET /applications/{id}/margin devolve employments[]: um item por vínculo empregatício, cada um
    com empregador, margem disponível e data de admissão. A simulação referencia um employment_id —
    é você quem escolhe em qual vínculo operar.
    Esconder isso seria decidir pelo cliente: dois empregos são duas margens, e a maior nem sempre é a
    que ele quer comprometer.

    MARGIN_QUERY que não sai do lugar#

    A consulta depende da bancarizadora, e ela pode falhar. Quando falha, a solicitação não morre: a
    plataforma retenta, e só encerra em FAILED por prazo (30 min) ou por teto de tentativas (8).
    Nesse meio-tempo o GET /status traz margin_failure_reason. O campo só existe quando há
    falha
    — em consulta normal a chave não vem, e é por isso que dá para distinguir as duas situações
    que antes eram o mesmo MARGIN_QUERY:
    /status em MARGIN_QUERYLeitura
    sem margin_failure_reasonconsulta em curso, espere
    com margin_failure_reasonuma tentativa falhou, a plataforma está retentando
    O código é sempre nosso e genérico (ARRANQUE_DA_CONSULTA_FALHOU, COLETA_DA_CONSULTA_FALHOU,
    NENHUMA_BANCARIZADORA_ELEGIVEL). O que a bancarizadora disse vai em failure_detail do GET /margin — é ali que aparece o texto dela, e é o que separa "parceiro em janela de manutenção" de
    "credencial vencida" sem abrir um chamado.

    4. Simular. Aqui você diz quanto quer.#

    basis decide qual valor você informa:
    INSTALLMENT — installment_amount, quanto ele quer pagar por mês;
    NET_AMOUNT — net_amount, quanto o cliente quer receber.

    Use a base em que o cliente pensa#

    Hoje todas as bancarizadoras do CLT atendem as duas bases. Se o cliente chegou dizendo quanto
    quer receber, peça em NET_AMOUNT; se ele chegou dizendo quanto pode pagar por mês, peça em
    INSTALLMENT. Traduzir de uma para a outra do lado de cá só embute uma conta que a bancarizadora
    faz melhor.
    Isso é o estado do catálogo, não uma garantia do contrato. Cada bancarizadora declara as bases que
    atende, e uma que atenda só uma delas continua plugável: ela apareceria em quotes[] com
    UNSUPPORTED_QUOTE_BASIS e não contribuiria com oferta. Não sobrando nenhuma elegível, a simulação
    falha com SIMULATION_BASIS_UNSUPPORTED — e aí não há menu nenhum.

    O teto do INSTALLMENT#

    Pedindo por parcela, o teto é a margem disponível do vínculo escolhido — a mesma que
    GET /applications/{id}/margin devolve em employments[].available_margin. Acima dela a simulação
    falha com INSTALLMENT_EXCEEDS_MARGIN (422) e nenhuma rodada é aberta: nenhuma bancarizadora
    aprovaria a operação, e disparar o fan-out só gastaria chamada em todas para voltar sem oferta.
    A recusa vale só para essa base. Em NET_AMOUNT quem calcula a parcela é a bancarizadora, já
    ciente da margem que ela mesma consultou.

    O teto do NET_AMOUNT#

    INSTALLMENT compromete a margem cheia; a inversão que uma bancarizadora faz para atender
    NET_AMOUNT pode partir de menos que isso. O efeito prático é que o líquido máximo pedindo por
    valor costuma ser menor do que o de uma parcela na margem toda
    — a mesma pessoa, o mesmo vínculo.
    Pedir acima desse teto não é erro: a bancarizadora responde com as condições do máximo que ela
    alcança e a quote traz a ressalva em reason. Confira o net_amount das ofertas antes de
    apresentá-las — ele pode ser menor do que o pedido, e o cliente precisa saber disso pela sua tela,
    não pelo extrato.
    O prazo não é pedido. Quem o define é o motor de crédito da bancarizadora, dentro dos valores
    que ele aceita para aquele cliente e aquela tabela — pedir um prazo não o faria valer. A plataforma
    oferta uma condição por prazo viável em cada tabela elegível, e é no menu que o cliente escolhe
    entre parcela menor e prazo mais curto.
    Repetir o POST /simulations é a re-cotação, e invalida o menu anterior. Não há endpoint de
    requote no CLT: descarte os offer_id antigos e trabalhe só com o menu da rodada nova.

    A ordem do menu#

    offers[] vem ordenado por net_amount decrescente, com as bancarizadoras misturadas: o topo é
    sempre a condição que mais entrega ao cliente, venha de quem vier. Empate no líquido é desempatado
    pela menor installment_amount — mesmo dinheiro na mão, menor comprometimento de folha primeiro.
    Ofertas sem condição (as recusadas, que trazem rejection_reason) vão para o fim.
    Não agrupamos por bancarizadora de propósito. Agrupar daria vantagem de posição a quem respondesse
    primeiro ao fan-out, que é uma característica nossa e não do produto que o cliente compra.

    A tabela vem identificada, não só nomeada#

    Toda oferta traz a tabela comercial que a originou em dois campos: table_name, o rótulo que o
    cliente lê na tela, e table_id, o uuid dela no cadastro da plataforma — o mesmo identificador que
    aparece no table_identifier da proposta depois do aceite.
    Use o table_id para qualquer casamento programático (agrupar o menu, aplicar a sua própria
    política por tabela, conciliar comissão): o nome é rótulo comercial e muda quando a bancarizadora
    renomeia a tabela ou publica uma "2.0", enquanto o uuid atravessa a renomeação.
    table_id vem ausente quando a bancarizadora ofertou uma condição que não casa com nenhuma
    tabela do catálogo. Nesse caso o table_name é o rótulo do próprio provedor — bom para exibir, sem
    serventia para conciliar. Trate a ausência como "tabela não identificada", nunca como erro.

    O seguro prestamista é dimensão da tabela#

    A bancarizadora publica tabelas irmãs — "BÚZIOS - COM SEGURO" e "BÚZIOS - SEM SEGURO" —, cada uma
    com sua própria condição. insurance_included diz de qual delas a oferta veio, e insurance_amount
    traz o prêmio já embutido na parcela; nas ofertas sem seguro ele vem zerado.
    Agrupar por insurance_included monta as duas listas. O que não existe é a garantia de que
    toda condição apareça nas duas: cada tabela tem seus próprios prazos e sua própria política de
    crédito, e um prazo pode ser ofertado com seguro e não sem — ou o contrário. Um menu real:
    Tabelainsurance_includedPrazos ofertados
    BÚZIOS - COM SEGUROtrue15x, 19x, 25x
    BÚZIOS - SEM SEGUROfalse15x, 19x, 25x
    JURERÊ - COM SEGUROtrue24x
    JURERÊ - SEM SEGUROfalse24x, 30x, 36x
    Repare na JURERÊ: 30x e 36x só existem sem seguro. Se a sua tela parear por prazo, essas duas
    ficam sem contrapartida — agrupe por tabela (pelo table_id, não pelo nome), não por prazo.

    5. Submeter o KYC. Antes do aceite, sempre.#

    O KYC é obrigatório, e o bloco bank precisa de conta bancária ou chave Pix. Sem um dos dois o
    aceite responde 422 DISBURSEMENT_DATA_REQUIRED — melhor descobrir aí do que depois de o cliente
    já ter assinado o contrato.
    O GET /applications/{id}/kyc devolve um rascunho pré-preenchido com o que a plataforma já sabe,
    incluindo o que veio da Dataprev. Use como ponto de partida do seu formulário.
    O POST /kyc é upsert e não exige Idempotency-Key — de propósito, para que corrigir um dado
    errado seja só reenviar.

    6. Aceitar e acompanhar.#

    Escolha um offer_id do menu e aceite. A oferta precisa estar AVAILABLE e dentro do expires_at;
    passado o prazo, o aceite responde 409 OFFER_EXPIRED e o caminho é simular de novo.
    Resposta 202: emissão do contrato, assinatura e averbação seguem em background. Continue no GET /status até DISBURSED ou um terminal de recusa.

    Duas coisas que costumam pegar quem integra#

    A chave de acompanhamento é o application_id, não o proposal_uuid. A proposta é criada
    apenas no aceite e muda a cada nova tentativa de contratação: se o banco recusar e você aceitar
    outra oferta, nasce outra proposta. Só o application_id atravessa o fluxo inteiro.
    Recusa do banco não é erro HTTP. Se o banco recusar a contratação, o POST /accept já terá
    respondido 202 — a recusa chega depois, com a solicitação em CONTRACT_REJECTED e o motivo em
    offers[].rejection_reason. Trate como "tente a próxima", não como fim de linha.

    Vincular a operação ao seu operador (user_uuid)#

    A partir de 05/10/2026 às 00:00 (horário de Brasília), o user_uuid é obrigatório. A
    abertura da solicitação sem ele passa a responder 422 VALIDATION_FAILED. Detalhes e prazo no
    documento Changelog e avisos de mudança.
    Sem o campo, a solicitação — e a proposta que nascer dela — fica vinculada ao usuário padrão da
    API
    , que aparece na plataforma como "Originação (Sistema)". Com isso nenhum operador do seu
    time aparece como usuário digitador da proposta, e a comissão não é atribuída a ninguém.
    Para vincular a operação a quem de fato a conduziu, informe o user_uuid desse operador na
    abertura da solicitação:
    O vínculo vale para a solicitação inteira: o operador fica como dono dela e passa a ser o usuário
    digitador da proposta contratada a partir dela. Não é preciso repetir o campo no KYC nem no aceite.

    Como obter o user_uuid#

    O user_uuid é o identificador do operador na nossa plataforma, não no seu sistema. Busque-o
    na API de usuários, filtrando pelo CPF (ou e-mail) do operador:
    Use o campo uuid do item retornado. O valor não muda: guarde o mapeamento
    "operador do seu sistema → uuid" no seu cadastro e consulte a API só quando entrar um operador
    novo. Se o operador ainda não existe na plataforma, cadastre-o com POST /api/v1/users.

    Regras#

    Obrigatório a partir de 05/10/2026 00:00 (horário de Brasília). Até lá, sem o campo a
    operação segue com o usuário padrão da API e a resposta 202 traz os headers Deprecation,
    Sunset (a data do prazo) e Link (a explicação). Depois do prazo, a omissão responde
    422 VALIDATION_FAILED com details[].field = "user_uuid" e details[].code = "REQUIRED", e a
    solicitação não é aberta.
    Scope users:read. A validação do operador usa a mesma leitura da API de usuários, então a
    sua api-key precisa desse scope (além de proposals:write). Sem ele a abertura responde 422.
    O operador precisa ser seu. Tem de ser um usuário ativo do seu parceiro ou de um
    sub-parceiro abaixo dele. Usuário de outro parceiro, inexistente ou inativo responde
    422 VALIDATION_FAILED, com details[].field = "user_uuid", e a solicitação não é aberta.
    Faz parte da idempotência. O user_uuid entra na comparação do corpo: reenviar a mesma
    Idempotency-Key com outro user_uuid responde 409, como qualquer outra mudança de corpo.

    Sem infra de webhook? Sem problema#

    O webhook é gatilho de conveniência; o GET é a fonte da verdade. O fluxo inteiro funciona só com
    POST + GET, e o GET /applications/{id}/status existe justamente para tornar o polling barato.
    Quem usa webhook também deve confirmar pelo GET antes de agir — um evento pode se perder, e o
    GET sempre reconcilia.
    Modificado em 2026-10-01 02:47:09
    Página anterior
    Guia: Originação FGTS
    Próxima página
    Guia: Quota diária
    Built with