Ir para o conteúdo

1.2. Convenções da API

🧾 Descrição

Esta página reúne as convenções transversais da API de cartão da plataforma VeFlow: base das rotas, headers obrigatórios, idempotência, paginação, códigos de resposta, formato de erro, janela de operação, formatos de dado e acompanhamento do processamento assíncrono.

Tudo o que está aqui vale para todos os endpoints v1.1 das seções 4 a 7, e por isso as páginas de endpoint apenas referenciam esta. A obtenção das credenciais, o fluxo de autenticação e a diferença entre os ambientes estão em 1.1. Primeiros Passos. Os endpoints v1 seguem as próprias páginas e o que está em 9. Mudanças e Impacto nas Integrações.


🔗 Base e Versionamento

Todas as chamadas da API de cartão partem desta base:

https://api.veflow.com/public/api/v1.1/cartao
Versão Situação Base
v1 Versão atual /public/api/v1/cartao
v1.1 Versão em testes assistidos /public/api/v1.1/cartao

Regras de convivência entre as versões:

  • As duas versões convivem no mesmo host. A publicação da v1.1 não desligou a v1.
  • Nada da v1 foi alterado: rotas, nomes de campo e comportamento seguem exatamente como estavam. Quem já integra a v1 não precisa mudar nada para continuar operando.
  • A v1.1 é a versão em evolução e concentra o fluxo completo de agenda, carrinho, contrato, liquidações e conciliação. Toda nova integração deve nascer nela.
  • O que muda de uma versão para a outra, e o impacto de migrar, está em 9. Mudanças e Impacto nas Integrações.

Nas páginas de endpoint, a coluna URL da tabela mostra a rota relativa (por exemplo /public/api/v1.1/cartao/agendas). Nos exemplos de cURL a URL aparece completa, com o host https://api.veflow.com.


📨 Headers Obrigatórios

Header Tipo Obrigatório Descrição
Authorization Bearer Token Sim Bearer Token obtido via Keycloak — ver 1.1. Primeiros Passos.
GrupoEconomico string Sim Identificador do grupo econômico, entregue na liberação do acesso. Obrigatório em toda requisição.
Content-Type string Sim nas requisições com corpo Sempre application/json. O corpo é JSON em UTF-8.
Idempotency-Key string Recomendado nas escritas (POST, PATCH, DELETE) String de até 100 caracteres — use um UUID por operação lógica. Ver a seção Idempotência abaixo.
curl -X GET "https://api.veflow.com/public/api/v1.1/cartao/agendas?indicePagina=1&tamanhoDaPagina=20" \
  -H "Authorization: Bearer {seu_token}" \
  -H "GrupoEconomico: {seu_grupo_economico}" \
  -H "Content-Type: application/json"

O header GrupoEconomico é obrigatório em todas as requisições

Ele acompanha o token em qualquer chamada, inclusive nas consultas (GET). É esse header que define em nome de qual grupo econômico a requisição é executada, e ele determina quais agendas, carrinhos e contratos ficam visíveis. Requisições sem ele são recusadas com 401.


🪞 Idempotência

Os endpoints de escrita (POST, PATCH e DELETE) aceitam o header Idempotency-Key, que protege a operação contra duplicidade em caso de retentativa. O header é recomendado, nunca obrigatório, e a chave vale por grupo econômico durante 24 horas.

