API e integrações

A especificação completa está em /openapi.json, em OpenAPI 3.1 — cole num cliente de API ou gere o SDK a partir dela. Esta página cobre o fluxo de autenticação e as armadilhas que a especificação não consegue impor sozinha.

Autenticação, em dois passos

A credencial de integração é uma chave de API — não um usuário. Ela não tem senha, não tem segundo fator, não entra no painel e não recupera acesso. Quem administra o cliente a cria em Equipe, ou pelo control plane:

./ops chave criar --tenant <cliente> --nome "ETL do BI" --papel viewer

Ela aparece uma vez só. O servidor guarda apenas o hash — se perder, crie outra e revogue a anterior.

1. Troque a chave por um token

curl -s -X POST https://app.adventury.com.br/v1/token \
  -H "Authorization: Bearer $ADVENTURY_KEY"

A chave vai no cabeçalho, nunca no corpo nem na URL: corpo de requisição aparece em log de aplicação com frequência, e query string aparece em log de proxy sempre.

2. Use o token nas leituras

Ele dura dois minutos e é escopado a um cliente e a um conjunto de contas. A resposta traz expires_at e tenant_id — esse último é o que vai no caminho das rotas de leitura, e não é você quem escolhe.

A vida curta é intencional: é o que permite revogar um acesso sem manter lista de revogação, e o que faz cada leitura ser verificada por assinatura, sem consultar banco nenhum.

O que uma chave nunca pode fazer

Escrever. O papel é restrito a viewer e analyst — os dois únicos que não concedem execução na plataforma de anúncio nem reescrita da classificação do relatório. A restrição está em três lugares independentes: no domínio, num CHECK do banco, e de novo na emissão do token.

Não é excesso de zelo. A permissão de execução gasta dinheiro real do cliente, e as três barreiras que a protegem — interruptor por cliente, confirmação na tela, trilha imutável — foram desenhadas para uma pessoa que decide. Uma chave no arquivo de configuração de um servidor de terceiro não passa por nenhuma delas.

Pela mesma razão, não isentamos “contas de serviço” do segundo fator. Isso criaria a única conta sem segundo fator do sistema, com leitura de tudo — exatamente a conta que um atacante procura.

Prazo e rotação

Toda chave expira; não existe opção “nunca”. O padrão é 90 dias e o teto é 365. Quando vence, a troca passa a responder 401 e a integração para — uma falha visível e reversível em minutos, em vez de uma porta que ninguém lembra de fechar.

Revogar surte efeito na próxima troca. Um token já emitido continua valendo os dois minutos que lhe restam: é o preço de a API verificar assinatura sem consultar o banco a cada requisição.

As quatro armadilhas que produzem número errado

1. Dinheiro está em micros

Todo campo terminado em _micros é um inteiro em que 1.000.000 vale uma unidade da moeda. O valor 1500000 é R$ 1,50.

Divida com aritmética inteira, nunca com ponto flutuante. Tratar micros como centavos infla tudo dez mil vezes — erro grande demais para passar despercebido. O perigoso é o oposto: dividir em ponto flutuante e perder um centavo por linha, que só aparece no total do mês.

2. Conversões também estão em micros

conversions_micros: 75000000 são 75 conversões, não 75 milhões. A plataforma reporta conversão fracionária por causa de atribuição parcial — é por isso que o campo não é um inteiro simples. Este erro já chegou a uma tela deste produto anunciando 75 milhões de conversões.

3. Métrica derivada não vem pronta, e não se soma

CPA, CPC, CTR, CPM e ROAS não estão nas respostas de propósito. Eles se calculam a partir dos totais somados: CPA = soma(gasto) / soma(conversões).

A média dos CPAs de dez campanhas não é o CPA do conjunto, e a diferença cresce quanto mais desiguais forem as campanhas. Se enviássemos a derivada pronta, alguém a somaria — e o resultado pareceria plausível.

4. O número de ontem pode mudar amanhã

As plataformas revisam dado já reportado por vários dias: atribuição que se completa, fraude removida, conversão que chega atrasada. Se você guarda histórico do nosso dado, reconcilie por /audit/revisions. Sem isso o seu banco diverge do nosso em silêncio, e a divergência só aparece quando alguém compara os dois relatórios numa reunião.

Isolamento entre clientes

O cliente vem sempre do caminho /v1/t/{tenantID}/… — e é conferido contra o token. Não há cabeçalho nem cookie que troque de cliente, e isso é inegociável no desenho: um “cliente atual” guardado no servidor é o estado escondido que produz o pior erro possível aqui, que é olhar o número do cliente errado acreditando ser o certo.

Um token usado no caminho de outro cliente recebe 403, e nunca uma resposta vazia. A distinção importa: vazio seria indistinguível de “não há dados”, e você concluiria a coisa errada.

O que não está publicado

Só leitura. As rotas que marcam campanha, conectam loja ou executam plano existem e não estão na especificação: elas mudam o que o painel mostra ou gastam dinheiro na plataforma do cliente, e as duas coisas passam por uma pessoa confirmando na tela, com trilha imutável. Publicar escrita antes de existir credencial de máquina revogável seria construir a porta antes da fechadura.

Especificação OpenAPI 3.1 → · Como os dados são tratados