trilambdasdocs

Trilambdas Connect · contrato v1

Documentação para desenvolvedores

Tudo o que o seu app precisa para mostrar ao usuário as pendências do próprio CPF, com consentimento, e ajudar a planejar o pagamento. A negociação continua no canal oficial de cada birô.

Visão geral

A integração tem três elos:

Seu appTrilambdasBirô
Identifica o usuário e abre a conexãoVerifica a identidade e coleta o consentimentoAutoriza o titular, quando tem fluxo próprio
Exibe as dívidas e ajuda a planejarConsulta, normaliza e junta duplicidadesFornece as pendências e negocia

A Trilambdas não guarda renda nem gastos, não negocia, não recebe pagamentos e não faz análise de crédito.

Início rápido

Com a chave de sandbox (tlk_test_…) que enviamos depois do pedido de acesso:

1. Crie a sessão de conexão (no seu backend)

curl https://api.trilambdas.com.br/v1/connect/sessions \
  -H "Authorization: Bearer $TRILAMBDAS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user": { "externalRef": "usr_123", "cpf": "529.982.247-25" },
    "providers": ["SANDBOX"],
    "redirectUrl": "https://seuapp.com.br/conexoes/retorno"
  }'
{
  "connectionId": "cmwfp2k3x0001abcd",
  "connectToken": "ctk_1f9c…",
  "connectUrl": "https://api.trilambdas.com.br/connect?token=ctk_1f9c…",
  "expiresAt": "2026-11-14T15:30:00.000Z"
}

2. Abra o widget para o usuário

Na web, entregue o connectToken ao front e abra com o connect-js. No app móvel, abra o connectUrl numa webview ou aba segura. O usuário confirma a identidade e autoriza. Veja Widget.

3. Consulte o estado da conexão

curl https://api.trilambdas.com.br/v1/connections/cmwfp2k3x0001abcd \
  -H "Authorization: Bearer $TRILAMBDAS_KEY"

4. Leia as dívidas e o resumo

curl https://api.trilambdas.com.br/v1/users/usr_123/debts -H "Authorization: Bearer $TRILAMBDAS_KEY"
curl https://api.trilambdas.com.br/v1/users/usr_123/debt-summary -H "Authorization: Bearer $TRILAMBDAS_KEY"

Testes automatizados podem pular o widget: POST /v1/connections/{id}/sandbox-authorize simula o titular autorizando e já faz a primeira consulta.

Autenticação e ambientes

AmbientePrefixo da chaveFontesDados
Sandboxtlk_test_SANDBOXfictícios, sempre iguais para o mesmo CPF
Produçãotlk_live_birôs com contrato ativoreais
  • Envie Authorization: Bearer tlk_… só do seu backend. A chave nunca vai para o app, o navegador ou o repositório.
  • A chave aparece uma única vez. Se vazar, peça a revogação.
  • Base: https://api.trilambdas.com.br/v1. Limite: 120 requisições por minuto por chave.

SDK para Node.js disponível

O @trilambdas/node cobre todas as rotas, com tipos, sem dependências (Node 20 ou mais novo). Repete sozinho leituras que falharam por rede, limite ou erro do servidor, e nunca repete um POST.

import { Trilambdas, constructEvent } from '@trilambdas/node';

const trilambdas = new Trilambdas({ apiKey: process.env.TRILAMBDAS_KEY! });

const { connectionId, connectToken } = await trilambdas.connect.createSession({
  user: { externalRef: 'usr_123', cpf: '529.982.247-25' },
  providers: ['SANDBOX'],
  redirectUrl: 'https://seuapp.com.br/conexoes/retorno',
});

const dividas = await trilambdas.debts.list('usr_123');
const resumo = await trilambdas.debts.summary('usr_123');

Até a publicação no npm, o SDK é entregue junto com a chave de sandbox: instale pelo repositório ou copie a pasta src para o seu projeto.

Conexões

A conexão é a autorização de um titular para um conjunto de fontes. Guarde o connectionId: é o identificador estável dela.

RotaPara quê
POST /v1/connect/sessionsCria a conexão pendente e o token de uso único do widget (vale 30 min)disponível
GET /v1/connections/:idEstado e resultado da última consulta, fonte por fontedisponível
GET /v1/users/:externalRef/connectionsConexões de um usuáriodisponível
DELETE /v1/connections/:idRevoga; repetir não causa errodisponível
POST /v1/debt-discoveriesConsulta de novo as fontes autorizadasdisponível

O externalRef é o id do usuário no seu app: estável e opaco, nunca CPF, e-mail ou telefone. Um externalRef fica preso a um CPF.

Widget

