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 hosthttps://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é
temProximaPaginavirfalse. Esse é o critério de parada, e não uma contagem calculada no cliente. - Uma listagem sem resultados devolve
200comregistrosvazio — 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 responde202 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; omotivoexplica o resultado. - Respostas de sucesso que não trazem
aceito(consultas,201e o202de processamento ou agendamento) significam pedido atendido ou recebido:aceitoausente não é recusa. - Uma recusa (
aceito: false) não fica guardada pelaIdempotency-Key: repetir o pedido depois deproximaJanela, 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
403de grupo econômico bloqueado traz ainda a extensãomotivo. Não a confunda com omotivodo Resultado de negócio, que vem em respostas2xx.
🕒 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 isso12.345.678/0001-99e12345678000199sã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) — vertipoOnusem 8.1. Enumerações. - Valores decimais são enviados e recebidos como
numberJSON, 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 oidentificadorProcessamentoe siga o fluxo quando a notificação chegar.
📎 Páginas Relacionadas¶
- Credenciais, autenticação e ambientes: 1.1. Primeiros Passos.
- Conceitos do produto (UR, agenda, carrinho, contrato): 2.1. Conceitos.
- Notificações assíncronas: 3.0. Visão Geral.
- Primeira chamada do fluxo: 4.1. Solicitar agenda.
- Diferenças entre v1 e v1.1: 9. Mudanças e Impacto nas Integrações.