Launch Week 3: Five days of launches

Widgets

Overview

The Confident AI SDK exposes every Widget method on the platform. This page documents how to call these methods in all supported languages. See the introduction to install the SDK and set your API key.

Methods

Query Ad Hoc

Computes the data for a widget you define inline, without saving it to a dashboard. Branch on data.kind to read the result: the widget's type and mode say how it is drawn, not how the payload is shaped. A query accepts at most 20 lines, a topK.limit of at most 100, and a range no longer than 366 days.

from confident_ai import ConfidentAI
from confident_ai.common import CreateWidgetRequest
from confident_ai.common import FilterSet
from confident_ai.common import WidgetGranularity
from confident_ai.common import WidgetLayout
from confident_ai.common import WidgetLineConfig
from confident_ai.common import WidgetTopK

client = ConfidentAI()

result = client.widgets.query_ad_hoc(
    widget=CreateWidgetRequest(
        name="Trace volume",
        description="Traces served per day across production.",
        type="LINE",
        unit="COUNT",
        mode="TIME_SERIES",
        bucket_mode="SERIES",
        dimension="model",
        top_k=WidgetTopK(
            limit=10,
            order_by="p90_latency",
            direction="desc"
        ),
        start_time="2025-01-01T00:00:00+00:00",
        end_time="2025-01-31T23:59:59.999000+00:00",
        layout=WidgetLayout(
            x=0,
            y=0,
            w=6,
            h=2
        ),
        lines=[
            WidgetLineConfig(
                name="Traces",
                color="BLUE",
                data_model="TRACE",
                aggregation="COUNT",
                filters=FilterSet(
                    operator="AND",
                    groups=[]
                ),
                extra_query_params={"metricMetadataKey": "tokenCount"}
            )
        ]
    ),
    start_time="2025-01-01T00:00:00+00:00",
    end_time="2025-01-31T23:59:59.999000+00:00",
    granularity=WidgetGranularity.THIRTY_MINUTES,
)

For async mode, call a_query_ad_hoc and await it as shown below:

result = await client.widgets.a_query_ad_hoc(...)

Parameters

ParameterTypeDescription
widgetCreateWidgetRequestRequired. See CreateWidgetRequest.
start_timeOptional[str]The start of the range to compute over, as an ISO 8601 datetime. Must be sent together with endTime, and overrides a range set on the widget itself.
end_timeOptional[str]The end of the range to compute over, as an ISO 8601 datetime. Must be sent together with startTime, and must be later than it.
granularityOptional[WidgetGranularity]See WidgetGranularity.

Returns

This method returns an object of type AdHocWidgetQueryResult.

Types

AdHocWidgetQueryResult

The computed data for a widget that was defined inline rather than saved, so it carries no widget id.

class AdHocWidgetQueryResult:
    type: Optional[WidgetType]
    mode: Optional[WidgetMode]
    data: WidgetData

typeOptional[WidgetType]Required

The visualization the widget asked for, echoed back. It says how to draw the result, not how to read it — branch on data.kind for that.

See WidgetType.

modeOptional[WidgetMode]Required

The aggregation mode the widget asked for, echoed back. Branch on data.kind rather than on this when reading the result.

See WidgetMode.

dataWidgetDataRequired

CreateWidgetRequest

A widget to add to a dashboard: the chart to draw, the time range and breakdown to draw it over, and the lines to plot on it.

class CreateWidgetRequest:
    name: str
    description: Optional[str] = None
    type: Optional[WidgetType] = None
    unit: Optional[WidgetUnit] = None
    mode: Optional[WidgetMode] = None
    bucket_mode: Optional[WidgetBucketMode] = Field(default=None, alias="bucketMode")
    dimension: Optional[WidgetDimension] = None
    top_k: Optional[WidgetTopK] = Field(default=None, alias="topK")
    start_time: Optional[str] = Field(default=None, alias="startTime")
    end_time: Optional[str] = Field(default=None, alias="endTime")
    layout: Optional[WidgetLayout] = None
    lines: Optional[List[WidgetLineConfig]] = None

namestrRequired

The name shown as the widget's title.

Example: "Trace volume"

descriptionOptional[str]

What the widget shows. Send null to leave it unset.

Example: "Traces served per day across production."

typeOptional[WidgetType]

The visualization to draw the widget as.

See WidgetType.

Example: "LINE"

unitOptional[WidgetUnit]

