Relatório de vendas
Relatório de vendas entre duas datas, com a série diária, o top de produtos e a receita por dia.
Três rotas para o mesmo propósito: ver como as vendas se comportaram em um intervalo de datas. report entrega tudo de uma vez (totais, série diária e os 10 produtos mais vendidos). daily e daily-revenue entregam só a série por dia; a diferença é que daily pula os dias sem pedido e daily-revenue devolve todos os dias do intervalo, com zero onde não houve venda, o que é o que um gráfico de linha precisa.
Relatório completo
/api/v1/admin/analytics/reportAdminRelatório de vendas entre duas datas
Parâmetros de consulta
startstringobrigatórioPrimeiro dia, formato
YYYY-MM-DD, no fuso da loja (America/Sao_Paulo).endstringobrigatórioÚltimo dia, formato
YYYY-MM-DD. O dia inteiro entra no cálculo.periodstringallSó o valor
all tem efeito aqui: remove o limite de 366 dias entre start e end. Qualquer outro valor é ignorado.Exemplo de requisição (report)
bash
curl "$BASE_URL/api/v1/admin/analytics/report?start=2026-10-01&end=2026-10-10" \
-H "Authorization: Bearer $TOKEN"Resposta (report)
200Relatório retornado
json
{
"stats": {
"total_orders": 6,
"total_revenue": 58587,
"pending_orders": 2,
"completed_orders": 1,
"cancelled_orders": 0,
"avg_order_value": 9764,
"unique_customers": 0,
"period": "2026-10-01 \u2014 2026-10-10",
"previous_total_orders": 0,
"previous_total_revenue": 0,
"previous_avg_order_value": 0,
"previous_unique_customers": 0,
"year_ago_total_orders": 0,
"year_ago_total_revenue": 0,
"year_ago_avg_order_value": 0,
"year_ago_unique_customers": 0
},
"daily_sales": [
{ "date": "2026-10-09", "orders": 4, "revenue": 13587 },
{ "date": "2026-10-10", "orders": 2, "revenue": 45000 }
],
"top_products": [
{ "product_id": "b02afb3d-4218-40ef-a72f-47beede28d46", "product_name": "Cafeteira Elétrica Lumina 900W", "quantity": 9, "revenue": 2691000 }
],
"generated_at": "2026-10-11T14:02:11.482Z"
}Campos da resposta
statsobjectTotais do intervalo, com os mesmos campos de Resumo de vendas. Os campos
previous_* e year_ago_* vêm sempre 0 neste relatório.daily_salesarraySérie por dia, só dos dias com pelo menos um pedido.
daily_sales[].datestringDia,
YYYY-MM-DD, no fuso da loja.daily_sales[].ordersintegerPedidos do dia.
daily_sales[].revenueintegerReceita do dia, em centavos.
top_productsarrayOs 10 produtos com mais receita no intervalo.
top_products[].product_idstringId do produto (UUID).
top_products[].product_namestringNome do produto.
top_products[].quantityintegerUnidades vendidas.
top_products[].revenueintegerReceita do produto, em centavos.
generated_atstringQuando o relatório foi calculado (RFC 3339, UTC).
Erros (report)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Falta start ou end. | {"error":"start and end query parameters are required (format: 2006-01-02)"} |
| 400 | Data fora do formato YYYY-MM-DD. | {"error":"invalid start date format; expected YYYY-MM-DD"} |
| 400 | start depois de end. | {"error":"start date must be before or equal to end date"} |
| 400 | Intervalo maior que 1 ano sem period=all. | {"error":"date range must not exceed 1 year"} |
| 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 ..."} |
Vendas por dia
/api/v1/admin/analytics/dailyAdminVendas por dia (só dias com pedido)
Parâmetros de consulta
startstringobrigatórioPrimeiro dia, formato
YYYY-MM-DD, no fuso da loja (America/Sao_Paulo).endstringobrigatórioÚltimo dia, formato
YYYY-MM-DD. O dia inteiro entra no cálculo.periodstringallSó o valor
all tem efeito aqui: remove o limite de 366 dias entre start e end. Qualquer outro valor é ignorado.Exemplo de requisição (daily)
bash
curl "$BASE_URL/api/v1/admin/analytics/daily?start=2026-10-01&end=2026-10-10" \
-H "Authorization: Bearer $TOKEN"Resposta (daily)
200Série retornada
json
{
"daily_sales": [
{ "date": "2026-10-09", "orders": 4, "revenue": 13587 },
{ "date": "2026-10-10", "orders": 2, "revenue": 45000 }
]
}Campos da resposta
daily_salesarrayUm item por dia com pedidos, em ordem de data. Lista vazia (
[]) se nenhum dia teve pedido.daily_sales[].datestringDia,
YYYY-MM-DD, no fuso da loja.daily_sales[].ordersintegerPedidos do dia.
daily_sales[].revenueintegerReceita do dia, em centavos.
Erros (daily)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Falta start ou end. | {"error":"start and end query parameters are required (format: 2006-01-02)"} |
| 400 | Data fora do formato YYYY-MM-DD. | {"error":"invalid start date format; expected YYYY-MM-DD"} |
| 400 | start depois de end. | {"error":"start date must be before or equal to end date"} |
| 400 | Intervalo maior que 1 ano sem period=all. | {"error":"date range must not exceed 1 year"} |
| 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 ..."} |
Receita por dia
/api/v1/admin/analytics/daily-revenueAdminReceita por dia (todos os dias do intervalo)
Parâmetros de consulta
startstringobrigatórioPrimeiro dia, formato
YYYY-MM-DD, no fuso da loja (America/Sao_Paulo).endstringobrigatórioÚltimo dia, formato
YYYY-MM-DD. O dia inteiro entra no cálculo.periodstringallSó o valor
all tem efeito aqui: remove o limite de 366 dias entre start e end. Qualquer outro valor é ignorado.Exemplo de requisição (daily-revenue)
bash
curl "$BASE_URL/api/v1/admin/analytics/daily-revenue?start=2026-10-01&end=2026-10-03" \
-H "Authorization: Bearer $TOKEN"Resposta (daily-revenue)
200Série retornada
json
{
"daily_revenue": [
{ "date": "2026-10-01", "revenue": 0, "orders": 0, "avg_order_value": 0 },
{ "date": "2026-10-02", "revenue": 0, "orders": 0, "avg_order_value": 0 },
{ "date": "2026-10-03", "revenue": 0, "orders": 0, "avg_order_value": 0 }
]
}Campos da resposta
daily_revenuearrayUm item para cada dia de
start a end, inclusive, mesmo sem vendas.daily_revenue[].datestringDia,
YYYY-MM-DD.daily_revenue[].revenueintegerReceita do dia, em centavos.
daily_revenue[].ordersintegerPedidos do dia.
daily_revenue[].avg_order_valueintegerTicket médio do dia, em centavos (
0 sem pedidos).Erros (daily-revenue)
| Status | Quando | Corpo |
|---|---|---|
| 400 | Falta start ou end. | {"error":"start and end query parameters are required (format: 2006-01-02)"} |
| 400 | Data fora do formato YYYY-MM-DD. | {"error":"invalid start date format; expected YYYY-MM-DD"} |
| 400 | start depois de end. | {"error":"start date must be before or equal to end date"} |
| 400 | Intervalo maior que 1 ano sem period=all. | {"error":"date range must not exceed 1 year"} |
| 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 ..."} |