Regra Comportamento
Valor da chave String de até 100 caracteres. Envie um UUID por operação lógica — uma solicitação de agenda, um contrato, um item de carrinho.
Mesma chave, mesma requisição A plataforma devolve a resposta 2xx original da primeira chamada, em vez de duplicar a operação.
Mesma chave, outra requisição (outro corpo, rota ou método) Quando a chave já guardou um sucesso, a resposta é 422 ("Idempotency-Key já usada com outra requisição."). Se a chave só registrou erro ou recusa, a nova requisição executa normalmente.
O que fica guardado Só o sucesso (2xx sem recusa). Resposta de erro e recusa de negócio (2xx com aceito: false) liberam a chave: repetir com a mesma chave executa a operação de novo — por exemplo, depois de proximaJanela.
Repetição concorrente Se a primeira chamada com a chave ainda está em processamento, a resposta é 422, informando que a requisição ainda está em processamento. Repita em instantes.
Chave nova É interpretada como uma nova operação e executa normalmente.
Retentativa automática Recomendado após timeout ou erro de rede, quando não se sabe se a chamada chegou: repita com a mesma chave — se a primeira deu certo, você recebe a resposta original em vez de duplicar a operação. Depois de um 5xx, a chave fica livre (erro não é guardado) e a repetição executa de novo: consulte o recurso antes de repetir.
curl -X POST https://api.veflow.com/public/api/v1.1/cartao/agendas \
  -H "Authorization: Bearer {seu_token}" \
  -H "GrupoEconomico: {seu_grupo_economico}" \
  -H "Idempotency-Key: 9f2c1b7e-5d84-4f3a-9c21-77bde1a4c5f0" \
  -H "Content-Type: application/json" \
  -d '{ "...": "..." }'
  • Gere o UUID antes da primeira tentativa e guarde-o junto do registro da operação no seu sistema. Uma chave gerada a cada tentativa não protege contra nada.
  • Não reaproveite a mesma chave para operações diferentes.
  • O mesmo cuidado vale no sentido inverso: nas assinaturas de notificação v1.1, cada notificação carrega o header X-Idempotency-Key, e o endpoint de callback do cliente precisa deduplicar por ele. As assinaturas v1 seguem como descrito em 3.0. Visão Geral.

📄 Paginação

Todos os endpoints de listagem são paginados e aceitam os mesmos query params:

Parâmetro Tipo Obrigatório Descrição
indicePagina integer Não Página desejada. Default 1.
tamanhoDaPagina integer Não Quantidade de registros por página. Default 20.
ordem string Não Campo de ordenação. Os campos aceitos estão na página de cada listagem.
direcaoOrdem string Não Direção da ordenação: asc ou desc, sem diferenciar maiúsculas de minúsculas.

📦 Envelope de Lista

A resposta de qualquer listagem tem sempre esta forma:

{
  "registros": [],
  "paginacao": {
    "paginaAtual": 1,
    "paginaTotal": 3,
    "paginaQuantidadeRegistro": 20,
    "quantidadeRegistros": 47,
    "temPaginaAnterior": false,
    "temProximaPagina": true
  },
  "mensagem": null
}
Campo Tipo Descrição
registros array Registros da página atual. O conteúdo de cada item é descrito na página do endpoint.
paginacao object Bloco de paginação, detalhado abaixo.
mensagem string/null Mensagem informativa opcional. Em caso de sucesso normalmente vem null.

🔹 paginacao

Campo Tipo Descrição
paginaAtual integer Página atual do retorno.
paginaTotal integer Total de páginas disponíveis.
paginaQuantidadeRegistro integer Quantidade máxima de registros por página.
quantidadeRegistros integer Total de registros encontrados.
temPaginaAnterior boolean Indica se há página anterior.
temProximaPagina boolean Indica se há próxima página.
  • Percorra as páginas até temProximaPagina vir false. Esse é o critério de parada, e não uma contagem calculada no cliente.
  • Uma listagem sem resultados devolve 200 com registros vazio — não é 404.
  • Os filtros de cada listagem são combinados com E (todos precisam ser satisfeitos) e valem junto com a paginação.

✅ Códigos de Resposta

Código Significado
200 OK Consulta atendida ou comando síncrono concluído.
201 Created Recurso criado de forma síncrona. O header Location da resposta aponta o recurso criado.
202 Accepted Requisição recebida para processamento assíncrono. A resposta devolve identificadorProcessamento para acompanhamento.
400 Bad Request Falha de validação: campo obrigatório ausente, tipo incorreto ou formato inválido — ou regra estática da requisição violada (por exemplo, tipoContrato incompatível com a modalidade, ou estratégia fora da matriz).
401 Unauthorized Falha de autenticação: token ausente, inválido ou expirado — ou header GrupoEconomico ausente.
403 Forbidden Requisição autenticada, mas sem permissão para o recurso ou para o grupo econômico informado.
404 Not Found Recurso inexistente para o grupo econômico informado (agenda, UR, item de carrinho ou contrato), ou referência que a operação não tem (por exemplo, registradora não vinculada à operação — o detalhe está na página do endpoint).
422 Unprocessable Entity Somente Idempotency-Key reusada — com outra requisição, ou enquanto a primeira ainda processa. Ver Idempotência, acima.

Um comando assíncrono nunca responde 201. Criação agendada ou enfileirada responde 202 Accepted.

📋 Resultado de negócio

