Documentação da API

A API REST da Saldo.tech permite que instituições financeiras e carteiras integrem ofertas vinculadas a pagamentos em seus apps — em cartões, PIX e outros meios. Todos os endpoints usam JSON sobre HTTPS e autenticam com uma API key por instituição (Bearer token): a instituição é sempre derivada da key, nunca do corpo da requisição.

Visão geral

A API é organizada em torno destas áreas de recursos:

Webhook de transações

POST /api/v1/transactions

Envie eventos de transação do portador de cartão para o emparelhamento de ofertas em tempo real. O principal ponto de integração para instituições financeiras.

Transações em lote

POST /api/v1/transactions/batch

Envie muitos eventos de transação em uma única requisição assinada — para feeds legados ou de alto volume.

Upload de arquivo em lote (CSV)

CSV · Institution Portal

Prefere um arquivo diário? Envie um CSV de transações pelo Portal da Instituição — validado e correspondido como o webhook.

Feed de ofertas

GET /api/v1/offers

Obtenha as ofertas elegíveis de um portador para exibir no seu app ou no widget integrável.

Adicionar oferta (inscrever)

POST /api/v1/offers/{id}/add

Inscreva um portador em uma oferta para que as transações dele passem a corresponder a ela.

Relatórios — Resgates

GET /api/v1/reporting/redemptions

Histórico de resgates paginado por cursor para integração com BI/data warehouse. Autenticado pela chave de API da instituição.

Relatórios — Liquidações

GET /api/v1/reporting/settlements

Razão de liquidações paginado por cursor com o valor financiado pelo comerciante, a receita da Saldo e o repasse à instituição.

Relatórios — Funil

GET /api/v1/reporting/funnel

Funil de engajamento para um período de datas: visualizações do widget, portadores de cartão únicos, impressões, adições e resgates.

Webhook de transações

O webhook de transações é a integração central para instituições financeiras. Publique os eventos de transação à medida que ocorrem, e o motor de emparelhamento da Saldo.tech determinará se existe uma oferta qualificável.

POST /api/v1/transactions

Authorization: Bearer slk_<your-key>

{
  "institution_id": "8f3e0b1c-...-uuid",  // optional — derived from your key
  "cardholder_token": "tok_ch_abc123",
  "instrument_token": "tok_inst_xyz789",  // card OR wallet/account token (card_token is the card-rail alias)
  "instrument_type": "card",              // card | wallet | account
  "merchant_identifier": "CA1234567890",  // preferred — the id your record carries
  "merchant_identifier_type": "card_acceptor", // card_acceptor | pix_key | upi_vpa | …
  "card_acceptor_id": "CA1234567890",     // legacy alias (implies card_acceptor)
  "mcc": "5411",                          // optional — reserved for enrichment
  "merchant_descriptor": "SOLESTYLE #12", // optional — reserved for enrichment
  "network": "visa",                      // optional
  "merchant_id": "aaaaaaaa-...-uuid",     // optional — only if you already resolved it
  "amount": 225.00,
  "transaction_ref": "txn_unique_id",
  "transacted_at": "2025-03-15T14:30:00Z"
}

Campos da requisição