The unit the widget's values are labelled with.

See WidgetUnit.

Example: "COUNT"

modeOptional[WidgetMode]

How the widget aggregates its lines. DIMENSION_SERIES requires dimension.

See WidgetMode.

Example: "TIME_SERIES"

bucket_modeOptional[WidgetBucketMode]

How the query range is bucketed. Defaults to SERIES when omitted.

See WidgetBucketMode.

Example: "SERIES"

dimensionOptional[WidgetDimension]

The property to break the widget's data down by. Required when mode is DIMENSION_SERIES.

See WidgetDimension.

Example: "model"

top_kOptional[WidgetTopK]

Caps a dimension breakdown at its top values. Send null, or omit it, to plot every value.

See WidgetTopK.

start_timeOptional[str]

The start of the widget's own time range, as an ISO 8601 datetime. Send null to let the query decide the range.

Example: "2025-01-01T00:00:00+00:00"

end_timeOptional[str]

The end of the widget's own time range, as an ISO 8601 datetime. Send null to let the query decide the range.

Example: "2025-01-31T23:59:59.999000+00:00"

layoutOptional[WidgetLayout]

Where the widget sits on the dashboard grid. Omit it, or send null, and Confident AI packs the widget into the first free space.

See WidgetLayout.

linesOptional[List[WidgetLineConfig]]

The series the widget plots.

See WidgetLineConfig.

FilterSet

A set of filter groups combined by a top-level operator. Each group combines its filter rows by its own operator, and each row matches one property, such as Name or User Id, against a value with a condition such as Is or Contains.

class FilterSet:
    operator: Literal["AND", "OR"]
    groups: List[FilterSetGroup]

operatorLiteral["AND", "OR"]Required

groupsList[FilterSetGroup]Required

WidgetAggregation

The aggregation a line computes, given as its token. Which tokens apply depends on the line's dataModel — AVG_RATING belongs to ANNOTATION lines, TOTAL_TOKENS to span lines — and a token that does not apply to the line's data model is rejected with the list of the ones that do.

class WidgetAggregation(Enum):
    AVG_COST = "AVG_COST"
    AVG_COST_PER_USER = "AVG_COST_PER_USER"
    AVG_LATENCY = "AVG_LATENCY"
    AVG_RATING = "AVG_RATING"
    AVG_SCORE = "AVG_SCORE"
    AVG_VALUE = "AVG_VALUE"
    COUNT = "COUNT"
    ERROR_COUNT = "ERROR_COUNT"
    ERROR_RATE = "ERROR_RATE"
    FAILURE_RATE = "FAILURE_RATE"
    INPUT_COST = "INPUT_COST"
    INPUT_TOKENS = "INPUT_TOKENS"
    MEDIAN_SCORE = "MEDIAN_SCORE"
    NEW_USERS = "NEW_USERS"
    OUTPUT_COST = "OUTPUT_COST"
    OUTPUT_TOKENS = "OUTPUT_TOKENS"
    P50_LATENCY = "P50_LATENCY"
    P90_LATENCY = "P90_LATENCY"
    P99_LATENCY = "P99_LATENCY"
    PASS_RATE = "PASS_RATE"
    RETENTION = "RETENTION"
    TOTAL_COST = "TOTAL_COST"
    TOTAL_TOKENS = "TOTAL_TOKENS"
    UNIQUE_END_USERS = "UNIQUE_END_USERS"
    UNIQUE_METADATA_VALUES = "UNIQUE_METADATA_VALUES"
    UNIQUE_THREADS = "UNIQUE_THREADS"
    UNIQUE_USERS = "UNIQUE_USERS"

AVG_COST · AVG_COST_PER_USER · AVG_LATENCY · AVG_RATING · AVG_SCORE · AVG_VALUE · COUNT · ERROR_COUNT · ERROR_RATE · FAILURE_RATE · INPUT_COST · INPUT_TOKENS · MEDIAN_SCORE · NEW_USERS · OUTPUT_COST · OUTPUT_TOKENS · P50_LATENCY · P90_LATENCY · P99_LATENCY · PASS_RATE · RETENTION · TOTAL_COST · TOTAL_TOKENS · UNIQUE_END_USERS · UNIQUE_METADATA_VALUES · UNIQUE_THREADS · UNIQUE_USERS

WidgetBucketMode

How a widget's data is bucketed over the query time range. SERIES splits the range into one bucket per granularity interval; RANGE aggregates the whole range into a single bucket, as a BIG_NUMBER widget wants. Defaults to SERIES.