Um pedido válido que não pode ser atendido — fora da janela de operação, item já contratado, agenda vencida, UR sem valor disponível ou já em outro item — não é erro HTTP. A resposta é 2xx com a entidade no status atual.

Todo resultado de negócio traz:

Campo Tipo Descrição
aceito boolean true quando o pedido foi atendido; false quando foi recusado.
motivo string[] Lista de textos que explica o resultado — numa recusa, o porquê.
proximaJanela string Quando couber: data e hora (ISO 8601 com fuso) a partir da qual o pedido pode ser repetido.

O corpo exato de cada endpoint está na página dele. Quando a resposta lista URs, o motivo de cada UR vem na própria UR.

{
  "identificador": "5174568d-9ffe-4c10-9fc2-b0f4e7f8d1b6",
  "status": 4,
  "aceito": false,
  "motivo": ["Fora do horário de operação da registradora."],
  "proximaJanela": "2025-08-11T12:00:00Z"
}
  • Quando a resposta traz aceito, é ele — e não o código HTTP — que diz se o pedido foi atendido; o motivo explica o resultado.
  • Respostas de sucesso que não trazem aceito (consultas, 201 e o 202 de processamento ou agendamento) significam pedido atendido ou recebido: aceito ausente não é recusa.
  • Uma recusa (aceito: false) não fica guardada pela Idempotency-Key: repetir o pedido depois de proximaJanela, com a mesma chave, executa a operação de novo — ver Idempotência, acima.

❌ Formato de Erro

Todo erro da v1.1 (400, 401, 403, 404 e 422) usa um único formato, o ProblemDetails, com o campo type apontando para a seção da RFC 9110 correspondente ao status:

{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "<título>",
  "status": 400,
  "errors": {
    "tipoContrato": ["Campo 'tipoContrato' inválido. Valores aceitos: 1 ou 2."]
  },
  "traceId": "<id do trace>"
}

Quando o erro não é de um campo específico (por exemplo, uma regra que vale para a requisição como um todo), a mensagem vem na chave vazia "" de errors.

Campo Tipo Descrição
type string URI da seção da RFC 9110 correspondente ao status devolvido.
title string Texto curto do erro. Pode variar: não o use em lógica.
status integer Código HTTP, igual ao status da resposta.
errors object Campo → lista de mensagens. Erro que não é de um campo vem na chave vazia "".
traceId string Identificador do rastreio da requisição. Informe-o ao suporte ao relatar um erro.

Cada chave de errors traz sempre uma lista, mesmo quando há um único problema. A plataforma valida a requisição inteira antes de responder, então uma única chamada pode devolver várias chaves e várias mensagens de uma vez. Trate errors como coleção: registre e exiba todas as mensagens, em vez de ler apenas a primeira.

O 403 de grupo econômico bloqueado traz ainda a extensão motivo. Não a confunda com o motivo do Resultado de negócio, que vem em respostas 2xx.


🕒 Janela de Operação

As operações que dependem de comunicação com as registradoras só são processadas dentro da janela de operação:

  • Horário publicado: 09:00 às 18:00, em dias úteis.
  • Horário efetivo: o horário cadastrado na registradora da operação, inclusive o horário de véspera de feriado. Feriados e fins de semana ficam fora da janela.

Fora da janela, a resposta depende da operação:

Operação Página Resposta fora da janela
Solicitação de agenda 4.1. Solicitar agenda 202 Accepted com identificador, identificadorProcessamento, dataAgendamento e mensagem.
Refazer consulta da agenda 4.7. Refazer consulta 202 Accepted com identificador, identificadorProcessamento, dataAgendamento e mensagem.
Criação de contrato 5.1. Criar contratos 200 OK com o recurso no status atual, aceito: false, motivo e proximaJanela. Sem agendamento.
Inclusão de UR no contrato 5.7. Adicionar URs ao contrato 200 OK com o recurso no status atual, aceito: false, motivo e proximaJanela. Sem agendamento.
Remoção de UR do contrato 5.8. Remover URs do contrato 200 OK com o recurso no status atual, aceito: false, motivo e proximaJanela. Sem agendamento.
Cancelamento de contrato 5.9. Cancelar contrato 200 OK com o recurso no status atual, aceito: false, motivo e proximaJanela. Sem agendamento.