institution_iduuidOpcional — a conta é derivada da sua chave de API. Inclua apenas se quiser que o servidor rejeite uma divergência.
cardholder_tokenstringId opaco e ESTÁVEL por cliente gerado pela sua instituição — ex.: HMAC-SHA256 de uma chave estável como o email do cliente ou seu id de cliente interno, com um segredo que você controla (um HMAC COM CHAVE, não um hash simples — email é de baixa entropia e um hash simples é reidentificável). Mesmo cliente → mesmo token, em todas as ofertas e ao longo do tempo. Nunca envie um email/id real; não rotacione nem aleatorize por evento, ou as transações não corresponderão às inscrições.
card_tokenstringPAN tokenizado do cartão usado (gerado pela FI, nunca o número real). Trilho de cartão; para QR/A2A use instrument_token.
instrument_tokenstringO instrumento de pagamento, tokenizado — um token de cartão OU um token de carteira/conta para consumidores QR/A2A sem cartão. Envie este ou card_token.
instrument_typestringTipo de instrumento: card | wallet | account. Opcional.
merchant_identifierstringPreferido. O identificador do comerciante que seu registro de transação carrega (um ID de estabelecimento, uma chave PIX, um UPI VPA, …). A Saldo o resolve para o comerciante.
merchant_identifier_typestringTipo de merchant_identifier: card_acceptor | pix_key | upi_vpa | codi | psp_merchant_id. Padrão: card_acceptor.
card_acceptor_idstringPreferido. O ID do estabelecimento (card-acceptor ID) do seu registro de transação (campo 42 do ISO-8583). A Saldo o resolve para o comerciante. Envie este ou o merchant_id.
mccstringOpcional. Código de categoria do comerciante (MCC). Reservado para enriquecimento futuro; ainda não usado na correspondência.
merchant_descriptorstringOpcional. O descritor do comerciante do seu registro de transação. Reservado para resolução de fallback futura; ainda não usado na correspondência.
networkstringOpcional. Bandeira do cartão (ex.: visa, mastercard).
merchant_iduuidOpcional. UUID do comerciante da Saldo.tech: envie apenas se você já resolveu o comerciante; caso contrário, envie card_acceptor_id.
amountnumberValor da transação, na moeda da oferta.
transaction_refstringSua referência única para esta transação. Usada para idempotência (única por instituição).
transacted_atstringCarimbo de data/hora ISO 8601 de quando a transação ocorreu.

Ingestão de transações em lote

Instituições legadas ou de alto volume podem enviar muitas transações em uma única requisição assinada com HMAC, em vez de um webhook por evento. Cada item usa os mesmos campos do webhook individual.

POST /api/v1/transactions/batch

{
  "transactions": [
    { "institution_id": "8f3e...uuid",
      "cardholder_token": "v1_ia_kp4EZvf5J2KpiRymLtJfFJd98ItuF07g95--u5YI",
      "card_token": "v1_or_44Zrluj8Iy3On_vABCdjpecpxLFo3_gE8BIp-iwQ",
      "merchant_id": "aaaa...uuid",
      "amount": 225.00, "transaction_ref": "txn_1",
      "transacted_at": "2025-03-15T14:30:00Z" }
  ]
}

// 202 Accepted
{ "received": 1, "accepted": 1, "duplicates": 0, "invalid": [] }

Upload de arquivo em lote (CSV)

Instituições nos planos Growth ou Enterprise podem enviar um CSV diário de transações pelo Portal da Instituição (Uploads em lote) em vez de chamar o webhook por evento. O arquivo é validado linha a linha, deduplicado por transaction_ref e passa pelo mesmo matching; um relatório de erros por linha é gerado para as linhas rejeitadas.

Colunas (linha de cabeçalho obrigatória, em qualquer ordem)

cardholder_token,card_token,card_acceptor_id,amount,transaction_ref,transacted_at
tok_ch_abc123,tok_card_xyz789,CA1234567890,225.00,txn_1,2025-03-15T14:30:00Z

institution_id vem da sua conta — nunca do arquivo. Linhas em branco são ignoradas; linhas inválidas são informadas por número de linha sem falhar o arquivo inteiro. Inclua card_acceptor_id (preferido — a Saldo o resolve para seu comerciante) ou merchant_id.

Autenticação

Todos os endpoints são autenticados com a API key Bearer da sua instituição. Cada key tem escopos (scopes) que definem quais endpoints ela pode chamar.

API key

Gere-a no Portal de Instituições em Dashboard → API Keys. O texto simples é exibido apenas uma vez na criação; somente o hash SHA-256 é armazenado. Cada chave é restrita à sua instituição.

Authorization: Bearer slk_<random>
Gerar uma chave →

Webhooks de transações

Os endpoints de transações e em lote usam a mesma chave Bearer que o resto — sem segredo de assinatura separado. Envie Authorization: Bearer e a instituição é obtida da chave.

Authorization: Bearer slk_<random>

Escopos da key