class WidgetBucketMode(Enum):
    SERIES = "SERIES"
    RANGE = "RANGE"

SERIES · RANGE

WidgetData

A widget's computed data. Branch on kind to read it: Confident AI derives the shape from the widget's type and mode, so a DIMENSION_SERIES widget drawn as a TABLE returns TABLE data.

WidgetData = Union[
    WidgetBigNumberData,
    WidgetTimeSeriesData,
    WidgetDimensionData,
    WidgetTableData,
]

A WidgetData is one of the shapes below. Send the fields of one of them, never a mix of both.

The whole query range aggregated to one figure per line, as a BIG_NUMBER widget draws it.

class WidgetBigNumberData:
    kind: Literal["BIG_NUMBER"]
    unit: Optional[WidgetUnit]
    values: List[WidgetScalarValue]

kindLiteral["BIG_NUMBER"]Required

Marks the result as a set of headline figures.

unitOptional[WidgetUnit]Required

The unit the values are measured in, or null when the widget's lines imply none.

See WidgetUnit.

valuesList[WidgetScalarValue]Required

One figure per line on the widget.

See WidgetScalarValue.

WidgetDataModel

The entity a widget line aggregates over. It decides which aggregations, filters and extraQueryParams the line accepts.

class WidgetDataModel(Enum):
    TRACE = "TRACE"
    SPAN = "SPAN"
    LLM_SPAN = "LLM_SPAN"
    AGENT_SPAN = "AGENT_SPAN"
    RETRIEVER_SPAN = "RETRIEVER_SPAN"
    TOOL_SPAN = "TOOL_SPAN"
    CUSTOM_SPAN = "CUSTOM_SPAN"
    THREAD = "THREAD"
    END_USER = "END_USER"
    METRIC_DATA = "METRIC_DATA"
    ANNOTATION = "ANNOTATION"
    CLASSIFICATION = "CLASSIFICATION"

TRACE · SPAN · LLM_SPAN · AGENT_SPAN · RETRIEVER_SPAN · TOOL_SPAN · CUSTOM_SPAN · THREAD · END_USER · METRIC_DATA · ANNOTATION · CLASSIFICATION

WidgetDimension

The property a widget breaks its data down by, one series or table row per distinct value.

class WidgetDimension(Enum):
    PROJECT = "project"
    TRACE_NAME = "trace_name"
    SPAN_NAME = "span_name"
    MODEL = "model"
    TYPE = "type"
    THREAD_ID = "thread_id"
    TEST_CASE_ID = "test_case_id"
    TEST_RUN_ID = "test_run_id"
    END_USER = "end_user"
    CUSTOMER = "customer"
    SOURCE = "source"
    ANNOTATOR = "annotator"
    NAME = "name"
    ERROR = "error"
    PROMPT_ALIAS = "prompt_alias"
    TAG = "tag"
    LABEL = "label"
    EVALUATION_MODEL = "evaluation_model"
    PROMPT_VERSION = "prompt_version"
    PROMPT_LABEL = "prompt_label"
    PROMPT_COMMIT_HASH = "prompt_commit_hash"
    METADATA = "metadata"
    HYPERPARAMETER = "hyperparameter"
    CLASSIFIER = "classifier"
    POLARITY = "polarity"
    CLASSIFIER_LABEL = "classifier_label"
    VERSION = "version"
    VALUE = "value"
    FAILURE_SUB_MODE = "failure_sub_mode"

PROJECT · TRACE_NAME · SPAN_NAME · MODEL · TYPE · THREAD_ID · TEST_CASE_ID · TEST_RUN_ID · END_USER · CUSTOMER · SOURCE · ANNOTATOR · NAME · ERROR · PROMPT_ALIAS · TAG · LABEL · EVALUATION_MODEL · PROMPT_VERSION · PROMPT_LABEL · PROMPT_COMMIT_HASH · METADATA · HYPERPARAMETER · CLASSIFIER · POLARITY · CLASSIFIER_LABEL · VERSION · VALUE · FAILURE_SUB_MODE

WidgetGranularity

The size of each bucket in computed widget data. Left unset, Confident AI picks one from the length of the query range.

class WidgetGranularity(Enum):
    THIRTY_MINUTES = "thirty_minutes"
    HOUR = "hour"
    DAY = "day"
    WEEK = "week"
    MONTH = "month"

