Canais de aquisição
Pedidos e receita por canal de origem (UTM), campanhas de cada canal e o custo de mídia para calcular o ROAS.
Cada pedido guarda de onde o cliente veio: a plataforma lê os parâmetros de campanha (UTM), os identificadores de clique de anúncios e o site de origem, e classifica o pedido em um dos oito canais. Estas rotas mostram a receita por canal e por campanha, e permitem lançar à mão o custo de mídia de cada mês, o que habilita o cálculo do ROAS (retorno sobre o investimento em anúncios).
Relatório por canal
/api/v1/admin/analytics/channelsAdminReceita e ROAS por canal
Parâmetros de consulta
fromstringPrimeiro dia,
YYYY-MM-DD. Padrão: 30 dias atrás. Valor inválido é ignorado em silêncio.tostringÚltimo dia,
YYYY-MM-DD, inclusive. Padrão: agora. Valor inválido é ignorado em silêncio.Exemplo de requisição (channels)
bash
curl "$BASE_URL/api/v1/admin/analytics/channels?from=2026-09-01&to=2026-10-10" \
-H "Authorization: Bearer $TOKEN"Resposta (channels)
200Relatório retornado
json
{
"rows": [
{ "channel": "direct", "orders_count": 8, "revenue_cents": 492287, "aov_cents": 61535, "cost_cents": 0, "roas_bps": null }
],
"direct_share_bps": 10000
}Campos da resposta
rowsarrayUm item por canal que teve pedidos.
rows[].channelstringdirectpaid_searchpaid_socialorganic_searchorganic_socialreferralwhatsappcrmChave do canal.
rows[].orders_countintegerPedidos atribuídos ao canal.
rows[].revenue_centsintegerReceita, em centavos.
rows[].aov_centsintegerTicket médio, em centavos.
rows[].cost_centsintegerCusto de mídia lançado para o canal nos meses do intervalo, em centavos.
rows[].roas_bpsinteger|nullReceita dividida por custo, em pontos-base (
30000 = ROAS de 3,0). null quando o custo é zero.direct_share_bpsintegerParticipação do canal
direct na receita, em pontos-base. Valor alto indica pouca atribuição (links sem UTM).Erros (channels)
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 403 | O usuário não tem o privilégio exigido. | {"error":"insufficient privileges","required":"view_reports"} |
| 403 | O módulo está desligado na loja. | {"error":"module_disabled","module":"analytics"} |
| 500 | Falha ao consultar os dados. | {"error":"failed to ..."} |
Campanhas de um canal
/api/v1/admin/analytics/channels/campaignsAdminCampanhas de um canal
Parâmetros de consulta
channelstringobrigatóriodirectpaid_searchpaid_socialorganic_searchorganic_socialreferralwhatsappcrmCanal a detalhar.
fromstringPrimeiro dia,
YYYY-MM-DD. Padrão: 30 dias atrás. Valor inválido é ignorado em silêncio.tostringÚltimo dia,
YYYY-MM-DD, inclusive. Padrão: agora. Valor inválido é ignorado em silêncio.Exemplo de requisição (campaigns)
bash
curl "$BASE_URL/api/v1/admin/analytics/channels/campaigns?channel=paid_social&from=2026-09-01&to=2026-10-10" \
-H "Authorization: Bearer $TOKEN"Resposta (campaigns)
200Campanhas retornadas
json
{
"rows": [
{ "campaign": "(sem campanha)", "orders_count": 8, "revenue_cents": 492287, "cost_cents": 0, "roas_bps": null }
]
}Campos da resposta
rowsarrayUma linha por campanha do canal.
rows[].campaignstringNome da campanha (
utm_campaign) ou o texto (sem campanha). Esse texto vem em português do servidor.rows[].orders_countintegerPedidos da campanha.
rows[].revenue_centsintegerReceita, em centavos.
rows[].cost_centsintegerCusto lançado para a campanha, em centavos.
rows[].roas_bpsinteger|nullROAS em pontos-base;
null sem custo.Erros (campaigns)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Falta channel. | {"error":"channel query param required"} |
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 403 | O usuário não tem o privilégio exigido. | {"error":"insufficient privileges","required":"view_reports"} |
| 403 | O módulo está desligado na loja. | {"error":"module_disabled","module":"analytics"} |
| 500 | Falha ao consultar os dados. | {"error":"failed to ..."} |
Ler custos de mídia
/api/v1/admin/analytics/channel-costsAdminCustos de mídia de um mês
Parâmetros de consulta
monthstringMês,
YYYY-MM. Padrão: o mês atual.Exemplo de requisição (ler custos)
bash
curl "$BASE_URL/api/v1/admin/analytics/channel-costs?month=2026-10" \
-H "Authorization: Bearer $TOKEN"Resposta (ler custos)
200Custos retornados
json
[
{ "month": "2026-10-01", "channel": "paid_social", "campaign": "black-friday", "cost_cents": 150000 }
]Campos da resposta
[]arrayLinhas de custo do mês;
[] se não houver nenhuma.[].monthstringPrimeiro dia do mês,
YYYY-MM-DD.[].channelstringdirectpaid_searchpaid_socialorganic_searchorganic_socialreferralwhatsappcrmChave do canal.
[].campaignstringCampanha; vazio para o custo geral do canal.
[].cost_centsintegerCusto, em centavos.
Erros (ler custos)
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 403 | O usuário não tem o privilégio exigido. | {"error":"insufficient privileges","required":"view_reports"} |
| 403 | O módulo está desligado na loja. | {"error":"module_disabled","module":"analytics"} |
| 500 | Falha ao consultar os dados. | {"error":"failed to ..."} |
Gravar custos de mídia
/api/v1/admin/analytics/channel-costsAdminGravar custos de mídia
Corpo da requisição
[]arrayobrigatórioO corpo é uma lista JSON de linhas de custo.
monthstringobrigatórioMês,
YYYY-MM ou YYYY-MM-DD. Sempre gravado como o primeiro dia do mês.channelstringobrigatóriodirectpaid_searchpaid_socialorganic_searchorganic_socialreferralwhatsappcrmChave do canal. Maiúsculas e espaços nas pontas são normalizados.
campaignstringCampanha. Vazio para o custo geral do canal.
cost_centsintegerobrigatórioCusto do mês, em centavos.
Exemplo de requisição (gravar custos)
bash
curl -X PUT "$BASE_URL/api/v1/admin/analytics/channel-costs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[{"month": "2026-10", "channel": "paid_social", "campaign": "black-friday", "cost_cents": 150000}]'Resposta (gravar custos)
200Custos gravados
json
{
"ok": true
}Campos da resposta
okbooleantrue quando todas as linhas foram gravadas.Erros (gravar custos)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo que não é uma lista JSON. | {"error":"invalid body"} |
| 400 | channel fora das oito chaves válidas. | {"error":"invalid channel","detail":"invalid channel: \"Google\" (must be one of: direct, paid_search, paid_social, organic_search, organic_social, referral, whatsapp, crm)"} |
| 401 | Sem token, token inválido ou expirado. | {"error":"missing authorization header"} |
| 403 | O usuário não tem o privilégio exigido. | {"error":"insufficient privileges","required":"view_reports"} |
| 403 | O módulo está desligado na loja. | {"error":"module_disabled","module":"analytics"} |
| 500 | Falha ao consultar os dados. | {"error":"failed to ..."} |