O widget é uma página da Trilambdas em três passos:

  1. Confirmar que é você. Em produção, com uma selfie no app Datavalid (Serpro): o titular informa um código de 9 caracteres no app e a foto é comparada à da CNH. No sandbox, também digitando o CPF da conta (5 tentativas; depois o link é bloqueado e a conexão fica ERROR).
  2. Autorizar, vendo o nome do seu app, as fontes, a validade e o que não acontece com os dados.
  3. Concluir e voltar para o seu app.
Como você abriuAo terminar
Janela aberta pelo seu site (window.open)postMessage para a origem do seu redirectUrl, e a janela fecha
Webview, aba segura ou navegação diretaRedireciona para o redirectUrl com connectionId e status=authorized|cancelled|error

Na web, com o connect-js

<script src="https://api.trilambdas.com.br/connect/connect.js"></script>
<script>
  botao.addEventListener('click', () => {
    TrilambdasConnect.open({
      token: connectToken, // da sessão criada no seu backend
      onSuccess: ({ connectionId }) => avisarBackend(connectionId),
      onExit: ({ reason }) => registrar(reason), // 'user_cancelled' | 'user_closed' | 'error'
    });
  });
</script>
  • Chame open() direto no clique do usuário, sem await antes: senão o navegador bloqueia a janela.
  • A página que chama open() precisa estar na mesma origem do redirectUrl da sessão: é só para ela que o widget envia o resultado.
  • Se a janela for bloqueada, o widget abre na mesma aba e volta ao redirectUrl; lá, TrilambdasConnect.readRedirect() devolve { connectionId, status }.
  • Se o seu site usa Cross-Origin-Opener-Policy: same-origin, troque para same-origin-allow-popups.

Confirme sempre o estado pelo seu backend (webhook ou GET): o retorno do navegador é só um aviso. O widget não abre dentro de iframe (proteção contra clique enganoso na tela de consentimento).

Ciclo de vida da conexão

EstadoQuandoO que o app faz
PENDINGSessão criada; titular ainda não concluiuNada. Expira em 30 min
AUTHORIZEDTitular autorizou; primeira consulta em andamentoMostrar "Buscando suas pendências"
ACTIVEPrimeira consulta concluídaExibir as dívidas
EXPIREDFim da validade (90 dias)Apagar os dados importados e oferecer reconectar
REVOKEDTitular desconectouApagar os dados importados
ERRORNenhuma fonte respondeu ou identidade não confirmadaVer lastErrorCode e oferecer nova sessão

Dívidas e resumo

{
  "id": "cm0debt001",
  "creditor": { "name": "Banco Exemplo S.A.", "document": "00000000000191" },
  "category": "CREDIT_CARD",
  "status": "NEGATIVATED",
  "currency": "BRL",
  "registeredAmount": 4250.9,
  "settlementOffer": { "amount": 2550.54, "validTo": "2026-11-28T00:00:00.000Z" },
  "lastVerifiedAt": "2026-11-13T22:41:00.000Z",
  "matchConfidence": "HIGH",
  "negotiationUrl": "https://…",
  "sources": ["SERASA", "BOA_VISTA"]
}
  • registeredAmount é o valor da anotação no birô. Não é o valor para quitar.
  • settlementOffer é o valor para quitar, com validade. Pode vir null.
  • matchConfidence: HIGH (uma fonte ou fontes casadas pelo CNPJ) ou MEDIUM (casadas pelo nome do credor).
{
  "userRef": "usr_123",
  "currency": "BRL",
  "identifiedDebt": 7241.66,
  "settlementOffersTotal": 4344.99,
  "uniqueDebts": 3,
  "openDebts": 3,
  "overdueDebts": 3,
  "debtsWithOffer": 3,
  "coverage": "complete"
}

Com coverage: "partial", avise o usuário que a lista pode estar incompleta.

Webhooks disponível

Cadastre um destino HTTPS público com POST /v1/webhooks e os eventos que quer receber. A resposta traz o secret uma única vez: guarde num cofre. Cada destino pertence ao ambiente da chave que o cadastrou: com tlk_test_ recebe só eventos do sandbox; com tlk_live_, só de produção.

EventoQuandoEm data
connection.authorizedO titular concluiu a autorizaçãoconnectionId, userRef, providers, expiresAt
connection.revokedA conexão foi revogadaconnectionId, userRef
connection.expiredA validade acabouconnectionId, userRef
debts.updatedUma consulta terminoudiscoveryId, userRef, added, updated, removed, coverage

O evento só avisa: nenhum CPF ou dado de dívida viaja nele. Os dados vêm do GET.