Escolha os escopos ao gerar uma key e dê a cada uma apenas o que ela precisa: uma ferramenta de BI só precisa de reporting. Chamar um endpoint fora dos escopos da key retorna 403. Keys criadas antes da existência dos escopos mantêm os três.

  • offers — feed de ofertas e inscrição (GET /api/v1/offers, POST /api/v1/offers/:id/add)
  • transactions — webhook de transações, lote e simulação
  • reporting — relatórios de resgates, liquidações e funil

Vencimento e rotação de chaves

As chaves podem ter data de vencimento (um ano por padrão). O Saldo avisa sua equipe 14 e 3 dias antes do vencimento e no próprio dia; uma chave vencida recebe 403 (Token expired). Para fazer a rotação sem interrupção: crie uma chave nova com os mesmos escopos, implante-a, confirme que as requisições funcionam e depois revogue a antiga. Faça a rotação pelo menos uma vez por ano, e imediatamente se uma chave puder ter sido exposta ou se alguém que a tinha sair. A criação e a revogação de chaves ficam registradas na sua Atividade de segurança.

Feed de ofertas e inscrição

Obtenha as ofertas que um portador vê e depois inscreva-o. Ambos os endpoints se autenticam com sua chave de API de instituição — a instituição é derivada da chave e todos os identificadores do portador são tokenizados.

GET/api/v1/offers

Retorna as ofertas ativas e com orçamento disponível para o portador, respeitando a ordem do seu programa e a elegibilidade por portador.

Parâmetros de consulta

  • cardholder_token Obrigatório. O token opaco do portador.
  • locale Opcional. en, es ou pt-BR — localiza o título e a descrição de cada oferta. Se o seu programa não oferecer esse idioma, o feed usa o primeiro idioma suportado pelo programa.
  • segment Opcional. O código de segmento do portador vindo dos seus próprios sistemas (ex.: premium). Ofertas que você limitou a segmentos só aparecem quando ele corresponde; ofertas sem restrição sempre aparecem. Usado apenas nesta requisição: a Saldo nunca armazena o segmento de um portador.
  • limit Opcional. 1–100 (também limitado pela configuração do seu widget).
  • personalize Opcional. Defina true para ordenar o feed por afinidade do portador; adiciona um reason a cada oferta.
  • prefer_merchants, prefer_categories Opcional. prefer_merchants e prefer_categories aceitam dicas separadas por vírgula, usadas apenas em memória e nunca armazenadas.
curl "https://saldo-consumer-api-git-staging-kalantech.vercel.app/api/v1/offers?cardholder_token=tok_ch_abc123&locale=es&limit=20" \
  -H "Authorization: Bearer slk_..."

{
  "offers": [
    {
      "id": "0b1...",
      "title": "Spend $200 at Acme, get $15 back",
      "description": "Gasta $200 en Acme y recibe $15",
      "merchant_id": "aaaa...",
      "min_spend": 200.00,
      "cashback_amount": 13.20,
      "currency": "USD",
      "starts_at": "2026-04-01T00:00:00Z",
      "expires_at": "2026-06-30T00:00:00Z",
      "added": false
    }
  ],
  "total": 12,
  "personalized": false
}
POST/api/v1/offers/{id}/add

Cria o vínculo portador–oferta para o matching começar. Idempotente — reenviar retorna already_added.

Corpo da requisição

curl -X POST "https://saldo-consumer-api-git-staging-kalantech.vercel.app/api/v1/offers/0b1.../add" \
  -H "Authorization: Bearer slk_..." \
  -H "Content-Type: application/json" \
  -d '{ "cardholder_token": "tok_ch_abc123", "card_token": "tok_card_xyz789" }'

// 201 Created
{ "status": "added", "cardholder_offer_id": "c0f..." }

// 200 OK (idempotent re-add)
{ "status": "already_added", "cardholder_offer_id": "c0f..." }

Envie o mesmo segment ao adicionar uma oferta limitada a segmentos (caso contrário, 403 segment_not_eligible). Se o portador já tiver o número máximo de ofertas ativas do seu programa, a requisição retorna 409 max_active_offers.

Webhook de resgates (Saldo → você)

Quando uma compra cumpre os termos de uma oferta, a Saldo envia o resgate por POST para a URL de webhook configurada no seu Portal da Instituição, para que você credite o portador.