THIRTY_MINUTES · HOUR · DAY · WEEK · MONTH

WidgetLayout

A widget's position and size on the dashboard's 12-column grid. Omit it when creating a widget and Confident AI packs it into the first free space.

class WidgetLayout:
    x: float
    y: float
    w: float
    h: float

xfloatRequired

The widget's left edge, as a column index on the 12-column grid.

Example: 0

yfloatRequired

The widget's top edge, as a row index on the grid.

Example: 0

wfloatRequired

The widget's width in grid columns.

Example: 6

hfloatRequired

The widget's height in grid rows.

Example: 2

WidgetLineColor

The colour a line is drawn in, from the Confident AI palette. A line you create without one is assigned the next colour in the palette.

class WidgetLineColor(Enum):
    AMBER = "AMBER"
    VIOLET = "VIOLET"
    EMERALD = "EMERALD"
    BLUE = "BLUE"
    PINK = "PINK"
    CYAN = "CYAN"
    ROSE = "ROSE"
    LIME = "LIME"
    TEAL = "TEAL"
    ORANGE = "ORANGE"

AMBER · VIOLET · EMERALD · BLUE · PINK · CYAN · ROSE · LIME · TEAL · ORANGE

WidgetLineConfig

One series to plot on a widget: what to aggregate, how to aggregate it, and over which entities.

class WidgetLineConfig:
    name: str
    color: Optional[WidgetLineColor] = None
    data_model: Optional[WidgetDataModel] = Field(default=None, alias="dataModel")
    aggregation: Optional[WidgetAggregation] = None
    filters: Optional[FilterSet] = None
    extra_query_params: Optional[WidgetLineExtraQueryParams] = Field(default=None, alias="extraQueryParams")

namestrRequired

The name the line is labelled with in the legend.

Example: "Traces"

colorOptional[WidgetLineColor]

The colour to draw the line in. Omit it, or send null, to take the next colour in the palette.

See WidgetLineColor.

Example: "BLUE"

data_modelOptional[WidgetDataModel]

The entity the line aggregates over. Required whenever aggregation is set; a line without one plots nothing.

See WidgetDataModel.

Example: "TRACE"

aggregationOptional[WidgetAggregation]

The aggregation the line computes over dataModel. Must be one of the tokens that data model accepts.

See WidgetAggregation.

Example: "COUNT"

filtersOptional[FilterSet]

The filters an entity must match to be counted by this line. Send null, or omit it, to aggregate over everything the data model holds.

See FilterSet.

extra_query_paramsOptional[WidgetLineExtraQueryParams]

Advanced query parameters for the line's data model. Send null, or omit it, when the data model needs none.

See WidgetLineExtraQueryParams.

Example: {"metricMetadataKey":"tokenCount"}

WidgetLineExtraQueryParams

Advanced per-line query parameters, whose recognised keys depend on the line's dataModel. spanType restricts a SPAN line to one span type; metricMetadataKey names the metadata field a span, trace or thread line aggregates; category and metricName pick out the metric a METRIC_DATA line reads; dataType and source say which annotations an ANNOTATION line counts. Unrecognised keys are ignored, and most lines send none of these.

WidgetMode

How a widget aggregates its lines. TIME_SERIES plots each configured line over time; DIMENSION_SERIES takes a single metric and splits it into one series per value of the widget's dimension. This is the widget's saved configuration — the shape of a query response is given by kind on the result.

class WidgetMode(Enum):
    TIME_SERIES = "TIME_SERIES"
    DIMENSION_SERIES = "DIMENSION_SERIES"

TIME_SERIES · DIMENSION_SERIES

WidgetScalarValue

One headline figure of a big number widget.

class WidgetScalarValue:
    key: str
    name: str
    color: WidgetLineColor
    line_id: Optional[str] = Field(default=None, alias="lineId")
    value: Optional[float]

keystrRequired

A key that identifies this series within the result, unique across the result and stable between queries. Use it as a render key, or to line results up across queries.

Example: "Traces"

namestrRequired

The label to show for the series.

Example: "Traces"

colorWidgetLineColorRequired

line_idOptional[str]

The id of the widget line this series was computed from, when one line produced it.

Example: "<LINE-ID>"

valueOptional[float]Required

The aggregated value over the whole query range, or null when there was nothing to aggregate.

Example: 3814

WidgetSeries

One plotted series of a time series or dimension breakdown.