POST /webhooks/trilambdas
Content-Type: application/json
Trilambdas-Event-Id: evt_3f1a…
Trilambdas-Signature: t=1763073660,v1=5f2b0c…

{
  "id": "evt_3f1a…",
  "type": "debts.updated",
  "environment": "SANDBOX",
  "createdAt": "2026-11-14T04:41:00.000Z",
  "data": { "connectionId": "cmwfp2k3x…", "discoveryId": "cmwfq9a1b…", "userRef": "usr_123",
            "added": 3, "updated": 0, "removed": 0, "coverage": "complete" }
}

Validar a assinatura

// Use o corpo bruto, exatamente como chegou, antes do JSON.parse
const evento = constructEvent(corpoBruto, req.headers['trilambdas-signature'], process.env.TRILAMBDAS_WEBHOOK_SECRET!);

Sem o SDK:

  1. Separe t e v1 do cabeçalho Trilambdas-Signature.
  2. Calcule HMAC-SHA256(secret, "{t}.{corpo bruto}") e compare com v1 em tempo constante.
  3. Recuse se t tiver mais de 5 minutos de diferença.
  4. Ignore Trilambdas-Event-Id já processado.
  5. Responda 2xx em até 10 s e processe em fila.

Novas tentativas e testes

  • Sem 2xx, reenviamos com o mesmo Trilambdas-Event-Id: depois de 30 s, 2 min, 10 min, 30 min, 1 h, 2 h, 4 h e então a cada 6 h, até 24 horas do evento. Redirecionamentos não são seguidos.
  • POST /v1/webhooks/{id}/ping envia agora um webhook.ping assinado e devolve o resultado.
  • GET /v1/webhooks/{id}/deliveries mostra as últimas 50 entregas, com tentativas e código HTTP.

removed vem sempre 0 por enquanto: dívidas que somem passam a ser detectadas com a reconsulta periódica.

Erros

Todos seguem a RFC 9457 (application/problem+json).

{
  "type": "https://docs.trilambdas.com.br/errors/422",
  "title": "UNPROCESSABLE_ENTITY",
  "status": 422,
  "detail": "No ambiente de testes, use apenas a fonte SANDBOX",
  "instance": "/v1/connect/sessions"
}
400Corpo inválido (errors lista os campos) ou CPF inválido
401Chave ausente, inválida ou revogada
403Operação não permitida no ambiente da chave
404Recurso não existe para o seu app (dados de outros apps nunca aparecem)
409externalRef já vinculado a outro CPF
422Regra de negócio (fonte de outro ambiente, sessão expirada, sem fonte autorizada)
429Limite de requisições

Sandbox e CPFs de teste

O 9º dígito do CPF define quantas dívidas voltam (9º dígito % 4). Os credores e os links de negociação são fictícios.

CPF de testeDívidas
100.000.000-190
100.000.001-081
100.000.002-802
529.982.247-253

Regras para o seu app

Obrigatórias em produção. Elas protegem o titular e fazem parte do que acordamos com os birôs.

  • Mostre um selo de origem em cada dívida importada: "via Trilambdas · Serasa".
  • Não deixe o usuário editar o que vem da fonte: credor, valores, datas, situação e link de negociação.
  • Guarde o id da dívida e atualize por ele. Dívidas manuais continuam existindo.
  • Planeje pela oferta de acordo, mostrando a validade. Nunca apresente o valor registrado como valor para quitar.
  • O botão de negociar leva sempre ao negotiationUrl.
  • Ofereça "Desconectar" com o mesmo destaque de "Conectar". Na revogação ou expiração, apague as dívidas importadas em até 24 horas.
  • Não use os dados para análise ou oferta de crédito, marketing ou repasse a terceiros.

Antes de abrir o widget, mostre:

Conectar suas pendências. Vamos consultar, com a sua autorização, as pendências registradas no seu CPF nos birôs de crédito. Você pode desconectar quando quiser. A consulta é feita pela Trilambdas. A negociação acontece no canal oficial de cada birô.

Homologação

Antes da chave de produção, o seu app precisa:

  • Criar a sessão e abrir o widget no fluxo real do app
  • Tratar os retornos do widget e confirmar o estado pelo backend
  • Exibir as dívidas com selo de origem e campos da fonte travados
  • Planejar pela oferta, com validade visível
  • Levar ao negotiationUrl no botão de negociar
  • Desconectar e apagar os dados importados em até 24 horas
  • Tratar coverage: partial e os erros 401, 409, 422 e 429
  • Mostrar os textos obrigatórios

Referência da API

Todos os campos, parâmetros e respostas, gerados a partir do código, estão na referência interativa (OpenAPI).

Ainda não tem acesso? Peça a chave do sandbox.