Agenda fora da janela. A solicitação não é recusada: ela fica agendada e o campo dataAgendamento (YYYY-MM-DD) informa a data da próxima janela da registradora — que pode ser o próprio dia, se a chamada vier antes da abertura. O campo mensagem é apenas informativo: não o use em lógica.

{
  "identificador": "a1b2c3d4-1111-2222-3333-444455556666",
  "identificadorProcessamento": "9f2c1b7e-5d84-4f3a-9c21-77bde1a4c5f0",
  "dataAgendamento": "2025-08-11",
  "mensagem": "Solicitação recebida e agendada para a próxima janela da registradora."
}

Contrato fora da janela. A operação não é agendada: a resposta traz o contrato no status atual, aceito: false, o motivo (lista de textos) e proximaJanela (ISO 8601 com fuso), que indica quando a operação pode ser repetida — ver Resultado de negócio, acima. O exemplo abaixo é de uma operação sobre contrato já existente (5.7, 5.8 e 5.9); o corpo da criação de contratos fora da janela está em 5.1. Criar contratos.

{
  "identificador": "5174568d-9ffe-4c10-9fc2-b0f4e7f8d1b6",
  "status": 4,
  "aceito": false,
  "motivo": ["Fora do horário de operação da registradora."],
  "proximaJanela": "2025-08-11T12:00:00Z"
}

O envio de liquidações não tem limite de horário e pode ser enviado a qualquer momento. Ainda assim, envie após as 10h05: o processamento em lote das agendas roda às 10h00, e o envio feito antes disso concorre com esse lote — ver 6.1. Envio dos créditos em conta.


🔢 Formatos

Item Formato Exemplo
Nomes de campo camelCase dataPrevistaLiquidacao
Data YYYY-MM-DD 2025-08-09
Data e hora ISO 8601 2025-08-09T14:32:10Z
CNPJ Com ou sem pontuação na entrada; sempre sem pontuação nas respostas e exemplos. 14 posições, que podem conter letras (CNPJ alfanumérico), devolvidas em maiúsculas — não valide como só números 12345678000199
Identificador da UR String opaca de até 36 caracteres (GUID ou base32, conforme a operação). Não valide como GUID 3f6c2a90-8b1d-4e57-a2c4-9d0e61f7b385
Valor decimal Ponto como separador decimal, sem separador de milhar 1500.75
Valor monetário number com 2 casas decimais 1500.75
Taxa number com até 4 casas decimais 1.9900
  • O CNPJ é normalizado na entrada: pontuação (., /, -) e espaços são removidos e letras viram maiúsculas. Por isso 12.345.678/0001-99 e 12345678000199 são aceitos e tratados como o mesmo CNPJ. Nas respostas o CNPJ vem sempre sem formatação.
  • O documento do titular de ônus de terceiro (efeitos[].documentoTitular) vem mascarado (não segue o formato de 14 posições) — ver tipoOnus em 8.1. Enumerações.
  • Valores decimais são enviados e recebidos como number JSON, nunca como string com vírgula.
  • A taxa só se aplica a contratos de troca de titularidade. Contratos de garantia não têm deságio e por isso não recebem nem devolvem taxa.

⏳ Processamento Assíncrono

Operações que dependem das registradoras — consulta de agenda, registro e cancelamento de contrato, remoção de UR — são assíncronas. A resposta 202 Accepted confirma apenas o recebimento da requisição, não a conclusão do processamento. Fora da janela, vale o que está na seção Janela de Operação, acima: operação de contrato não é agendada — responde 200 com aceito: false.

Recurso Como acompanhar
identificadorProcessamento GUID devolvido no 202. Identifica o processamento e é a referência para acompanhamento e para acionar o suporte.
WebHook Forma recomendada. A plataforma notifica a conclusão na URL de callback do cliente — ver 3.0. Visão Geral.
Consulta ativa Alternativa de contingência, pelos endpoints de detalhes do recurso — por exemplo 4.3. Detalhes da agenda e 5.3. Detalhes do contrato.
  • Prefira WebHook a polling. O WebHook avisa no instante em que o processamento termina; o polling gasta chamada, atrasa a reação do seu sistema e não traz nenhuma informação adicional.
  • Use consulta ativa como contingência — quando a notificação não chegou após as retentativas, ou para reconciliar o estado depois de uma indisponibilidade do seu callback.
  • Não amarre o fluxo do usuário à resposta 202. Guarde o identificadorProcessamento e siga o fluxo quando a notificação chegar.

📎 Páginas Relacionadas