Insights da Venddor Intelligence
Lê observações automáticas sobre a loja, fixa uma delas como card e gera um parágrafo explicativo para um card.
A Venddor Intelligence (VI) acompanha a loja e escreve insights: "a receita caiu 85% em 30 dias", "2 pedidos estão atrasados". Cada insight vem com uma frase explicativa, números de apoio (facts) e, quando faz sentido, a especificação de um card que mostra o dado (spec). Estas rotas permitem ler os insights, fixar um deles numa aba como card comum e pedir um parágrafo de análise para qualquer card existente.
Ler insights
/api/v1/admin/dashboards/insightsAdminLer os insights da loja
Parâmetros de consulta
langstringpt-BR, en...). Sem isso, usa Accept-Language.refreshbooleanpadrão: falsetrue ignora o cache e recalcula.Exemplo de requisição (ler)
curl "$BASE_URL/api/v1/admin/dashboards/insights?lang=pt-BR" \
-H "Authorization: Bearer $TOKEN"Resposta (ler)
{
"available": true,
"insights": [
{
"key": "signal:late_orders",
"source": "signal",
"severity": "warning",
"title_key": "admin.dashboards.vi.signal.lateOrders.title",
"body_key": "admin.dashboards.vi.signal.lateOrders.body",
"body_params": { "count": "2" },
"narrative": "Foram identificados 2 pedidos com atraso na entrega.",
"narrative_source": "llm",
"icon": "alerta",
"facts": [ { "label_key": "admin.dashboards.vi.fact.lateOrders", "value": "2", "raw": 2, "unit": "count", "tone": "down" } ],
"cta_url": "/admin/orders",
"pinnable": true,
"spec": { "spec_version": 1, "kind": "query", "title": "Pedidos atrasados", "viz": { "type": "kpi", "snippet_id": "vi-late-orders" }, "query": { "entity": "orders" } },
"width": 1,
"height": 1,
"generated_at": "2026-10-11T21:10:02Z"
}
],
"generated_at": "2026-10-11T21:10:02Z",
"cached": false,
"narrator_ready": true
}Campos da resposta
availablebooleanfalse quando não há como gerar insights; veja reason.reasonstringvi_not_configured ou no_data. Só quando available é false.insightsarray[] se não houver.insights[].keystringinsights[].sourcestringsignalpulseproactiveinsights[].severitystringinfowarningopportunityinsights[].title_keystringtitle_params. Alguns insights trazem title já em texto.insights[].body_keystringbody_params. Alguns trazem body em texto.insights[].narrativestringinsights[].narrative_sourcestringllmtemplatenarrative foi produzida: texto gerado pela VI ou modelo de texto fixo.insights[].iconstringinsights[].factsarraylabel_key, value (formatado), raw (número), unit (cents, percent, count...) e tone (up/down).insights[].cta_urlstringinsights[].pinnablebooleaninsights[].specobjectinsights[].widthintegerinsights[].heightintegerinsights[].generated_atstringgenerated_atstringcachedbooleantrue se veio do cache.narrator_readybooleanfalse quando a geração de texto pela VI está indisponível; as frases vêm de modelos fixos.Erros (ler)
| 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"} |
| 500 | Falha inesperada no servidor. | {"error":"failed to ..."} |
Criar a aba de insights
/api/v1/admin/dashboards/insights/tabAdminGarantir a aba de insights
Corpo da requisição
namestringExemplo de requisição (aba)
curl -X POST "$BASE_URL/api/v1/admin/dashboards/insights/tab" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}'Resposta (aba)
{
"dashboard": {
"id": "42475577-6012-42d8-bd1e-d60375205f42",
"slug": "vi-insights",
"name": "Insights da VI",
"panel": "A",
"visibility": "G",
"kind": "vi_insights"
},
"kind": "vi_insights"
}Campos da resposta
dashboardobjectkindstringvi_insights.Erros (aba)
| 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":"manage_dashboards"} |
| 503 | O recurso de insights não está configurado neste ambiente. | {"error":"insights engine not configured"} |
| 500 | Falha inesperada no servidor. | {"error":"failed to ..."} |
Fixar um insight
/api/v1/admin/dashboards/insights/pinAdminFixar um insight como card
Corpo da requisição
keystringobrigatóriokey do insight (de Ler insights).dashboard_iduuidwidthintegerheightintegerorderintegerExemplo de requisição (fixar)
curl -X POST "$BASE_URL/api/v1/admin/dashboards/insights/pin" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key": "signal:late_orders", "width": 1, "height": 1}'Resposta (fixar)
{
"card": {
"id": "dd3470e6-dc16-4b41-9393-23797b50d7ba",
"dashboard_id": "8da0f9c1-b05b-4809-b07d-0b36573489e7",
"spec": {
"spec_version": 1,
"kind": "query",
"title": "Receita",
"viz": { "type": "kpi", "snippet_id": "receita-semana", "number_format": { "style": "currency_cents" } },
"query": {
"entity": "orders",
"period": { "mode": "inherit" },
"metrics": [ { "id": "receita", "kind": "catalog", "ref": "orders.revenue", "status_scope": { "mode": "store_default", "include": ["Paid", "shipped", "delivered"] } } ]
}
},
"spec_version": 1,
"kind": "Q",
"title": "Receita",
"grid_row": 0,
"grid_col": 0,
"width": 1,
"height": 1,
"order": 0,
"status": "A",
"source": "M",
"created_by": "d4613dde-ac7a-431c-9232-50d8cd6ad5fc",
"created_at": "2026-10-11T21:10:41.552Z",
"updated_at": "2026-10-11T21:10:41.552Z"
},
"dashboard_id": "56a570ca-f6a1-4483-ba89-55bcea0b5c4a"
}Campos da resposta
cardobjectdashboard_iduuidErros (fixar)
| 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":"manage_dashboards"} |
| 400 | Corpo inválido: não é JSON, tem campo desconhecido (a leitura rejeita campos que a API não conhece) ou passa de 1 MB. | {"error":"invalid request body","detail":"json: unknown field \"foo\""} |
| 404 | Insight não encontrado (a chave muda com o tempo), ou aba inexistente. | {"error":"insight not found"} |
| 422 | key vazia, insight não fixável, aba de insights como destino, nenhuma aba editável, ou falha ao criar o card. | {"error":"insight is not pinnable"} |
| 503 | O recurso de insights não está configurado neste ambiente. | {"error":"insights engine not configured"} |
Narrativa de um card
/api/v1/admin/dashboards/cards/{cardId}/narrativeAdminGerar um parágrafo de análise de um card
Parâmetros de caminho
cardIduuidobrigatórioCorpo da requisição
periodobjectPeríodo a aplicar aos cards com período inherit. Mesmo formato de period na especificação. Cards com período próprio ignoram este.
modestringobrigatórioinheritpresetfixedrelativepresetstringtodayyesterdaylast7last30last90thisMonthlastMonththisQuarterthisYearlastYearmode=preset.fromstringmode=fixed: primeiro dia, YYYY-MM-DD.tostringmode=fixed: último dia, YYYY-MM-DD.last_n_daysintegermode=relative: quantos dias para trás, até 1095.fieldstringentidade.campo). Padrão: o campo de data principal da entidade.refreshbooleanpadrão: falsetrue ignora o cache.langstringExemplo de requisição (narrativa)
curl -X POST "$BASE_URL/api/v1/admin/dashboards/cards/f4368e4f-e696-4a57-9ca8-a026ba5ad694/narrative" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"lang": "pt-BR"}'Resposta (narrativa)
{
"text": "A maior parte dos pedidos está entregue; 145 seguem pendentes.",
"source": "llm",
"dataset_hash": "909130ef2a69eb9d303cbad672e6197dcafab6653d010c0223462d25a0dbd00a",
"cached": false,
"generated_at": "2026-10-11T21:20:00Z",
"narrator_ready": true
}{
"error": { "code": "no_dataset", "message_key": "admin.dashboards.err.no_dataset" }
}Campos da resposta
textstringsourcestringllmtemplatedataset_hashstringcachedbooleangenerated_atstringnarrator_readybooleanerrorobjectcode e message_key.Erros (narrativa)
| 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"} |
| 400 | Corpo inválido: não é JSON, tem campo desconhecido (a leitura rejeita campos que a API não conhece) ou passa de 1 MB. | {"error":"invalid request body","detail":"json: unknown field \"foo\""} |
| 404 | O card não existe ou a aba dele não é sua. | {"error":"card not found"} |
| 422 | A especificação gravada do card é inválida. | {"error":"invalid stored spec"} |
| 503 | O recurso de insights não está configurado neste ambiente. | {"error":"insights engine not configured"} |
| 500 | Falha inesperada no servidor. | {"error":"failed to ..."} |