POST https://your-bank.example/saldo/redemptions
X-Saldo-Signature: sha256=9f2c...
X-Saldo-Timestamp: 1791633600
X-Saldo-Signature-V2: sha256=4b7e...

{
  "event": "redemption.completed",
  "redemption_id": "r1a...",
  "institution_id": "i9f...",
  "offer_id": "0b1...",
  "cardholder_token": "v1_ia_kp4E…(46 characters)…u5YI",
  "cardholder_token_masked": "v1_i...u5YI",
  "institution_payout_amount": 13.20,
  "occurred_at": "2026-10-08T12:00:00.000Z"
}

API de relatórios

Extraia programaticamente os dados de resgates, liquidações e engajamento da sua instituição — para conciliação financeira, painéis de BI ou ferramentas internas personalizadas. Todos os endpoints retornam JSON, são restritos à instituição proprietária da chave de API e têm um limite de 60 requisições por minuto por chave.

GET/api/v1/reporting/redemptions

Lista de resgates paginada por cursor para a instituição que faz a chamada. Os tokens de portador de cartão são mascarados para os primeiros/últimos 4 caracteres.

Parâmetros de consulta

  • from, to — carimbos de data/hora ISO 8601 (opcional)
  • cursor — valor opaco da resposta anterior (opcional)
  • limit — de 1 a 1000 (padrão 100)

Exemplo

curl https://saldo-consumer-api-git-staging-kalantech.vercel.app/api/v1/reporting/redemptions?limit=2 \
  -H "Authorization: Bearer slk_..."

{
  "data": [
    {
      "id": "8f3...",
      "created_at": "2026-04-29T14:32:11.000Z",
      "status": "settled",
      "merchant_funded_amount": 15.00,
      "institution_payout_amount": 13.20,
      "offer": {
        "id": "0b1...",
        "title": "Spend $200 at Acme, get $15 back",
        "merchant_name": "Acme Inc."
      },
      "cardholder_token_masked": "tok_...c123"
    }
  ],
  "pagination": {
    "limit": 2,
    "next_cursor": "2026-04-29T14:32:11.000Z|8f3..."
  }
}
GET/api/v1/reporting/settlements

Entradas do razão de liquidações paginadas por cursor com o valor financiado pelo comerciante, a receita da comissão da Saldo, o repasse à instituição e o status.

Parâmetros de consulta

  • status — pending | settled | reversed (opcional)
  • from, to, cursor, limit — mesma semântica dos resgates
GET/api/v1/reporting/funnel

Funil de engajamento agregado para um período de datas. Por padrão, usa os últimos 30 dias quando from / to são omitidos.

{
  "window": { "from": "...", "to": "..." },
  "data": {
    "widget_views": 12834,
    "unique_cardholders": 4291,
    "offer_impressions": 38420,
    "offer_add_successes": 5102,
    "redemptions": 612
  }
}

Paginação

Os endpoints de lista retornam uma string pagination.next_cursor quando há mais linhas disponíveis. Devolva-a como o parâmetro de consulta cursor para buscar a próxima página. O cursor é opaco — trate-o como uma string arbitrária. Quando next_cursor for null, você chegou ao fim.

Conectando a partir de uma ferramenta de BI?

Receitas prontas para copiar e colar para cURL, Python, Node.js, Google Sheets, Power BI e Metabase.

Ver receitas de integração →

Erros

Privacidade e tratamento de dados

A API da Saldo.tech é projetada em torno de identificadores tokenizados. Sua instituição gera os valores cardholder_token e card_token usando suas próprias chaves criptográficas. A Saldo.tech nunca recebe, processa ou armazena PII de portadores de cartão (nomes, e-mails, endereços ou números reais de cartão). Consulte nossa Política de Privacidade para todos os detalhes.

Ambiente de desenvolvimento

Use o endpoint de simulação para testar o emparelhamento de transações sem dados de pagamento reais:

POST /api/v1/transactions/simulate

Este endpoint aceita a mesma carga útil que o webhook de transações de produção, mas ignora o processamento de liquidação. Use-o para verificar se sua integração trata corretamente as respostas de correspondência/não correspondência.

Pronto para integrar?

Entre em contato com nossa equipe para obter suas credenciais de API e começar a desenvolver.