# API de CPF para plataformas SaaS: como implementar multi-tenancy

> Aprenda a implementar multi-tenancy para consultas de CPF via API em plataformas SaaS, com controle de consumo e isolamento por tenant.

**Publicado:** 07/05/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/api-de-cpf-para-plataformas-saas-como-implementar-multi-tenancy

---


Para implementar multi-tenancy com API de CPF em plataformas SaaS, o caminho é criar uma camada intermediária que isola o consumo por tenant, controla limites individuais e centraliza a chave de API no backend. Cada tenant opera com seu próprio namespace no cache, registro de consumo e faturamento proporcional. A [OWASP](https://owasp.org) recomenda que chaves de API nunca sejam expostas ao cliente final — a arquitetura de middleware resolve exatamente isso.

---

## Desafios do multi-tenancy com APIs externas

### Controle de consumo

Quando múltiplos tenants compartilham uma única chave de API, é necessário rastrear quantas consultas cada um realizou para fins de faturamento e limites.

### Isolamento de dados

Os resultados de consulta de um tenant não devem ser acessíveis por outro. Mesmo que o cache seja compartilhado, as chaves devem incluir o identificador do tenant.

### Limites diferenciados

Cada tenant pode ter um plano diferente dentro da sua plataforma SaaS, com limites de consultas distintos.

### Faturamento proporcional

O custo das consultas à API precisa ser repassado (total ou parcialmente) para cada tenant com base no seu consumo real.

---

## Arquitetura proposta

A solução consiste em uma camada intermediária (middleware) entre os tenants e a API da CPFHub.io.

### Componentes

* **Middleware de controle** -- Recebe as requisições dos tenants, verifica limites e encaminha para a API.

* **Banco de dados** -- Armazena os limites e o consumo de cada tenant.

* **Cache compartilhado** -- Redis com chaves prefixadas pelo tenant ID para isolamento.

* **Módulo de faturamento** -- Contabiliza o consumo para cobrança.

---

## Implementação em Python com Flask

```python
import requests
import redis
import json
from flask import Flask, request, jsonify
from datetime import datetime

app = Flask(__name__)

redis_client = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)

CPFHUB_API_KEY = 'SUA_CHAVE_DE_API'

# Configuracao de limites por tenant (em producao, vem do banco de dados)
TENANT_LIMITES = {
 'tenant_001': {'limite_mensal': 500, 'plano': 'basico'},
 'tenant_002': {'limite_mensal': 2000, 'plano': 'premium'},
 'tenant_003': {'limite_mensal': 100, 'plano': 'trial'}
}

def obter_consumo_mensal(tenant_id: str) -> int:
 mes_atual = datetime.now().strftime('%Y-%m')
 chave = f'cpfhub:consumo:{tenant_id}:{mes_atual}'
 consumo = redis_client.get(chave)
 return int(consumo) if consumo else 0

def incrementar_consumo(tenant_id: str):
 mes_atual = datetime.now().strftime('%Y-%m')
 chave = f'cpfhub:consumo:{tenant_id}:{mes_atual}'
 redis_client.incr(chave)
 # Expirar no final do mes seguinte
 redis_client.expire(chave, 60 * 60 * 24 * 35)

def verificar_limite(tenant_id: str) -> bool:
 config = TENANT_LIMITES.get(tenant_id)
 if not config:
 return False
 consumo = obter_consumo_mensal(tenant_id)
 return consumo < config['limite_mensal']

@app.route('/api/cpf/<cpf>')
def consultar_cpf(cpf):
 # 1. Identificar tenant
 tenant_id = request.headers.get('X-Tenant-ID')
 if not tenant_id:
 return jsonify({'error': 'Header X-Tenant-ID obrigatorio'}), 400

 if tenant_id not in TENANT_LIMITES:
 return jsonify({'error': 'Tenant nao encontrado'}), 404

 # 2. Verificar limite
 if not verificar_limite(tenant_id):
 return jsonify({
 'error': 'Limite de consultas excedido',
 'consumo': obter_consumo_mensal(tenant_id),
 'limite': TENANT_LIMITES[tenant_id]['limite_mensal']
 }), 429

 # 3. Verificar cache (isolado por tenant)
 chave_cache = f'cpfhub:cache:{tenant_id}:{cpf}'
 cacheado = redis_client.get(chave_cache)
 if cacheado:
 return jsonify(json.loads(cacheado))

 # 4. Consultar API
 url = f'https://api.cpfhub.io/cpf/{cpf}'
 headers = {
 'x-api-key': CPFHUB_API_KEY,
 'Accept': 'application/json'
 }

 try:
 response = requests.get(url, headers=headers, timeout=10)
 resultado = response.json()

 if resultado.get('success'):
 # Cachear por 1 hora
 redis_client.setex(chave_cache, 3600, json.dumps(resultado))

 # Incrementar consumo
 incrementar_consumo(tenant_id)

 return jsonify(resultado)

 except requests.exceptions.Timeout:
 return jsonify({'error': 'Timeout na consulta'}), 504
 except Exception as e:
 return jsonify({'error': str(e)}), 500

@app.route('/api/consumo')
def obter_consumo():
 tenant_id = request.headers.get('X-Tenant-ID')
 if not tenant_id:
 return jsonify({'error': 'Header X-Tenant-ID obrigatorio'}), 400

 config = TENANT_LIMITES.get(tenant_id, {})
 consumo = obter_consumo_mensal(tenant_id)

 return jsonify({
 'tenant_id': tenant_id,
 'consumo_atual': consumo,
 'limite_mensal': config.get('limite_mensal', 0),
 'restante': max(0, config.get('limite_mensal', 0) - consumo),
 'plano': config.get('plano', 'desconhecido')
 })

if __name__ == '__main__':
 app.run(port=5000)
```

---

## Controle de consumo em Node.js

```javascript
const express = require('express');
const Redis = require('ioredis');

const app = express();
const redis = new Redis();

const CPFHUB_API_KEY = 'SUA_CHAVE_DE_API';

async function verificarLimite(tenantId, limiteMensal) {
 const mesAtual = new Date().toISOString().slice(0, 7);
 const chave = `cpfhub:consumo:${tenantId}:${mesAtual}`;
 const consumo = parseInt(await redis.get(chave) || '0');
 return consumo < limiteMensal;
}

async function incrementarConsumo(tenantId) {
 const mesAtual = new Date().toISOString().slice(0, 7);
 const chave = `cpfhub:consumo:${tenantId}:${mesAtual}`;
 await redis.incr(chave);
 await redis.expire(chave, 60 * 60 * 24 * 35);
}

app.get('/api/cpf/:cpf', async (req, res) => {
 const tenantId = req.headers['x-tenant-id'];
 if (!tenantId) {
 return res.status(400).json({ error: 'Header X-Tenant-ID obrigatorio' });
 }

 const podeContinuar = await verificarLimite(tenantId, 500);
 if (!podeContinuar) {
 return res.status(429).json({ error: 'Limite de consultas excedido' });
 }

 const { cpf } = req.params;

 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), 10000);

 try {
 const response = await fetch(
 `https://api.cpfhub.io/cpf/${cpf}`,
 {
 headers: {
 'x-api-key': CPFHUB_API_KEY,
 'Accept': 'application/json'
 },
 signal: controller.signal
 }
 );

 clearTimeout(timeoutId);
 const resultado = await response.json();
 await incrementarConsumo(tenantId);

 return res.json(resultado);
 } catch (error) {
 clearTimeout(timeoutId);
 return res.status(500).json({ error: 'Erro na consulta' });
 }
});

