Skip to main content
The Dashboard Data API provides pre-aggregated analytics for the platform’s monitoring dashboards. Data is aggregated via SQL to avoid loading large result sets.

GET /api/v1/dashboard-data

Retrieve dashboard data by type.

Query Parameters

Data Types


Response — summary

All entity counts (activeOffers, activeChannels, activeTriggers) exclude soft-deleted rows, so they always match what the corresponding list pages show. Soft-delete only sets a deletedAt timestamp — it does not change status — so these counts filter on deletedAt IS NULL in addition to status.

Response — acceptance_rate

Response — offer_performance

Response — channel_effectiveness

Response — budget_burn

Response — funnel

Every funnel stage counts live entities only (deletedAt IS NULL). “Total Offers” is all non-deleted offers, not literally every row ever created — soft-deleted offers and creatives are excluded from all four stages so the funnel stays consistent with the offers and creatives list pages. The offer_performance list is filtered the same way.

Response — attribution_summary

Response — daily_trend

Response — model_metrics_trend

Response — latency_trend

Response — offer_performance_grouped

Response — revenue_trend

Response — policy_impact

Response — score_distribution

The score_distribution type accepts groupBy values of channel, offer, or category to break down scores by dimension. Use filterId to show only scores for a specific dimension value.

Response — degraded_scoring

Returns the count of recommend calls where the scoring engine fell back to degraded mode (e.g., model timeout, missing data). totalCount is the total number of scored requests in the period.

Response — selection_frequency

Aggregates DecisionTrace.scoringResults[] and selectedOffers[] across the window. The trace sample is capped at 10,000 rows per call for latency. rankDistribution is a 10-element array covering ranks 1..10; ranks beyond 10 are not tracked. Supports optional channelId, categoryId, decisionFlowId, and segmentId filters. Example:

Response — anomaly_candidates

Severity is classified by the larger of the z-score magnitude and the absolute percent change: info at |z| >= 2 or |%| >= 15, warning at |z| >= 3 or |%| >= 30, critical at |z| >= 4 or |%| >= 50. Metrics covered: acceptance_rate (overall, per-offer, per-channel), revenue (per-offer), and degraded_scoring_rate (overall). This endpoint is stateless — it does not fire alerts; it surfaces candidates that a scheduler in a later phase may escalate. Example:

Response — why_not_ranked

For a given target offer, walks the most recent traces (capped at sampleCap) and attributes every miss to one of: contact-policy block, qualification rejection, or scored-but-outranked. When the offer was scored but not selected, the winning offer in that decision is counted toward the beatenBy list (top 5). The offerId query parameter is required; optional segmentId narrows the analysis to customers in that segment. Example:

Segment dimension on existing performance endpoints

acceptance_rate, offer_performance, offer_performance_grouped, channel_effectiveness, daily_trend, and revenue_trend all accept an optional segmentId query parameter. When provided, the underlying aggregation is restricted to interactions from customers in the segment’s materialized view. offer_performance_grouped&groupBy=segment fans the result out by active segment instead of channel/category; each offer row is decorated with segmentId and segmentName. If the segment is unknown or its view has not been materialized yet, the endpoint returns {"data": [], "warning": "..."} instead of an error, so dashboards can render a friendly notice.

Error codes

Role requirements