Especificação do card
O formato JSON que descreve um card do dashboard: tipo, visual, consulta, período, filtros e limites.
Todo card é descrito por uma especificação (spec) em JSON. As rotas de preview, de criação de card e de geração por IA devolvem ou recebem esse mesmo objeto. A especificação não contém SQL: ela diz o que medir, usando nomes do catálogo (Catálogo e modelos), e a plataforma monta e executa a consulta, com o escopo da loja já aplicado.
Estrutura geral
A especificação é estrita: qualquer campo que a API não conhece é recusado com o código unknown_field, em todos os níveis. Campos de layout (linha, coluna, largura, altura) não fazem parte dela; vão ao lado, no corpo da criação do card.
Campos do objeto spec
spec_versionintegerobrigatório11.kindstringobrigatórioquerysqlcomponentservicetextquery é o construtor sobre o catálogo (o normal). component é um bloco nativo fixo. service é um relatório pronto da plataforma. text é uma nota livre. sql é SQL escrito à mão e exige o privilégio manage_reports.titlestringobrigatóriosubtitlestringvizobjectobrigatórioqueryobjectkind=query; proibido nos outros tipos.componentobjectkind=component: { "component_id": "..." }, um de quick_actions, system_status, theme_status, recent_activity, predictive_section, seed_banner.serviceobjectkind=service: service_id (da lista fechada abaixo) e args opcional.textobjectkind=text: content (até 4000 caracteres), format (markdown ou plain) e align (start ou center).Os service_id aceitos: order_stats, sales_report, top_products, worst_products, revenue_by_category, orders_by_status, orders_by_status_for_period, orders_by_status_in_range, customer_stats, daily_revenue, repurchase_rate, top_customers, predictive_insights, e, só no painel do administrador, customer_ltv, time_between_orders, rfm_segments, sales_by_day_of_week, monthly_growth, sales_heatmap, sales_by_customer, retention_cohorts, profit_report, channel_report, channel_campaigns, dashboard_data, revenue_by_vendor, shipping_report.
O bloco viz
Campos de viz
typestringobrigatóriokpilineareabarhbarstacked_barpiedonuttableheatmapgaugesparklinefunneltreemapmap_brscattercombopivottextvi_insightnativenative é para cards component. Gráficos de barra, linha, área, pizza e rosca exigem pelo menos 1 dimensão; o mapa de calor exige 2.snippet_idstringobrigatórioreceita-semana). Não mude ao renomear o card.legendstringtopbottomleftrighthiddenpalettestringbrandcategoricalsequentialdivergingcustomcolorsarray#RRGGBB.data_labelsbooleannumber_formatobjectstyle (currency_cents, percent, integer, decimal, compact, duration_days, percent_of_total) e decimals (0 a 4).iconstringaccentstring#RRGGBB.thresholdsarrayop (lt, lte, gt, gte), value, color e label opcional.compare_displaystringbadgeserieshiddenO bloco query
Campos de query
entitystringobrigatórioperiodobjectmode: inherit (usa o período da aba ou do pedido), preset (preset: today, yesterday, last7, last30, last90, thisMonth, lastMonth, thisQuarter, thisYear, lastYear), fixed (from e to, YYYY-MM-DD) ou relative (last_n_days, até 1095). field escolhe o campo de data da entidade.compareobjectmode: none, previous_period ou previous_year.metricsarrayid e kind: catalog (ref, por exemplo orders.revenue), agg (agg: count, count_distinct, sum, avg, min, max, mais field), ratio (num e den com ids de métricas anteriores, scale: raw ou percent) ou constant (value). label é opcional.dimensionsarrayid, field (entidade.campo), grain opcional (hour, day, week, month, quarter, year) e fill_gaps para preencher períodos sem dado.filterobjectop: and ou or, com nodes) ou uma comparação (field, cmp, value ou values). Profundidade máxima 3, no máximo 40 nós, no máximo 20 valores em in.orderarrayby (id de métrica ou dimensão) e dir (asc ou desc).limitintegerpadrão: 100other_bucketbooleandrill_downobjectdetail_entity e path (ids de dimensões) para abrir as linhas por trás de um ponto do gráfico.postarrayop (cumulative, moving_avg, percent_of_total, rank), metric, window (obrigatório em moving_avg) e output_id.Operadores de filtro (cmp): eq, ne, gt, gte, lt, lte, between, in, not_in, contains, not_contains, starts_with, ends_with, is_null, is_not_null, last_n_days, next_n_days, overdue, in_set, not_in_set. last_n_days, next_n_days, is_null, is_not_null e overdue não levam value.
Exemplo completo
{
"spec_version": 1,
"kind": "query",
"title": "Receita por dia",
"viz": {
"type": "line",
"snippet_id": "receita-por-dia",
"legend": "bottom",
"number_format": { "style": "currency_cents" }
},
"query": {
"entity": "orders",
"period": { "mode": "preset", "preset": "last30" },
"metrics": [ { "id": "receita", "kind": "catalog", "ref": "orders.revenue" } ],
"dimensions": [ { "id": "dia", "field": "orders.created_at", "grain": "day", "fill_gaps": true } ],
"order": [ { "by": "dia", "dir": "asc" } ]
}
}Erros de validação
Quando a especificação é inválida, as rotas que a recebem respondem 422 com {"error":"invalid card spec","detail":"<código>: <mensagem>"} (no preview, "error":"invalid spec"). Códigos frequentes: unknown_field (campo desconhecido, ou referência que não existe no catálogo), invalid_spec_version, invalid_kind, invalid_title, invalid_viz_type, missing_snippet_id, invalid_viz_requires_dimension, too_many_metrics, too_many_dimensions, invalid_limit, invalid_period, invalid_operator, filter_too_deep, filter_too_many_nodes, invalid_kind_payload (campos do tipo errado) e invalid_status_scope. A mensagem de detail está em inglês.