app.listen(3000);
```

---

## Estratégias de faturamento

| Modelo | Descrição | Melhor para |
| --- | --- | --- |
| Incluso no plano | Cada plano SaaS inclui X consultas | Simplicidade |
| Pay-per-use | Cobrar por consulta realizada | Transparência |
| Créditos | Tenant compra pacotes de créditos | Flexibilidade |
| Híbrido | Base inclusa + excedente cobrado à parte | Previsibilidade com elasticidade |

---

## Boas práticas

* **Isole o cache por tenant** -- Use o tenant ID como prefixo nas chaves do Redis para evitar vazamento de dados entre clientes.

* **Registre cada consulta** -- Mantenha um log detalhado com tenant ID, CPF consultado (ou hash), timestamp e resultado para auditoria e faturamento.

* **Implemente alertas de consumo** -- Notifique o tenant quando ele atingir 80% e 100% do limite mensal.

* **Considere o plano Corporativo** -- Para plataformas SaaS com alto volume de consultas distribuídas entre múltiplos tenants, o plano Corporativo da CPFHub.io oferece limites personalizados e SLA de 99,9%.

* **Centralize a chave de API** -- Use uma única chave de API no backend da sua plataforma. Nunca exponha a chave aos tenants.

---

## Perguntas frequentes

### Como funciona o isolamento de dados entre tenants ao usar uma API de CPF compartilhada?

O isolamento é feito prefixando todas as chaves de cache e registro com o tenant ID. No Redis, uma chave como `cpfhub:cache:tenant_001:12345678900` garante que o resultado da consulta de um tenant nunca seja servido a outro, mesmo que o CPF seja idêntico. Cada tenant enxerga apenas seu próprio consumo e seus próprios resultados.

### O que acontece se um tenant ultrapassar o limite de consultas da minha plataforma SaaS?

O middleware deve retornar HTTP 429 para o tenant antes de sequer acionar a API externa. Isso protege seu orçamento e mantém a equidade entre clientes. No plano gratuito da CPFHub.io, 50 consultas mensais são incluídas sem cartão — consultas adicionais custam R$0,15 cada, sem bloqueio automático da API.

### Qual modelo de faturamento é mais indicado para SaaS com múltiplos tenants e volumes variáveis?

O modelo híbrido — base inclusa no plano + excedente cobrado à parte — costuma funcionar melhor. Ele dá previsibilidade ao tenant nos meses normais e elasticidade nos picos, sem que você absorva integralmente o custo extra. A CPFHub.io adota exatamente esse modelo: plano com cota inclusa e R$0,15 por consulta além do limite.

### Como garantir conformidade com a LGPD ao repassar consultas de CPF entre tenants e a API?

Cada tenant é um controlador de dados independente. O middleware deve registrar a finalidade da consulta, o tenant solicitante e o timestamp, sem armazenar o CPF bruto além do necessário. A [ANPD](https://www.gov.br/anpd) orienta que dados de identificação devem ser tratados com minimização e finalidade declarada — o log de consumo por tenant serve como evidência de rastreabilidade.

### Leia também

- [Como Implementar Verificação de Identidade (CPF) Segura em APIs](https://cpfhub.io/blog/verificacao-identidade-cpf-segura-apis)
- [Como Criar um Processo de Verificação de Identidade (CPF) Simples e Eficiente](https://cpfhub.io/blog/processo-verificacao-identidade-cpf-simples-eficiente)
- [APIs de verificação de identidade (CPF): Como garantir segurança na compra online](https://cpfhub.io/blog/apis-de-verificacao-de-identidade-cpf-seguranca-compra-online)
- [SLA de API de CPF: níveis de disponibilidade](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)

---

## Conclusão

Implementar multi-tenancy para consultas de CPF em plataformas SaaS exige planejamento cuidadoso de controle de consumo, isolamento de dados e faturamento. Com uma camada intermediária bem construída e o Redis para controle de limites e cache, é possível oferecer essa funcionalidade de forma escalável e transparente. A [**CPFHub.io**](https://www.cpfhub.io/)

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/)