class WidgetSeries:
    key: str
    name: str
    color: WidgetLineColor
    line_id: Optional[str] = Field(default=None, alias="lineId")
    points: List[WidgetSeriesPoint]

keystrRequired

A key that identifies this series within the result, unique across the result and stable between queries. Use it as a render key, or to line results up across queries.

Example: "Traces"

namestrRequired

The label to show for the series.

Example: "Traces"

colorWidgetLineColorRequired

line_idOptional[str]

The id of the widget line this series was computed from, when one line produced it.

Example: "<LINE-ID>"

pointsList[WidgetSeriesPoint]Required

The series' points, ordered by time for TIME_SERIES data and by the order the dimension values were ranked in for DIMENSION data.

See WidgetSeriesPoint.

WidgetSeriesPoint

One plotted point of a series.

class WidgetSeriesPoint:
    x: str
    y: Optional[float]

xstrRequired

The point's position along the x axis: the start of the time bucket for TIME_SERIES data, the dimension value for DIMENSION data.

Example: "2025-01-15T00:00:00+00:00"

yOptional[float]Required

The aggregated value at this point, or null when the bucket held nothing to aggregate.

Example: 128

WidgetTableColumn

One column of a table widget's result.

class WidgetTableColumn:
    key: str
    label: str

keystrRequired

The key each row holds this column's value under.

Example: "Traces"

labelstrRequired

The label to show in the column header.

Example: "Traces"

WidgetTopK

Caps a dimension breakdown at the most interesting values, so a dimension with thousands of values still plots.

class WidgetTopK:
    limit: Optional[int] = None
    order_by: Optional[Literal["count", "avg_latency", "p50_latency", "p90_latency", "p99_latency", "error_rate", "pass_rate", "failure_rate", "input_cost", "output_cost", "total_cost", "avg_cost", "input_tokens", "output_tokens", "total_tokens", "count_distinct_endUserId", "count_distinct_threadId", "count_distinct_model", "count_distinct_projectId", "count_distinct_error", "count_distinct_metadata", "error_count", "pass_count", "avg_score", "stddev_score", "median_score", "avg_rating", "avg_value", "score_histogram", "created_at", "start_time", "dimension"]] = Field(default=None, alias="orderBy")
    direction: Optional[Literal["asc", "desc"]] = None

limitOptional[int]

The number of series or rows to keep, taking the highest or lowest by orderBy. Defaults to 10.

Example: 10

order_byOptional[Literal["count", "avg_latency", "p50_latency", "p90_latency", "p99_latency", "error_rate", "pass_rate", "failure_rate", "input_cost", "output_cost", "total_cost", "avg_cost", "input_tokens", "output_tokens", "total_tokens", "count_distinct_endUserId", "count_distinct_threadId", "count_distinct_model", "count_distinct_projectId", "count_distinct_error", "count_distinct_metadata", "error_count", "pass_count", "avg_score", "stddev_score", "median_score", "avg_rating", "avg_value", "score_histogram", "created_at", "start_time", "dimension"]]

The metric or column the dimension values are ranked by. Defaults to count.

Example: "p90_latency"

directionOptional[Literal["asc", "desc"]]

Whether to keep the highest ranked values or the lowest. Defaults to desc.

Example: "desc"

WidgetType

The visualization a widget is drawn as. It is how the widget is displayed and does not by itself decide the shape of a query response — a TABLE widget returns tabular data whatever its mode is.

class WidgetType(Enum):
    LINE = "LINE"
    AREA = "AREA"
    BAR = "BAR"
    STACKED_BAR = "STACKED_BAR"
    GROUPED_BAR = "GROUPED_BAR"
    TABLE = "TABLE"
    BIG_NUMBER = "BIG_NUMBER"

LINE · AREA · BAR · STACKED_BAR · GROUPED_BAR · TABLE · BIG_NUMBER

WidgetUnit

The unit a widget's values are measured in.

class WidgetUnit(Enum):
    COUNT = "COUNT"
    PERCENT = "PERCENT"
    SCORE = "SCORE"
    SECONDS = "SECONDS"
    USD = "USD"
    MILLISECONDS = "MILLISECONDS"

COUNT · PERCENT · SCORE · SECONDS · USD · MILLISECONDS

Building a production pipeline?Design a scalable API workflow for evals, datasets, traces, and promptsTalk to an engineer

Last updated on

Built byConfident AI