RPG For Developers
Nesta página
RPG FOR DEVELOPERS

Da sua chave ao primeiro dado.

Guia completo do RPG Connecta: chaves API, sandbox, consentimento bancário, dados, webhooks e produção. Documentação pública para pessoas e agentes.

https://www.rpgcapital.com.br/api/connecta/v1

01

Da conta à primeira resposta

Entre com Google no console. Escolha Sandbox, crie uma chave com nome e guarde o valor completo imediatamente: ele aparece uma única vez. Não precisa cadastrar aplicativo, informar URL de site ou ter conta na Malvo.

Salve a chave como RPG_API_KEY no backend. Crie uma conexão fictícia, guarde data.id como RPG_CONNECTION_ID e consulte contas e transações. Os exemplos abaixo executam fora do console; as consultas no console usam sua sessão autenticada.

  • 1. Crie sua chave RPG de sandbox.
  • 2. Execute o quickstart e guarde o ID da conexão.
  • 3. Explore o JSON, altere cenários e acompanhe eventos.
cURL + jq
# Requires bash, curl and jq. Store your sandbox key in RPG_API_KEY.
set -euo pipefail
: "${RPG_API_KEY:?Set RPG_API_KEY in your shell}"
BASE='https://www.rpgcapital.com.br/api/connecta/v1'
CONNECTION_ID=$(curl --fail-with-body -sS "$BASE/connections" \
  -H "Authorization: Bearer $RPG_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"provider":"rpg_simulator","scenario":"success"}' | jq -er '.data.id')
curl --fail-with-body -sS "$BASE/connections/$CONNECTION_ID/accounts" \
  -H "Authorization: Bearer $RPG_API_KEY"
curl --fail-with-body -sS "$BASE/connections/$CONNECTION_ID/transactions?offset=0" \
  -H "Authorization: Bearer $RPG_API_KEY"
02

Chaves, permissões e ambientes

Envie Authorization: Bearer seguido da chave RPG em toda chamada. rpg_test_ identifica sandbox; rpg_live_ identifica produção. O cabeçalho opcional X-RPG-Environment deve corresponder à chave. A credencial acessa somente conexões do seu titular e ambiente.

Guarde segredos em variáveis do servidor ou gerenciador de segredos. Nunca em código do navegador, prompts públicos, logs ou Git. Renomeie pelo console; para rotacionar, crie uma substituta, atualize o backend e revogue a antiga. A revogação é imediata.

  • Limite: 10 chaves ativas por usuário e ambiente.
  • Limite: 60 requisições por minuto por chave. Respeite Retry-After no HTTP 429.
  • Limite: 20 conexões ativas por usuário e ambiente.
03

Um sandbox completo dentro do painel

O simulador RPG mantém contas e transações fictícias por conexão. Use provider=rpg_simulator e depois POST /connections/{id}/simulate com um cenário. Não conecta banco, não exige cartão e não faz pagamento real.

success gera uma base completa; pending aguarda autorização; expired pede renovação; unavailable simula indisponibilidade; partial expõe dados incompletos. Dados válidos anteriores podem continuar visíveis em indisponibilidade ou pendência: consulte status e last_synced_at.

O sandbox Malvo dedicado é outro adaptador e depende de credenciais próprias configuradas pela RPG. Sua disponibilidade aparece nas opções avançadas. A prévia anônima /developers/sandbox/data é uma base pequena separada, não seu workspace persistente.

  • Use success após outro cenário para restaurar a base fictícia completa.
  • Reutilize IDs nas execuções e desconecte bases que não usa mais.
04

Produção e consentimento bancário

Ative Produção explicitamente no console, crie uma chave desse ambiente e envie POST /connections com {"provider":"malvo"}. A RPG autentica no servidor com a própria conta Malvo. A resposta traz connect_url temporária para o titular autorizar acesso bancário. Não registre nem deixe agentes abrirem ou pré-visualizarem esse link automaticamente.

A conexão pertence à conta RPG do desenvolvedor. Em integrações para clientes finais, seu backend deve associá-la ao cliente autenticado e verificar essa associação antes de devolver dados. Nunca entregue a chave RPG ao navegador do cliente.

Após a autorização, seu backend envia POST /connections/{id}/complete com {"item_id":"ID retornado"}. A RPG verifica a titularidade no provedor. O retorno /developers/connect conclui o fluxo de um desenvolvedor logado; a jornada de cliente final exige conclusão pelo seu próprio backend autenticado.

Consulte GET /connections/{id} para acompanhar o estado. POST /sync lê os dados disponíveis no provedor, sem garantir nova atualização bancária. POST /reconnect gera novo link de consentimento. DELETE /connections/{id} desconecta e remove o snapshot local.

  • Produção utiliza dados reais e exige consentimento do titular.
  • O gateway de cobrança não está habilitado; ativar produção não cobra cartão.
  • Cobertura e disponibilidade bancárias dependem do provedor e da instituição.
05

Um contrato de dados previsível

As respostas são JSON. Listas têm data, pagination e meta. Valores monetários usam inteiros na menor unidade: 185000 BRL significa R$ 1.850,00. Preserve a moeda ao exibir ou somar valores. Transações positivas representam entradas; negativas representam saídas.

IDs identificam registros da origem: guarde-os para conciliação. Categoria pode ser texto, objeto do provedor ou null. Etiquetas podem não existir na origem; classificação ausente não significa ausência de atividade. Trate datas e campos ausentes explicitamente.

A resposta abaixo é ilustrativa. IDs, datas, categorias, registros e saldos reais podem variar. Os recursos publicados hoje são contas e transações; investimentos, relatórios de crédito, cartões e pagamentos não são recursos adicionais desta API.

    JSON
    {
      "data": [{
        "id": "CONNECTION_ID_tx_1",
        "account_id": "CONNECTION_ID_checking",
        "date": "2026-10-31",
        "description": "Recebimento de cliente",
        "amount_minor": 185000,
        "currency": "BRL",
        "category": "Receitas",
        "tags": ["synthetic", "sandbox"]
      }],
      "pagination": {"offset": 0, "limit": 100, "total": 1, "next_offset": null},
      "meta": {"environment":"sandbox", "provider":"rpg_simulator", "synthetic":true, "status":"connected", "last_synced_at":"2026-10-31T12:00:00Z", "partial":false, "note":null}
    }
    06

    Paginação, dados parciais e atualização

    Contas e transações aceitam offset inteiro não negativo. Cada página tem até 100 registros. Siga pagination.next_offset até null; transações também aceitam account_id. A primeira página pode não conter todo o histórico.

    meta.partial e meta.status descrevem o snapshot. Mostre last_synced_at e um indicador de incompletude no produto. HTTP de sucesso pode trazer dados antigos ou parciais. O saldo não tem garantia de atualização em tempo real.

    A coleta do provedor tem limites; históricos grandes podem ficar parciais. Repetir sync não remove esses limites. Eventos e requisições expõem os últimos 100 registros; o console mostra um histórico recente menor. Persista o histórico necessário para seu produto.

    07

    Exemplos completos para executar

    Use Node.js 18+ ou Python 3 com biblioteca padrão; não precisa instalar SDK. Exporte RPG_API_KEY no terminal com sua chave de sandbox. Salve o exemplo no arquivo indicado no primeiro comentário e execute.

    Defina RPG_CONNECTION_ID para reutilizar a base nas próximas execuções. Os exemplos criam uma conexão fictícia somente quando essa variável não existe, consultam contas e percorrem as páginas de transações. Falhas incluem os detalhes retornados pelo servidor.

      Node.js 18+
      // Node.js 18+. Save as quickstart.mjs; run: node quickstart.mjs
      const base = 'https://www.rpgcapital.com.br/api/connecta/v1';
      const key = process.env.RPG_API_KEY;
      if (!key?.startsWith('rpg_test_')) throw new Error('Use a sandbox RPG_API_KEY');
      async function api(path, body) {
        const response = await fetch(base + path, {
          method: body ? 'POST' : 'GET',
          signal: AbortSignal.timeout(30000),
          headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
          ...(body ? { body: JSON.stringify(body) } : {})
        });
        const payload = await response.json();
        if (!response.ok) throw new Error(`${response.status} ${payload.error?.code}: ${payload.error?.message} [${payload.request_id}]`);
        return payload;
      }
      // Reuse RPG_CONNECTION_ID on subsequent runs to avoid creating duplicate fixtures.
      const id = process.env.RPG_CONNECTION_ID || (await api('/connections', {
        provider: 'rpg_simulator', scenario: 'success'
      })).data.id;
      console.log('Connection:', id);
      console.log('Accounts:', (await api(`/connections/${id}/accounts`)).data);
      const transactions = [];
      let offset = 0;
      do {
        const page = await api(`/connections/${id}/transactions?offset=${offset}`);
        transactions.push(...page.data);
        offset = page.pagination.next_offset;
      } while (offset !== null);
      console.log('Transactions:', transactions);
      Python 3
      # Python 3, standard library only. Save as quickstart.py.
      import json, os, urllib.request, urllib.error
      BASE = 'https://www.rpgcapital.com.br/api/connecta/v1'
      KEY = os.environ.get('RPG_API_KEY', '')
      if not KEY.startswith('rpg_test_'):
          raise RuntimeError('Use a sandbox RPG_API_KEY')
      def api(path, body=None):
          request = urllib.request.Request(BASE + path,
              data=json.dumps(body).encode() if body is not None else None,
              headers={'Authorization': 'Bearer ' + KEY, 'Content-Type': 'application/json'})
          try:
              with urllib.request.urlopen(request, timeout=30) as response:
                  return json.load(response)
          except urllib.error.HTTPError as error:
              details = json.load(error)
              raise RuntimeError(f'{error.code}: {details}') from error
      connection_id = os.environ.get('RPG_CONNECTION_ID') or api('/connections',
          {'provider': 'rpg_simulator', 'scenario': 'success'})['data']['id']
      print('Connection:', connection_id)
      print('Accounts:', api(f'/connections/{connection_id}/accounts')['data'])
      transactions, offset = [], 0
      while offset is not None:
          page = api(f'/connections/{connection_id}/transactions?offset={offset}')
          transactions.extend(page['data'])
          offset = page['pagination']['next_offset']
      print('Transactions:', transactions)
      08

      Webhooks assinados e processamento seguro

      Configure um endpoint HTTPS público por ambiente no console. Copie o segredo de assinatura quando aparecer. RPG-Signature contém t=<timestamp Unix>,v1=<HMAC hexadecimal>. Calcule HMAC-SHA256(segredo, timestamp + "." + corpo bruto). Valide antes de interpretar ou processar os dados e rejeite diferenças de horário superiores a cinco minutos.

      Use o ID do evento como chave única persistente. Grave o recebimento e enfileire o trabalho de negócio atomicamente; reentregas não podem repetir efeitos financeiros. O exemplo valida assinaturas e não executa operação de negócio: adicione persistência antes de processar eventos em produção.

      O console mostra a entrega e permite reenvio manual. Não há retentativas automáticas. Eventos automáticos de entrada da Malvo também exigem configuração de segredo pela RPG; na ausência, use conclusão e sync explícito. Trate o evento como sinal para consultar o estado canônico da conexão.

        Node.js · Webhook
        // Node.js 18+, no framework. Terminate HTTPS at your public hosting provider.
        import http from 'node:http';
        import { createHmac, timingSafeEqual } from 'node:crypto';
        const secret = process.env.RPG_WEBHOOK_SECRET;
        if (!secret) throw new Error('Set RPG_WEBHOOK_SECRET');
        http.createServer(async (req, res) => {
          if (req.method !== 'POST' || req.url !== '/webhooks/rpg') { res.writeHead(404).end(); return; }
          const chunks = []; let size = 0;
          for await (const chunk of req) {
            size += chunk.length;
            if (size > 1_000_000) { res.writeHead(413).end(); return; }
            chunks.push(chunk);
          }
          const raw = Buffer.concat(chunks);
          const parts = String(req.headers['rpg-signature'] || '').split(',');
          const t = parts.find(p => p.startsWith('t='))?.slice(2) || '';
          if (!/^\d+$/.test(t) || Math.abs(Date.now()/1000 - Number(t)) > 300) { res.writeHead(401).end(); return; }
          const expected = createHmac('sha256', secret).update(t + '.').update(raw).digest();
          const valid = parts.filter(p => p.startsWith('v1=')).some(p => {
            const hex = p.slice(3); if (!/^[a-f0-9]{64}$/.test(hex)) return false;
            return timingSafeEqual(Buffer.from(hex, 'hex'), expected);
          });
          if (!valid) { res.writeHead(401).end(); return; }
          try {
            const event = JSON.parse(raw.toString('utf8'));
            // REQUIRED: persist event.id with a UNIQUE constraint in your database,
            // and enqueue the business effect in the same transaction (outbox pattern).
            // Duplicate event IDs must become a no-op, including after restarts.
            // This signature example intentionally performs no business effect.
            res.writeHead(200, {'Content-Type':'application/json'}).end(JSON.stringify({received:true,id:event.id}));
          } catch { res.writeHead(400).end(); }
        }).listen(Number(process.env.PORT || 3000));
        09

        Erros com uma próxima ação clara

        Erros têm error.code, error.message e request_id; X-Request-ID também é retornado. Ao pedir suporte, envie o request ID, nunca a chave nem conteúdo financeiro.

        Em falhas transitórias, use retentativas limitadas com espera exponencial e variação aleatória. Respeite Retry-After. Não repita POST /connections cegamente após timeout ambíguo: liste as conexões para evitar duplicação. Não existe contrato publicado de chave de idempotência.

          JSON
          {
            "error": {
              "code": "environment_mismatch",
              "message": "Esta chave pertence a outro ambiente."
            },
            "request_id": "uuid"
          }
          10

          Monte um dashboard útil

          Comece por uma rota no servidor que consulte a conexão associada ao cliente autenticado. Percorra páginas de contas e transações, preserve IDs e exiba saldos por moeda. Separe entradas e saídas; agrupe por mês e categoria mantendo categorias desconhecidas visíveis.

          Mostre estado, última sincronização, dados parciais e ação de reconexão junto aos dados. HTTP 401 deve oferecer nova autenticação ou correção da credencial. Em falha bancária, preserve o último snapshot válido com data. Teste os cinco estados do sandbox antes de produção.

          11

          Instruções para agentes de programação

          Leia este guia e o OpenAPI antes de gerar código. Use o Markdown em inglês como entrada compacta. Mantenha placeholders para credenciais; oriente a pessoa a criar a chave no console e guardá-la nos segredos do backend.

          Gere integração no servidor, associação de titularidade, paginação, validação de assinatura e erros com request IDs. Comece pelo sandbox. Não invente endpoints MCP, skills instaláveis, pacotes SDK, cobertura bancária, preços ou recursos de pagamento.

          O agente pode criar código e explicar a autorização. Login Google, consentimento bancário e ativação devem permanecer visíveis à pessoa e respeitar ferramentas de autenticação e permissões disponíveis no ambiente do agente.

          12

          Preparação para produção e limites atuais

          Antes de lançar: rotacione credenciais de desenvolvimento, isole segredos por ambiente, confira titularidade dos clientes, teste consentimento expirado e dados parciais, valide assinaturas sobre corpo bruto e deduplicação persistente, e confirme monitoramento e suporte.

          Disponível: login Google, chaves RPG, simulador persistente, adaptador Malvo de produção, contas, transações, eventos, diagnóstico de requisições e webhooks assinados com reenvio manual. Sandbox Malvo dedicado e eventos automáticos dependem da configuração do servidor.

          Ainda não há servidor MCP publicado, SDK empacotado, retentativas automáticas ou gateway de cobrança. A API legada de lojas em /api/public/v1 e /developers/docs tem outro contrato e não usa chaves Connecta. Contato: comercial@rpgcapital.com.br.

          HTTP API

          MétodoEndpointFinalidade
          GET/connectionsListar suas conexões
          POST/connectionsCriar conexão fictícia ou de consentimento bancário
          GET/connections/{id}Consultar estado da conexão
          GET/connections/{id}/accountsConsultar contas e saldos; paginação por offset
          GET/connections/{id}/transactionsConsultar transações; filtros offset e account_id
          POST/connections/{id}/simulateAlterar cenário do simulador RPG
          POST/connections/{id}/syncLer o snapshot mais recente do provedor
          POST/connections/{id}/completeVerificar e vincular o item autorizado
          POST/connections/{id}/reconnectGerar novo link de consentimento bancário
          DELETE/connections/{id}Desconectar e apagar o snapshot local
          GET/eventsConsultar os últimos 100 eventos
          GET/requestsConsultar as últimas 100 requisições

          Dicionário de dados

          idIdentificador estável na origem; preserve para conciliação
          account_idConta associada à transação
          name / typeNome de exibição e tipo da conta
          balance_minorSaldo inteiro na menor unidade monetária
          amount_minorValor inteiro com sinal na menor unidade monetária
          currencyCódigo explícito da moeda; não misture moedas
          dateData da transação na origem; trate ausências
          descriptionDescrição original da transação
          categoryTexto, objeto ou null; trate todos os formatos
          tagsClassificação; cobertura depende da origem
          pagination.next_offsetPróximo offset, ou null quando acabar
          meta.synthetic / providerIndica dado fictício e o provedor de origem
          meta.status / partialEstado da conexão e indicação de incompletude
          meta.last_synced_atHorário do snapshot; exiba na interface

          Status

          StatusSignificadoPróxima ação
          401 invalid_api_keyChave ausente, inválida ou revogadaSubstitua a credencial do servidor; cookie de sessão não é chave API
          403 environment_mismatchCabeçalho e chave de ambientes diferentesUse o ambiente correto ou remova o cabeçalho opcional
          403 production_inactiveProdução ainda não ativadaAtive explicitamente no console
          404 not_foundConexão não encontrada para conta e ambienteConfira ID, titular e ambiente da chave
          409 authorization_pendingAutorização bancária incompletaConclua o consentimento antes de sincronizar
          409 connection_limit / key_limitLimite de recursos ativos atingidoRevogue chave ou desconecte conexão sem uso
          429 rate_limitedLimite de chamadas por chave atingidoEspere Retry-After e reduza consultas periódicas
          502 provider_error / provider_auth_errorFalha ou autenticação rejeitada no provedorRepita falhas transitórias; se persistir, contate a RPG
          503 provider_not_configuredCredenciais do provedor indisponíveisUse o simulador RPG ou contate o suporte
          400 invalid_scenario / invalid_offsetParâmetro inválidoUse cenário válido e offset inteiro não negativo
          BALCÃO · v12.0 · 480bb05