Pontos de atenção
Referência rápida do que você precisa saber para escrever um cliente robusto. Cada seção vai direto ao formato e ao snippet de tratamento.
Paginação
Endpoints de lista usam cursor pagination. A resposta carrega um nextPageToken. Para a próxima página, passe esse valor em pageToken.
Parâmetros:
| Parâmetro | Default | Máximo |
|---|---|---|
pageSize | 50 | 200 (valores maiores são reduzidos para 200 sem erro) |
pageToken | (vazio = primeira página) | n/a |
Quando não há mais páginas, nextPageToken vem como string vazia ou ausente.
Loop completo em pseudo-código:
token = ""
loop:
resposta = GET /v1/fichas?pageSize=200&pageToken=<token>
processa(resposta.fichas)
token = resposta.nextPageToken
se token vazio: pare
O cursor é opaco. Não decodifique nem construa cursores no seu sistema: trate como string e devolva intacto.
Formato de erros
Toda resposta de erro segue o padrão google.rpc.Status:
{
"code": 7,
"message": "Missing required scope: api.cobranca.financeiro.read",
"details": [{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "MISSING_SCOPE",
"domain": "banqer.crm.public.v1",
"metadata": {
"method": "/banqer.crm.public.v1.FichasService/ListContratosByFicha",
"scope": "api.cobranca.financeiro.read"
}
}]
}
Use o campo details[0].reason como chave para lógica de tratamento. O campo message é para log e exibição, não para parsing.
Mapeamento HTTP / gRPC / reason:
| HTTP | gRPC code | reason mais comum | Como tratar |
|---|---|---|---|
| 400 | 3 InvalidArgument | INVALID_ARGUMENT | Bug no cliente. Não retry. |
| 401 | 16 Unauthenticated | (sem body, WWW-Authenticate no header) | Renovar token e tentar uma vez. |
| 403 | 7 PermissionDenied | MISSING_SCOPE | Peça o escopo ao gestor Banqer. Não retry. |
| 404 | 5 NotFound | NOT_FOUND | Recurso inexistente ou fora da sua lista de produtos. |
| 429 | 8 ResourceExhausted | RESOURCE_EXHAUSTED | Respeite o header Retry-After. |
| 500 | 13 Internal | INTERNAL_ERROR | Erro do servidor. Retry com backoff. |
| 503 | 14 Unavailable | DB_TRANSIENT ou UNAVAILABLE | Erro transitório. Retry com backoff. |
| 504 | 4 DeadlineExceeded | DEADLINE_EXCEEDED | Timeout. Retry com backoff. |
Estratégia recomendada para erros transitórios (5xx, 429):
- Backoff exponencial com jitter: aguardar
min(2^n + random(0, 1) segundos, 30s). - Máximo de 3 tentativas para a maioria dos casos.
- Para 429, sempre respeite
Retry-Afterse vier no header.
Headers de resposta
| Header | Valor | Para que serve |
|---|---|---|
banqer-api-version | 1.0.0 (semver) | Detecção de versão para clientes de longa vida. |
content-type | application/json; charset=utf-8 | Sempre JSON em V1. |
retry-after | número de segundos | Presente em 429. Aguarde antes de retentar. |
www-authenticate | Bearer error="invalid_token" | Presente em 401. Indica que o token deve ser renovado. |
Rate limits
Há duas camadas de limite, em pontos diferentes do stack:
| Camada | Host | O que limita | Resposta |
|---|---|---|---|
| Borda Cloudflare | auth.banqer.com.br | 5 requisições / 10 s no endpoint de token, por IP | HTTP 429, bloqueio de 10 s |
| Servidor de API | api-SUA-EMPRESA.banqer.com.br | Concorrência por integrador (tier Light / Heavy) | HTTP 429 + Retry-After |
O cache em memória descrito em Autenticação mantém você abaixo do limite do token endpoint.
Limites no servidor de API
O servidor aplica limites de concorrência por integrador (não por requisições/segundo). Dois grupos:
| Grupo | Endpoints | Limite |
|---|---|---|
| Leve | A grande maioria | Concorrência alta |
| Pesado | GET /v1/acordos/{}/parcelas/{}/boleto, GET /v1/acordos/{}/boleto-consolidado | Concorrência reduzida (renderização de PDF) |
Se você atingir o limite, recebe 429 Too Many Requests com Retry-After. Em integrações que geram boletos em lote, serialize as chamadas: faça uma de cada vez ou no máximo duas em paralelo.
Versionamento
- O caminho da URL carrega a versão major:
/v1/... - Mudanças aditivas (novo endpoint, novo campo opcional, novo enum value) entram na V1 sem aviso prévio. Seu cliente deve ignorar campos desconhecidos no JSON.
- Mudanças que quebrariam clientes existentes entram em uma V2 publicada em paralelo, em
/v2/.... A V1 continua funcionando. - O header
banqer-api-versioncarrega a versão semver completa (ex:1.0.0,1.1.0). Use para detectar se um campo opcional novo já está disponível no deployment do cliente.
Códigos de exibição vs identificadores externos
A API usa dois identificadores diferentes para a maioria das entidades:
- O identificador externo é um GUID/UUID estável, usado nas URLs (
idFichaCobranca,idAcordo,idPagamento,idContrato). - O código de exibição é um inteiro curto que aparece nas telas do CRM (
idFichaCobrancaExibicao,idAcordoExibicao, etc.).
Sempre persista o GUID. O código de exibição é informativo e pode ser usado em interfaces para o operador, mas não como chave de relacionamento.
Ausência de campos opcionais
Quando um campo opcional não tem dado (e quando não está liberado por escopo), ele é omitido do JSON em vez de aparecer como null. Seu cliente deve tratar a ausência como "não disponível", não como erro de parsing. Listas vazias retornam [].
TLS e identidade do servidor
A API só responde em HTTPS. O certificado é gerenciado pela Cloudflare na borda. Não desabilite verificação de certificado em clientes de produção, mesmo em ambientes de teste.