{"openapi":"3.1.0","info":{"title":"Adventury — API de leitura","version":"1.0.0","summary":"Investimento em mídia paga, auditável, por cliente.","description":"API de LEITURA do Adventury. Ela devolve o que as plataformas de anúncio\nreportaram, exatamente como reportaram, com a trilha de quando cada número\nfoi observado.\n\n## Antes de escrever uma linha de código, quatro coisas\n\n**1. Dinheiro está em micros.** Todo campo terminado em `_micros` é um\ninteiro em que 1.000.000 vale uma unidade da moeda. Divida por 1.000.000,\ncom aritmética inteira. Tratar micros como centavos infla tudo dez mil vezes,\ne o erro é grande demais para passar despercebido — o perigoso é o inverso,\nquem divide por 1.000.000 em ponto flutuante e perde um centavo por linha.\n\n**2. Conversões TAMBÉM estão em micros.** `conversions_micros: 75000000` são\n75 conversões, não 75 milhões. A plataforma reporta conversão fracionária\npor causa de atribuição parcial, e é por isso que o campo não é inteiro.\n\n**3. Métrica derivada não vem pronta, e é de propósito.** CPA, CPC, CTR e\nROAS são calculados a partir dos totais somados — nunca pela média das\nlinhas. Enviá-los prontos convidaria a somá-los, e somar razões é errado.\n\n**4. O mesmo número pode ser reescrito depois.** As plataformas revisam\ndado já reportado por dias. Se você guarda histórico, reconcilie por\n`/audit/revisions` — sem isso o seu banco diverge do nosso em silêncio.\n\n## Autenticação, em dois passos\n\n**1. Troque a chave por um token.** A chave começa com `adv_` e vai no\ncabeçalho — nunca no corpo, nunca na URL:\n\n```\ncurl -s -X POST https://app.adventury.com.br/v1/token \\\n  -H \"Authorization: Bearer $ADVENTURY_KEY\"\n```\n\n**2. Use o token nas leituras.** Ele é assinado, dura **dois minutos** e é\nescopado a um cliente e a um conjunto de contas. Renove quando expirar —\nnão guarde, e não tente adivinhar quando falta pouco: a resposta traz\n`expires_at`.\n\nA vida curta é intencional. É o que permite revogar um acesso sem manter\nlista de revogação, e o que faz cada leitura ser verificada por assinatura,\nsem consultar banco nenhum.\n\n### O que a chave nunca pode fazer\n\n**Escrever.** O papel é restrito a `viewer` e `analyst` — os dois únicos que\nnão concedem execução na plataforma de anúncio nem reescrita da\nclassificação do relatório. A restrição está no domínio, num CHECK do banco,\ne de novo na emissão do token.\n\nNão é excesso de zelo: a permissão de execução gasta dinheiro real, e as três\nbarreiras que a protegem (interruptor por cliente, confirmação na tela,\ntrilha imutável) foram desenhadas para uma pessoa que decide. Uma chave no\narquivo de configuração de um servidor de terceiro não passa por nenhuma.\n\n### Prazo e rotação\n\nToda chave expira — não existe opção \"nunca\". O padrão é 90 dias e o teto é\n365. Quando ela vence, a troca passa a responder `401` e a integração para:\né uma falha visível e reversível, em vez de uma porta que ninguém lembra de\nfechar.\n\n## Isolamento\n\nO cliente vem sempre do CAMINHO (`/v1/t/{tenantID}/...`) e é conferido\ncontra o token. Não há cabeçalho nem cookie que troque de cliente. Um token\nusado num caminho de outro cliente recebe 403 — nunca uma resposta vazia,\nque seria indistinguível de 'não há dados'.","contact":{"name":"Adventury","url":"https://adventury.com.br"}},"servers":[{"url":"https://app.adventury.com.br","description":"Produção"}],"components":{"securitySchemes":{"chaveDeAPI":{"type":"http","scheme":"bearer","bearerFormat":"adv_...","description":"A credencial de MÁQUINA, criada por quem administra o cliente. Vale só em `POST /v1/token` — ela não abre nenhuma rota de leitura diretamente, e é isso que permite à API verificar cada requisição por assinatura, sem consultar banco."},"tokenDeAcesso":{"type":"http","scheme":"bearer","bearerFormat":"Ed25519 compacto","description":"Token de acesso assinado, com dois minutos de validade, escopado a um cliente e a um conjunto de contas. Obtido em `POST /v1/token`."}},"schemas":{"Totais":{"type":"object","description":"Métricas ADITIVAS: somar duas linhas destas produz o total correto. Note que NÃO há CPA, CPC, CTR nem ROAS aqui, e a ausência é deliberada — ver a descrição de `conversions_micros`.","properties":{"spend_micros":{"type":"integer","format":"int64","description":"Investimento em MICROS: divida por 1.000.000 para obter o valor na moeda. 1.500.000 é 1,50. Nunca use ponto flutuante para converter — multiplique e divida como inteiro."},"impressions":{"type":"integer","format":"int64","description":"Impressões."},"clicks":{"type":"integer","format":"int64","description":"Cliques."},"conversions_micros":{"type":"integer","format":"int64","description":"Conversões, TAMBÉM EM MICROS. A plataforma reporta conversões fracionárias (atribuição parcial), então a contagem não é inteira. Divida por 1.000.000 para ter o número de conversões. Exibir este campo cru já produziu um painel anunciando '75 milhões de conversões' onde havia 75."},"conversion_value_micros":{"type":"integer","format":"int64","description":"Valor das conversões reportado pela plataforma em MICROS: divida por 1.000.000 para obter o valor na moeda. 1.500.000 é 1,50. Nunca use ponto flutuante para converter — multiplique e divida como inteiro."},"currency":{"type":"string","description":"Moeda da CONTA, código ISO-4217. Contas de moedas diferentes NÃO podem ser somadas sem conversão — o total viria numericamente certo e semanticamente sem sentido."},"revisions":{"type":"integer","description":"Quantas alterações retroativas afetam este recorte. Maior que zero significa que a plataforma mudou números que já havia reportado."}}},"PontoDaSerie":{"allOf":[{"$ref":"#/components/schemas/Totais"},{"type":"object","properties":{"date":{"type":"string","format":"date","description":"O dia, no fuso da CONTA de anúncio e não em UTC. É por isso que o total de um mês pode divergir da soma de trinta dias vindos de contas em fusos diferentes."}}}]},"Campanha":{"allOf":[{"$ref":"#/components/schemas/Totais"},{"type":"object","properties":{"campaign_id":{"type":"string","description":"O identificador na plataforma. É a ÚNICA chave estável: nome de campanha muda, e casar por nome já produziu atribuição errada neste sistema quando dois clientes usaram o mesmo nome."},"campaign_name":{"type":"string"},"account_id":{"type":"string","description":"Conta de anúncio de origem."},"days":{"type":"integer","description":"Quantos dias do período tiveram entrega desta campanha."}}}]},"Conta":{"type":"object","description":"Uma conta de anúncio do cliente. O par `last_date` / `last_observed_at` é o que distingue 'a campanha caiu' de 'a coleta parou' — a segunda hipótese é a mais comum e a que ninguém checa.","properties":{"account_id":{"type":"string"},"provider":{"type":"string","enum":["meta","google","tiktok"],"description":"Rede de anúncio de origem."},"name":{"type":"string","description":"Nome da conta na plataforma. Cai no identificador quando a estrutura ainda não foi lida — nunca vem vazio."},"timezone":{"type":"string","description":"Fuso em que os dias desta conta são contados."},"last_date":{"type":"string","format":"date","nullable":true,"description":"Último DIA com dado. Nulo quando a conta nunca entregou nada."},"last_observed_at":{"type":"string","format":"date-time","nullable":true,"description":"Quando a coleta falou com esta conta pela última vez. Diferente de `last_date`: uma conta coletada há dez minutos pode ter dados só até anteontem, e isso é normal."}}},"Conversao":{"type":"object","description":"Um tipo de ação que a plataforma reporta como conversão, e o que ELE significa para este cliente.","properties":{"action_type":{"type":"string","description":"O nome da ação na plataforma."},"conversions_micros":{"type":"integer","format":"int64","description":"Volume, em micros — divida por 1.000.000 em MICROS: divida por 1.000.000 para obter o valor na moeda. 1.500.000 é 1,50. Nunca use ponto flutuante para converter — multiplique e divida como inteiro."},"value_micros":{"type":"integer","format":"int64","description":"Valor atribuído em MICROS: divida por 1.000.000 para obter o valor na moeda. 1.500.000 é 1,50. Nunca use ponto flutuante para converter — multiplique e divida como inteiro."},"kind":{"type":"string","description":"Como este cliente classificou a ação. O que estiver como não classificado NÃO entra em total nenhum, de propósito: somar uma ação cujo significado ninguém declarou é inventar resultado."}}},"Erro":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Código estável, seguro para comparar."},"message":{"type":"string","description":"Texto para pessoa. Pode mudar entre versões — não decida nada a partir dele."},"trace_id":{"type":"string","description":"Identificador da ocorrência. Cite-o ao pedir suporte."}}}}}}},"security":[{"tokenDeAcesso":[]}],"paths":{"/v1/token":{"post":{"summary":"Trocar a chave de API por um token de acesso","description":"O primeiro passo de qualquer integração. A chave (`adv_...`) vai no cabeçalho `Authorization` — **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.\n\nO token devolvido vale **dois minutos**. Renove quando expirar; a resposta traz `expires_at`.\n\nEsta é a única rota que aceita a chave. Todas as outras exigem o token.","security":[{"chaveDeAPI":[]}],"responses":{"200":{"description":"Token emitido","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"tenant_id":{"type":"string","format":"uuid","description":"O cliente desta chave. Use-o no caminho das rotas de leitura — ele não é escolhido por você."},"tenant_name":{"type":"string"},"role":{"type":"string","enum":["viewer","analyst"]},"permissions":{"type":"array","items":{"type":"string"}},"accounts":{"type":"array","items":{"type":"string"},"description":"As contas de anúncio que esta chave enxerga. `[\"*\"]` significa todas as do cliente."}}}}}},"401":{"description":"Chave ausente, malformada, vencida ou revogada. A resposta NÃO distingue os quatro casos: fazê-lo contaria a quem tenta se ele acertou o formato e se a chave já existiu.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/summary":{"get":{"summary":"Totais do período","description":"Os números aditivos do cliente inteiro na janela pedida. É a rota por onde começar: quase toda pergunta sobre desempenho é este número mais um recorte.\n\nExige a permissão `insights.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Totais"}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/insights/daily":{"get":{"summary":"Série diária","description":"Os mesmos totais, dia a dia. Some os dias e você obtém o resumo — as duas rotas nunca divergem, porque leem a mesma tabela.\n\nExige a permissão `insights.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PontoDaSerie"}}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/campaigns":{"get":{"summary":"Desempenho por campanha","description":"Uma linha por campanha com entrega no período.\n\n**Não tire média de métrica derivada entre linhas.** O CPA do conjunto é a soma dos gastos dividida pela soma das conversões — a média dos CPAs individuais dá um número que campanha nenhuma teve, e a diferença cresce com a desigualdade entre elas.\n\nExige a permissão `insights.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Campanha"}}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/accounts":{"get":{"summary":"Contas de anúncio e frescor do dado","description":"As contas do cliente com a data do último dado recebido.\n\n**Consulte isto antes de concluir que algo caiu.** Uma conta que parou de coletar produz exatamente o mesmo desenho de uma campanha que morreu, e as duas hipóteses pedem ações opostas.\n\nExige a permissão `account.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Conta"}}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/conversions":{"get":{"summary":"O que está sendo contado como conversão","description":"Os tipos de ação reportados pela plataforma e como este cliente os classificou. O que não estiver classificado não entra em total nenhum.\n\nExige a permissão `insights.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Conversao"}}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/audit/revisions":{"get":{"summary":"Alterações retroativas","description":"Números que a plataforma mudou DEPOIS de já os ter reportado.\n\nÉ a rota que responde 'esse número estava diferente ontem'. Se você guarda histórico do nosso dado, reconcilie por aqui — sem isso, o seu banco vai divergir do nosso sem que nada acuse.\n\nExige a permissão `audit.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/pacing":{"get":{"summary":"Ritmo de consumo do orçamento","description":"Quanto do orçamento contratado do mês já foi gasto e se está no ritmo. Os limiares são do servidor — recalculá-los do seu lado faria o seu alerta e o nosso painel discordarem sobre a mesma situação.\n\nExige a permissão `budget.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/plano/funil":{"get":{"summary":"Funil de mídia declarado","description":"O gasto agrupado por etapa do funil, por produto e por canal, segundo o que a equipe marcou.\n\n**As três leituras somam o mesmo total e não se somam entre si.** Existem dois baldes especiais: `não marcadas`, o gasto sem classificação, e `vários canais`, a campanha declarada em mais de um canal — que não é rateada porque a plataforma não informa a divisão, e inventar a proporção seria pior que agrupar.\n\nExige a permissão `plano.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/v1/t/{tenantID}/creatives":{"get":{"summary":"Galeria de criativos com desempenho","description":"As peças que rodaram, com os números de cada uma. A imagem vem por URL pública do nosso armazenamento — **não a guarde**: ela aponta para um objeto endereçado por conteúdo, e o endereço muda se a peça mudar.\n\nExige a permissão `creative.read`.","parameters":[{"name":"tenantID","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"O cliente. Vem SEMPRE do caminho — nunca de cabeçalho, nunca de cookie. Ele é conferido contra o token: um identificador que não bata com o do token devolve 403, e não uma resposta vazia."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Primeiro dia, AAAA-MM-DD. Omitido, o servidor escolhe uma janela padrão — não presuma qual: peça explicitamente sempre que o número for comparado com outro."},{"name":"until","in":"query","schema":{"type":"string","format":"date"},"description":"Último dia, AAAA-MM-DD. Inclusivo."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Token ausente, malformado ou vencido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"403":{"description":"O token é válido, e o escopo não. Ou ele foi emitido para outro cliente, ou o papel não inclui a permissão da rota. NÃO é 404 de propósito: esconder um erro de escopo atrás de 'não encontrado' faz quem integra procurar o problema no lugar errado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}}},"tags":[{"name":"leitura","description":"Tudo nesta especificação é leitura. As rotas de escrita existem e não estão publicadas: elas mudam o que o painel mostra ou gastam dinheiro na plataforma do cliente, e as duas coisas exigem uma pessoa confirmando na tela, com trilha."}]}