Skip to content

Result Types

Explore on DeepWiki

🤖 Result Types Reference →

Ask questions about result structures, DataFrame conversion, or type usage patterns.

All result types are immutable frozen dataclasses with:

  • Lazy DataFrame conversion via the .df property
  • JSON serialization via the .to_dict() method
  • Full type hints for IDE/mypy support

App API Types

Types for the Mixpanel App API infrastructure.

mixpanel_data.PublicWorkspace

Bases: BaseModel

A workspace within a Mixpanel project.

Represents a workspace as returned by the Mixpanel App API GET /api/app/projects/{pid}/workspaces/public endpoint. Extra fields from the API response are preserved via extra="allow".

ATTRIBUTE DESCRIPTION
id

Workspace identifier.

TYPE: int

name

Human-readable workspace name.

TYPE: str

project_id

Parent project identifier.

TYPE: int

is_default

Whether this is the default workspace.

TYPE: bool

description

Workspace description, if set.

TYPE: str | None

is_global

Whether workspace is global.

TYPE: bool | None

is_restricted

Whether workspace has restrictions.

TYPE: bool | None

is_visible

Whether workspace is visible.

TYPE: bool | None

created_iso

ISO 8601 creation timestamp.

TYPE: str | None

creator_name

Name of workspace creator.

TYPE: str | None

Example
ws = PublicWorkspace(
    id=1, name="Main", project_id=12345, is_default=True
)
assert ws.is_default is True

id instance-attribute

id: int

Workspace identifier.

name instance-attribute

name: str

Human-readable workspace name.

project_id instance-attribute

project_id: int

Parent project identifier.

is_default instance-attribute

is_default: bool

Whether this is the default workspace.

description class-attribute instance-attribute

description: str | None = None

Workspace description, if set.

is_global class-attribute instance-attribute

is_global: bool | None = None

Whether workspace is global.

is_restricted class-attribute instance-attribute

is_restricted: bool | None = None

Whether workspace has restrictions.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

Whether workspace is visible.

created_iso class-attribute instance-attribute

created_iso: str | None = None

ISO 8601 creation timestamp.

creator_name class-attribute instance-attribute

creator_name: str | None = None

Name of workspace creator.

mixpanel_data.CursorPagination

Bases: BaseModel

Cursor-based pagination metadata from App API responses.

ATTRIBUTE DESCRIPTION
page_size

Number of items per page.

TYPE: int

next_cursor

Cursor for next page, or None if last page.

TYPE: str | None

previous_cursor

Cursor for previous page.

TYPE: str | None

Example
pagination = CursorPagination(page_size=100, next_cursor="abc123")
assert pagination.next_cursor == "abc123"

page_size instance-attribute

page_size: int

Number of items per page.

next_cursor class-attribute instance-attribute

next_cursor: str | None = None

Cursor for next page (None = last page).

previous_cursor class-attribute instance-attribute

previous_cursor: str | None = None

Cursor for previous page.

mixpanel_data.PaginatedResponse

Bases: BaseModel, Generic[T]

Paginated App API response wrapper.

Generic wrapper for paginated responses from the Mixpanel App API. Contains the results list, status, and optional pagination metadata.

ATTRIBUTE DESCRIPTION
status

Response status (typically "ok").

TYPE: str

results

Page of results.

TYPE: list[T]

pagination

Pagination metadata, or None for single-page responses.

TYPE: CursorPagination | None

Example
response = PaginatedResponse[dict](
    status="ok",
    results=[{"id": 1}],
    pagination=CursorPagination(page_size=100),
)
assert len(response.results) == 1

status instance-attribute

status: str

Response status (typically "ok").

results instance-attribute

results: list[T]

Page of results.

pagination class-attribute instance-attribute

pagination: CursorPagination | None = None

Pagination metadata, or None for single-page responses.

Insights Query Types

Types for Workspace.query() — typed Insights engine queries with composable metrics, filters, and breakdowns.

mixpanel_data.Metric dataclass

Metric(
    event: str,
    math: MathType = "total",
    property: str | CustomPropertyRef | InlineCustomProperty | None = None,
    per_user: PerUserAggregation | None = None,
    percentile_value: int | float | None = None,
    filters: list[Filter] | None = None,
    filters_combinator: FiltersCombinator = "all",
    segment_method: SegmentMethod | None = None,
)

Encapsulates a single event to query with its aggregation settings.

Used with Workspace.query() to specify per-event math, property, per-user aggregation, and filters. Plain event name strings inherit top-level query defaults; Metric objects override them.

ATTRIBUTE DESCRIPTION
event

Mixpanel event name.

TYPE: str

math

Aggregation function. Default: "total".

TYPE: MathType

property

Property for property-based math types (name, ref, or inline).

TYPE: str | CustomPropertyRef | InlineCustomProperty | None

per_user

Per-user pre-aggregation (average, total, min, max).

TYPE: PerUserAggregation | None

filters

Per-metric filters (applied in addition to global where).

TYPE: list[Filter] | None

filters_combinator

How per-metric filters combine. "all" = AND (default), "any" = OR.

TYPE: FiltersCombinator

Example
from mixpanel_data import Metric

# Simple event with defaults
m1 = Metric("Login")

# With aggregation
m2 = Metric("Purchase", math="average", property="amount")

# With per-user aggregation
m3 = Metric("Purchase", math="total", per_user="average")

event instance-attribute

event: str

Mixpanel event name.

math class-attribute instance-attribute

math: MathType = 'total'

Aggregation function.

property class-attribute instance-attribute

property: str | CustomPropertyRef | InlineCustomProperty | None = None

Property for property-based math types (name, ref, or inline).

per_user class-attribute instance-attribute

per_user: PerUserAggregation | None = None

Per-user pre-aggregation type.

percentile_value class-attribute instance-attribute

percentile_value: int | float | None = None

Custom percentile value (e.g. 95 for p95).

Required when math="percentile". Ignored for other math types. Maps to percentile in bookmark JSON.

filters class-attribute instance-attribute

filters: list[Filter] | None = None

Per-metric filters (list of Filter objects).

filters_combinator class-attribute instance-attribute

filters_combinator: FiltersCombinator = 'all'

How per-metric filters combine ("all" = AND, "any" = OR).

segment_method class-attribute instance-attribute

segment_method: SegmentMethod | None = None

Segment method for counting qualifying events.

Controls how events are counted per user: "all" counts every qualifying event (default server behavior), "first" counts only the first qualifying event per user.

Maps to segmentMethod in the bookmark measurement block.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If event is empty or contains control characters (M1), math requires a property but none is set (M2), or math="percentile" but percentile_value is missing (M3).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If event is empty or contains control characters
            (M1), math requires a property but none is set (M2),
            or math="percentile" but percentile_value is missing (M3).
    """
    _validate_event_name(self.event, "Metric")
    if self.math in _MATH_REQUIRING_PROPERTY and self.property is None:
        raise ValueError(
            f"Metric math={self.math!r} requires a property "
            f"to be set (e.g., Metric({self.event!r}, math={self.math!r}, "
            f'property="your_property"))'
        )
    if self.math == "percentile" and self.percentile_value is None:
        raise ValueError(
            'Metric math="percentile" requires percentile_value '
            "(e.g., Metric(event, math='percentile', percentile_value=95))"
        )
    # M4: segment_method must be valid if set
    if self.segment_method is not None:
        valid_segments = {"all", "first"}
        if self.segment_method not in valid_segments:
            raise ValueError(
                f"Metric segment_method must be one of {sorted(valid_segments)}, "
                f"got {self.segment_method!r}"
            )

mixpanel_data.Formula dataclass

Formula(expression: str, label: str | None = None)

A formula expression referencing events by position letter (A, B, C...).

Letters map to event positions in the list passed to Workspace.query(). A is the first event, B the second, etc.

Can be passed as an element of the events list alongside strings and Metric objects, or use the top-level formula parameter for single-formula convenience.

ATTRIBUTE DESCRIPTION
expression

Formula expression, e.g. "(B / A) * 100".

TYPE: str

label

Optional display label for the formula result.

TYPE: str | None

Example
from mixpanel_data import Formula, Metric

# Formula in the events list
result = ws.query(
    [Metric("Signup", math="unique"),
     Metric("Purchase", math="unique"),
     Formula("(B / A) * 100", label="Conversion %")],
)

# Equivalent using top-level parameter
result = ws.query(
    [Metric("Signup", math="unique"),
     Metric("Purchase", math="unique")],
    formula="(B / A) * 100",
    formula_label="Conversion %",
)

expression instance-attribute

expression: str

Formula expression referencing events by letter.

label class-attribute instance-attribute

label: str | None = None

Optional display label for the formula result.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If expression is empty (FM1).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If expression is empty (FM1).
    """
    if not self.expression or not self.expression.strip():
        raise ValueError("Formula.expression must be a non-empty string")

mixpanel_data.Filter dataclass

Filter(
    _property: str | CustomPropertyRef | InlineCustomProperty,
    _operator: FilterOperator,
    _value: str
    | int
    | float
    | list[str]
    | list[int | float]
    | list[dict[str, Any]]
    | None,
    _property_type: FilterPropertyType = "string",
    _resource_type: Literal["events", "people"] = "events",
    _date_unit: FilterDateUnit | None = None,
    _list_item_filters: tuple[Filter, ...] | None = None,
    _list_item_quantifier: Literal["any", "all"] | None = None,
)

Represents a typed filter condition on a property.

Constructed exclusively via class methods — never instantiated directly. Each class method maps to specific filterType, filterOperator, and filterValue format in the bookmark JSON.

Example
from mixpanel_data import Filter

f1 = Filter.equals("country", "US")
f2 = Filter.greater_than("age", 18)
f3 = Filter.between("amount", 10, 100)
f4 = Filter.is_set("email")

__post_init__

__post_init__() -> None

Validate Filter mode invariants.

Only validates the list_contains mode today. Other operator modes rely on classmethod-only validation; expanding this coverage is a separate concern from this PR's list_contains feature.

RAISES DESCRIPTION
ValueError

If _operator == "list_contains" but _list_item_filters or _list_item_quantifier is None. List-contains filters must be constructed via Filter.list_contains(...).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate Filter mode invariants.

    Only validates the ``list_contains`` mode today. Other operator
    modes rely on classmethod-only validation; expanding this
    coverage is a separate concern from this PR's list_contains
    feature.

    Raises:
        ValueError: If ``_operator == "list_contains"`` but
            ``_list_item_filters`` or ``_list_item_quantifier`` is
            ``None``. List-contains filters must be constructed
            via ``Filter.list_contains(...)``.
    """
    if self._operator == "list_contains":
        if self._list_item_filters is None:
            raise ValueError(
                "list_contains Filter requires _list_item_filters; "
                "construct via Filter.list_contains(...)"
            )
        if self._list_item_quantifier is None:
            raise ValueError(
                "list_contains Filter requires _list_item_quantifier; "
                "construct via Filter.list_contains(...)"
            )

equals classmethod

equals(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str | list[str],
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create an equality filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Value or list of values.

TYPE: str | list[str]

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for string equality.

Source code in src/mixpanel_data/types.py
@classmethod
def equals(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str | list[str],
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create an equality filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Value or list of values.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for string equality.
    """
    val = [value] if isinstance(value, str) else value
    return cls(
        _property=property,
        _operator="equals",
        _value=val,
        _property_type="string",
        _resource_type=resource_type,
    )

not_equals classmethod

not_equals(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str | list[str],
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a not-equals filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Value or list of values.

TYPE: str | list[str]

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for string inequality.

Source code in src/mixpanel_data/types.py
@classmethod
def not_equals(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str | list[str],
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a not-equals filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Value or list of values.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for string inequality.
    """
    val = [value] if isinstance(value, str) else value
    return cls(
        _property=property,
        _operator="does not equal",
        _value=val,
        _property_type="string",
        _resource_type=resource_type,
    )

contains classmethod

contains(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a contains (substring) filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Substring to match.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for substring containment.

Source code in src/mixpanel_data/types.py
@classmethod
def contains(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a contains (substring) filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Substring to match.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for substring containment.
    """
    return cls(
        _property=property,
        _operator="contains",
        _value=value,
        _property_type="string",
        _resource_type=resource_type,
    )

not_contains classmethod

not_contains(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a not-contains filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Substring that must not match.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for substring non-containment.

Source code in src/mixpanel_data/types.py
@classmethod
def not_contains(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a not-contains filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Substring that must not match.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for substring non-containment.
    """
    return cls(
        _property=property,
        _operator="does not contain",
        _value=value,
        _property_type="string",
        _resource_type=resource_type,
    )

greater_than classmethod

greater_than(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a greater-than filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Numeric threshold.

TYPE: int | float

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for numeric greater-than.

Source code in src/mixpanel_data/types.py
@classmethod
def greater_than(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a greater-than filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Numeric threshold.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for numeric greater-than.
    """
    return cls(
        _property=property,
        _operator="is greater than",
        _value=value,
        _property_type="number",
        _resource_type=resource_type,
    )

less_than classmethod

less_than(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a less-than filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Numeric threshold.

TYPE: int | float

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for numeric less-than.

Source code in src/mixpanel_data/types.py
@classmethod
def less_than(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a less-than filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Numeric threshold.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for numeric less-than.
    """
    return cls(
        _property=property,
        _operator="is less than",
        _value=value,
        _property_type="number",
        _resource_type=resource_type,
    )

between classmethod

between(
    property: str | CustomPropertyRef | InlineCustomProperty,
    min_val: int | float,
    max_val: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a between (inclusive range) filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

min_val

Minimum value (inclusive).

TYPE: int | float

max_val

Maximum value (inclusive).

TYPE: int | float

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for numeric range.

Source code in src/mixpanel_data/types.py
@classmethod
def between(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    min_val: int | float,
    max_val: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a between (inclusive range) filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        min_val: Minimum value (inclusive).
        max_val: Maximum value (inclusive).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for numeric range.
    """
    return cls(
        _property=property,
        _operator="is between",
        _value=[min_val, max_val],
        _property_type="number",
        _resource_type=resource_type,
    )

not_between classmethod

not_between(
    property: str | CustomPropertyRef | InlineCustomProperty,
    min_val: int | float,
    max_val: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a not-between (exclusive range) filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

min_val

Minimum value (exclusive).

TYPE: int | float

max_val

Maximum value (exclusive).

TYPE: int | float

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for numeric values outside the range.

Example
f = Filter.not_between("age", 18, 65)
Source code in src/mixpanel_data/types.py
@classmethod
def not_between(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    min_val: int | float,
    max_val: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a not-between (exclusive range) filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        min_val: Minimum value (exclusive).
        max_val: Maximum value (exclusive).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for numeric values outside the range.

    Example:
        ```python
        f = Filter.not_between("age", 18, 65)
        ```
    """
    return cls(
        _property=property,
        _operator="not between",
        _value=[min_val, max_val],
        _property_type="number",
        _resource_type=resource_type,
    )

at_least classmethod

at_least(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a greater-than-or-equal filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Numeric threshold (inclusive).

TYPE: int | float

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for numeric greater-than-or-equal.

Example
f = Filter.at_least("score", 80)
Source code in src/mixpanel_data/types.py
@classmethod
def at_least(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a greater-than-or-equal filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Numeric threshold (inclusive).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for numeric greater-than-or-equal.

    Example:
        ```python
        f = Filter.at_least("score", 80)
        ```
    """
    return cls(
        _property=property,
        _operator="is at least",
        _value=value,
        _property_type="number",
        _resource_type=resource_type,
    )

at_most classmethod

at_most(
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a less-than-or-equal filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

value

Numeric threshold (inclusive).

TYPE: int | float

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for numeric less-than-or-equal.

Example
f = Filter.at_most("errors", 5)
Source code in src/mixpanel_data/types.py
@classmethod
def at_most(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    value: int | float,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a less-than-or-equal filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        value: Numeric threshold (inclusive).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for numeric less-than-or-equal.

    Example:
        ```python
        f = Filter.at_most("errors", 5)
        ```
    """
    return cls(
        _property=property,
        _operator="is at most",
        _value=value,
        _property_type="number",
        _resource_type=resource_type,
    )

is_set classmethod

is_set(
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a property-existence filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for property existence.

Source code in src/mixpanel_data/types.py
@classmethod
def is_set(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a property-existence filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for property existence.
    """
    return cls(
        _property=property,
        _operator="is set",
        _value=None,
        _property_type="string",
        _resource_type=resource_type,
    )

is_not_set classmethod

is_not_set(
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a property-nonexistence filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for property non-existence.

Source code in src/mixpanel_data/types.py
@classmethod
def is_not_set(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a property-nonexistence filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for property non-existence.
    """
    return cls(
        _property=property,
        _operator="is not set",
        _value=None,
        _property_type="string",
        _resource_type=resource_type,
    )

starts_with classmethod

starts_with(
    property: str | CustomPropertyRef | InlineCustomProperty,
    prefix: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a starts-with (prefix match) filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

prefix

String prefix to match.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for string prefix matching.

Example
f = Filter.starts_with("url", "https://")
Source code in src/mixpanel_data/types.py
@classmethod
def starts_with(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    prefix: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a starts-with (prefix match) filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        prefix: String prefix to match.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for string prefix matching.

    Example:
        ```python
        f = Filter.starts_with("url", "https://")
        ```
    """
    return cls(
        _property=property,
        _operator="starts with",
        _value=prefix,
        _property_type="string",
        _resource_type=resource_type,
    )

ends_with classmethod

ends_with(
    property: str | CustomPropertyRef | InlineCustomProperty,
    suffix: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create an ends-with (suffix match) filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

suffix

String suffix to match.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for string suffix matching.

Example
f = Filter.ends_with("email", "@example.com")
Source code in src/mixpanel_data/types.py
@classmethod
def ends_with(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    suffix: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create an ends-with (suffix match) filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        suffix: String suffix to match.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for string suffix matching.

    Example:
        ```python
        f = Filter.ends_with("email", "@example.com")
        ```
    """
    return cls(
        _property=property,
        _operator="ends with",
        _value=suffix,
        _property_type="string",
        _resource_type=resource_type,
    )

is_true classmethod

is_true(
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a boolean true filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for boolean true.

Source code in src/mixpanel_data/types.py
@classmethod
def is_true(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a boolean true filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for boolean true.
    """
    return cls(
        _property=property,
        _operator="true",
        _value=None,
        _property_type="boolean",
        _resource_type=resource_type,
    )

is_false classmethod

is_false(
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a boolean false filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for boolean false.

Source code in src/mixpanel_data/types.py
@classmethod
def is_false(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a boolean false filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for boolean false.
    """
    return cls(
        _property=property,
        _operator="false",
        _value=None,
        _property_type="boolean",
        _resource_type=resource_type,
    )

in_cohort classmethod

in_cohort(cohort: int | CohortDefinition, name: str | None = None) -> Filter

Create a filter restricting to users in a cohort.

Accepts either a saved cohort ID (int) or an inline CohortDefinition. The filter can be passed to where= on any query method (query, query_funnel, query_retention, query_flow).

PARAMETER DESCRIPTION
cohort

Saved cohort ID (positive integer) or inline CohortDefinition.

TYPE: int | CohortDefinition

name

Display name for the cohort. Optional for saved cohorts; recommended for inline definitions.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
Filter

Filter for cohort membership (contains).

RAISES DESCRIPTION
ValueError

If cohort ID is not positive (CF1) or name is empty when provided (CF2).

Example
from mixpanel_data import Filter

# Saved cohort
f = Filter.in_cohort(123, "Power Users")

# Inline cohort
f = Filter.in_cohort(cohort_def, name="Frequent Buyers")
Source code in src/mixpanel_data/types.py
@classmethod
def in_cohort(
    cls,
    cohort: int | CohortDefinition,
    name: str | None = None,
) -> Filter:
    """Create a filter restricting to users in a cohort.

    Accepts either a saved cohort ID (``int``) or an inline
    ``CohortDefinition``. The filter can be passed to ``where=``
    on any query method (``query``, ``query_funnel``,
    ``query_retention``, ``query_flow``).

    Args:
        cohort: Saved cohort ID (positive integer) or inline
            ``CohortDefinition``.
        name: Display name for the cohort. Optional for saved
            cohorts; recommended for inline definitions.

    Returns:
        Filter for cohort membership (contains).

    Raises:
        ValueError: If cohort ID is not positive (CF1) or name
            is empty when provided (CF2).

    Example:
        ```python
        from mixpanel_data import Filter

        # Saved cohort
        f = Filter.in_cohort(123, "Power Users")

        # Inline cohort
        f = Filter.in_cohort(cohort_def, name="Frequent Buyers")
        ```
    """
    return cls._build_cohort_filter(cohort, name, negated=False)

not_in_cohort classmethod

not_in_cohort(
    cohort: int | CohortDefinition, name: str | None = None
) -> Filter

Create a filter excluding users in a cohort.

Accepts either a saved cohort ID (int) or an inline CohortDefinition. The filter can be passed to where= on any query method.

PARAMETER DESCRIPTION
cohort

Saved cohort ID (positive integer) or inline CohortDefinition.

TYPE: int | CohortDefinition

name

Display name for the cohort. Optional for saved cohorts; recommended for inline definitions.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
Filter

Filter for cohort exclusion (does not contain).

RAISES DESCRIPTION
ValueError

If cohort ID is not positive (CF1) or name is empty when provided (CF2).

Example
from mixpanel_data import Filter

f = Filter.not_in_cohort(789, "Bots")
Source code in src/mixpanel_data/types.py
@classmethod
def not_in_cohort(
    cls,
    cohort: int | CohortDefinition,
    name: str | None = None,
) -> Filter:
    """Create a filter excluding users in a cohort.

    Accepts either a saved cohort ID (``int``) or an inline
    ``CohortDefinition``. The filter can be passed to ``where=``
    on any query method.

    Args:
        cohort: Saved cohort ID (positive integer) or inline
            ``CohortDefinition``.
        name: Display name for the cohort. Optional for saved
            cohorts; recommended for inline definitions.

    Returns:
        Filter for cohort exclusion (does not contain).

    Raises:
        ValueError: If cohort ID is not positive (CF1) or name
            is empty when provided (CF2).

    Example:
        ```python
        from mixpanel_data import Filter

        f = Filter.not_in_cohort(789, "Bots")
        ```
    """
    return cls._build_cohort_filter(cohort, name, negated=True)

on classmethod

on(
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a date equality filter (exact date match).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty (e.g. "$time", "created").

TYPE: str | CustomPropertyRef | InlineCustomProperty

date

Date in YYYY-MM-DD format.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for exact date match.

RAISES DESCRIPTION
ValueError

If date is not valid YYYY-MM-DD.

Source code in src/mixpanel_data/types.py
@classmethod
def on(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a date equality filter (exact date match).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty (e.g. ``"$time"``, ``"created"``).
        date: Date in YYYY-MM-DD format.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for exact date match.

    Raises:
        ValueError: If date is not valid YYYY-MM-DD.
    """
    cls._validate_date(date)
    return cls(
        _property=property,
        _operator="was on",
        _value=date,
        _property_type="datetime",
        _resource_type=resource_type,
    )

not_on classmethod

not_on(
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a date inequality filter (not on date).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

date

Date in YYYY-MM-DD format.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for date inequality.

RAISES DESCRIPTION
ValueError

If date is not valid YYYY-MM-DD.

Source code in src/mixpanel_data/types.py
@classmethod
def not_on(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a date inequality filter (not on date).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        date: Date in YYYY-MM-DD format.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for date inequality.

    Raises:
        ValueError: If date is not valid YYYY-MM-DD.
    """
    cls._validate_date(date)
    return cls(
        _property=property,
        _operator="was not on",
        _value=date,
        _property_type="datetime",
        _resource_type=resource_type,
    )

before classmethod

before(
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a date before filter.

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

date

Date in YYYY-MM-DD format.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for dates before the specified date.

RAISES DESCRIPTION
ValueError

If date is not valid YYYY-MM-DD.

Source code in src/mixpanel_data/types.py
@classmethod
def before(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a date before filter.

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        date: Date in YYYY-MM-DD format.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for dates before the specified date.

    Raises:
        ValueError: If date is not valid YYYY-MM-DD.
    """
    cls._validate_date(date)
    return cls(
        _property=property,
        _operator="was before",
        _value=date,
        _property_type="datetime",
        _resource_type=resource_type,
    )

since classmethod

since(
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a date since filter (from date onward).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

date

Date in YYYY-MM-DD format.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for dates on or after the specified date.

RAISES DESCRIPTION
ValueError

If date is not valid YYYY-MM-DD.

Source code in src/mixpanel_data/types.py
@classmethod
def since(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a date since filter (from date onward).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        date: Date in YYYY-MM-DD format.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for dates on or after the specified date.

    Raises:
        ValueError: If date is not valid YYYY-MM-DD.
    """
    cls._validate_date(date)
    return cls(
        _property=property,
        _operator="was since",
        _value=date,
        _property_type="datetime",
        _resource_type=resource_type,
    )

in_the_last classmethod

in_the_last(
    property: str | CustomPropertyRef | InlineCustomProperty,
    quantity: int,
    date_unit: FilterDateUnit,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a relative date filter (in the last N units).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

quantity

Number of time units (must be positive).

TYPE: int

date_unit

Time unit ("hour", "day", "week", "month").

TYPE: FilterDateUnit

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for events within the last N units.

RAISES DESCRIPTION
ValueError

If quantity is not positive.

Source code in src/mixpanel_data/types.py
@classmethod
def in_the_last(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    quantity: int,
    date_unit: FilterDateUnit,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a relative date filter (in the last N units).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        quantity: Number of time units (must be positive).
        date_unit: Time unit (``"hour"``, ``"day"``, ``"week"``,
            ``"month"``).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for events within the last N units.

    Raises:
        ValueError: If quantity is not positive.
    """
    if quantity <= 0:
        raise ValueError(f"quantity must be a positive integer (got {quantity})")
    return cls(
        _property=property,
        _operator="was in the",
        _value=quantity,
        _property_type="datetime",
        _resource_type=resource_type,
        _date_unit=date_unit,
    )

not_in_the_last classmethod

not_in_the_last(
    property: str | CustomPropertyRef | InlineCustomProperty,
    quantity: int,
    date_unit: FilterDateUnit,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a relative date exclusion filter (not in the last N units).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

quantity

Number of time units (must be positive).

TYPE: int

date_unit

Time unit ("hour", "day", "week", "month").

TYPE: FilterDateUnit

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for events NOT within the last N units.

RAISES DESCRIPTION
ValueError

If quantity is not positive.

Source code in src/mixpanel_data/types.py
@classmethod
def not_in_the_last(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    quantity: int,
    date_unit: FilterDateUnit,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a relative date exclusion filter (not in the last N units).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        quantity: Number of time units (must be positive).
        date_unit: Time unit (``"hour"``, ``"day"``, ``"week"``,
            ``"month"``).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for events NOT within the last N units.

    Raises:
        ValueError: If quantity is not positive.
    """
    if quantity <= 0:
        raise ValueError(f"quantity must be a positive integer (got {quantity})")
    return cls(
        _property=property,
        _operator="was not in the",
        _value=quantity,
        _property_type="datetime",
        _resource_type=resource_type,
        _date_unit=date_unit,
    )

date_between classmethod

date_between(
    property: str | CustomPropertyRef | InlineCustomProperty,
    from_date: str,
    to_date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a date range filter (between two dates, inclusive).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

from_date

Start date in YYYY-MM-DD format.

TYPE: str

to_date

End date in YYYY-MM-DD format.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for dates within the range.

RAISES DESCRIPTION
ValueError

If dates are not valid YYYY-MM-DD or from_date is after to_date.

Source code in src/mixpanel_data/types.py
@classmethod
def date_between(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    from_date: str,
    to_date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a date range filter (between two dates, inclusive).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        from_date: Start date in YYYY-MM-DD format.
        to_date: End date in YYYY-MM-DD format.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for dates within the range.

    Raises:
        ValueError: If dates are not valid YYYY-MM-DD or
            from_date is after to_date.
    """
    from_parsed = cls._validate_date(from_date)
    to_parsed = cls._validate_date(to_date)
    if from_parsed > to_parsed:
        raise ValueError(
            f"from_date must be before to_date (got '{from_date}' > '{to_date}')"
        )
    return cls(
        _property=property,
        _operator="was between",
        _value=[from_date, to_date],
        _property_type="datetime",
        _resource_type=resource_type,
    )

date_not_between classmethod

date_not_between(
    property: str | CustomPropertyRef | InlineCustomProperty,
    from_date: str,
    to_date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a date exclusion range filter (not between two dates).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

from_date

Start date in YYYY-MM-DD format.

TYPE: str

to_date

End date in YYYY-MM-DD format.

TYPE: str

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for dates outside the range.

RAISES DESCRIPTION
ValueError

If dates are not valid YYYY-MM-DD or from_date is after to_date.

Example
f = Filter.date_not_between("created", "2024-01-01", "2024-06-30")
Source code in src/mixpanel_data/types.py
@classmethod
def date_not_between(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    from_date: str,
    to_date: str,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a date exclusion range filter (not between two dates).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        from_date: Start date in YYYY-MM-DD format.
        to_date: End date in YYYY-MM-DD format.
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for dates outside the range.

    Raises:
        ValueError: If dates are not valid YYYY-MM-DD or
            from_date is after to_date.

    Example:
        ```python
        f = Filter.date_not_between("created", "2024-01-01", "2024-06-30")
        ```
    """
    from_parsed = cls._validate_date(from_date)
    to_parsed = cls._validate_date(to_date)
    if from_parsed > to_parsed:
        raise ValueError(
            f"from_date must be before to_date (got '{from_date}' > '{to_date}')"
        )
    return cls(
        _property=property,
        _operator="was not between",
        _value=[from_date, to_date],
        _property_type="datetime",
        _resource_type=resource_type,
    )

in_the_next classmethod

in_the_next(
    property: str | CustomPropertyRef | InlineCustomProperty,
    quantity: int,
    date_unit: FilterDateUnit,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter

Create a relative date filter (in the next N units).

PARAMETER DESCRIPTION
property

Property name, CustomPropertyRef, or InlineCustomProperty.

TYPE: str | CustomPropertyRef | InlineCustomProperty

quantity

Number of time units (must be positive).

TYPE: int

date_unit

Time unit ("hour", "day", "week", "month").

TYPE: FilterDateUnit

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

RETURNS DESCRIPTION
Filter

Filter for events within the next N units.

RAISES DESCRIPTION
ValueError

If quantity is not positive.

Example
f = Filter.in_the_next("expires", 7, "day")
Source code in src/mixpanel_data/types.py
@classmethod
def in_the_next(
    cls,
    property: str | CustomPropertyRef | InlineCustomProperty,
    quantity: int,
    date_unit: FilterDateUnit,
    *,
    resource_type: Literal["events", "people"] = "events",
) -> Filter:
    """Create a relative date filter (in the next N units).

    Args:
        property: Property name, CustomPropertyRef, or InlineCustomProperty.
        quantity: Number of time units (must be positive).
        date_unit: Time unit (``"hour"``, ``"day"``, ``"week"``,
            ``"month"``).
        resource_type: Resource type. Default: ``"events"``.

    Returns:
        Filter for events within the next N units.

    Raises:
        ValueError: If quantity is not positive.

    Example:
        ```python
        f = Filter.in_the_next("expires", 7, "day")
        ```
    """
    if quantity <= 0:
        raise ValueError(f"quantity must be a positive integer (got {quantity})")
    return cls(
        _property=property,
        _operator="was in the next",
        _value=quantity,
        _property_type="datetime",
        _resource_type=resource_type,
        _date_unit=date_unit,
    )

list_contains classmethod

list_contains(
    property: str,
    *item_filters: Filter,
    quantifier: Literal["any", "all"] = "any",
    resource_type: Literal["events", "people"] = "events",
    **equals: str | list[str],
) -> Filter

Match events whose list-of-object property contains items satisfying inner conditions.

Used to filter on subproperties of objects nested inside a list property (e.g. cart is a list of {"Brand": str, "Category": str, "Price": int}). Each inner condition is evaluated per-item; the quantifier controls whether at least one item ("any", the default) or every item ("all") must satisfy all inner conditions.

Two ways to specify inner conditions:

  • Keyword shorthand for the common equality case: Filter.list_contains("cart", Brand="nike", Category="hats"). Inner equality filters inherit the outer resource_type.
  • Explicit Filter instances for any wire-format operator: Filter.list_contains("cart", Filter.equals("Brand", "nike"), Filter.greater_than("Price", 50)). Each inner Filter carries its own resource_type from its own factory call — pass resource_type= explicitly on each inner factory if you want them to match the outer.

Mixing the two shapes in one call raises ValueError.

PARAMETER DESCRIPTION
property

Name of the list-of-object property to filter on.

TYPE: str

*item_filters

Inner Filter instances applied per list item. Mutually exclusive with **equals.

TYPE: Filter DEFAULT: ()

quantifier

"any" (≥1 item must match all inner conditions) or "all" (every item must). Default: "any".

TYPE: Literal['any', 'all'] DEFAULT: 'any'

resource_type

Resource type. Default: "events".

TYPE: Literal['events', 'people'] DEFAULT: 'events'

**equals

Keyword shorthand — each key=value becomes Filter.equals(key, value, resource_type=resource_type). Mutually exclusive with *item_filters. Values must be str or list[str]; keys must be non-empty.

TYPE: str | list[str] DEFAULT: {}

RETURNS DESCRIPTION
Filter

Filter that emits the listItemFilters bookmark structure

Filter

on serialization.

RAISES DESCRIPTION
ValueError

If both *item_filters and **equals are provided, if quantifier is not "any" or "all", if a kwarg key is empty, if no inner conditions are given, or if any inner filter is itself a list_contains (nesting is not supported).

TypeError

If a **equals value is not str or list[str] (the wire format only supports string equality; numeric/boolean comparisons require explicit Filter.equals(...) / Filter.greater_than(...) positional inner filters).

Example
from mixpanel_data import Filter

# Cart contains a nike-branded hat
f1 = Filter.list_contains("cart", Brand="nike", Category="hats")

# Every cart item costs more than $50
f2 = Filter.list_contains(
    "cart",
    Filter.greater_than("Price", 50),
    quantifier="all",
)
Source code in src/mixpanel_data/types.py
@classmethod
def list_contains(
    cls,
    property: str,
    *item_filters: Filter,
    quantifier: Literal["any", "all"] = "any",
    resource_type: Literal["events", "people"] = "events",
    **equals: str | list[str],
) -> Filter:
    """Match events whose list-of-object property contains items satisfying inner conditions.

    Used to filter on subproperties of objects nested inside a list
    property (e.g. ``cart`` is a list of ``{"Brand": str, "Category":
    str, "Price": int}``). Each inner condition is evaluated
    per-item; the ``quantifier`` controls whether at least one item
    (``"any"``, the default) or every item (``"all"``) must satisfy
    all inner conditions.

    Two ways to specify inner conditions:

    - **Keyword shorthand** for the common equality case:
      ``Filter.list_contains("cart", Brand="nike", Category="hats")``.
      Inner equality filters inherit the outer ``resource_type``.
    - **Explicit Filter instances** for any wire-format operator:
      ``Filter.list_contains("cart", Filter.equals("Brand", "nike"),
      Filter.greater_than("Price", 50))``. Each inner Filter carries
      its own ``resource_type`` from its own factory call — pass
      ``resource_type=`` explicitly on each inner factory if you
      want them to match the outer.

    Mixing the two shapes in one call raises ``ValueError``.

    Args:
        property: Name of the list-of-object property to filter on.
        *item_filters: Inner ``Filter`` instances applied per list
            item. Mutually exclusive with ``**equals``.
        quantifier: ``"any"`` (≥1 item must match all inner
            conditions) or ``"all"`` (every item must). Default:
            ``"any"``.
        resource_type: Resource type. Default: ``"events"``.
        **equals: Keyword shorthand — each ``key=value`` becomes
            ``Filter.equals(key, value, resource_type=resource_type)``.
            Mutually exclusive with ``*item_filters``. Values must
            be ``str`` or ``list[str]``; keys must be non-empty.

    Returns:
        Filter that emits the ``listItemFilters`` bookmark structure
        on serialization.

    Raises:
        ValueError: If both ``*item_filters`` and ``**equals`` are
            provided, if ``quantifier`` is not ``"any"`` or
            ``"all"``, if a kwarg key is empty, if no inner
            conditions are given, or if any inner filter is itself
            a ``list_contains`` (nesting is not supported).
        TypeError: If a ``**equals`` value is not ``str`` or
            ``list[str]`` (the wire format only supports string
            equality; numeric/boolean comparisons require explicit
            ``Filter.equals(...)`` / ``Filter.greater_than(...)``
            positional inner filters).

    Example:
        ```python
        from mixpanel_data import Filter

        # Cart contains a nike-branded hat
        f1 = Filter.list_contains("cart", Brand="nike", Category="hats")

        # Every cart item costs more than $50
        f2 = Filter.list_contains(
            "cart",
            Filter.greater_than("Price", 50),
            quantifier="all",
        )
        ```
    """
    if item_filters and equals:
        raise ValueError(
            "Filter.list_contains: pass either positional Filter instances "
            "OR keyword equals shorthand, not both"
        )
    if quantifier not in ("any", "all"):
        raise ValueError(
            f"Filter.list_contains quantifier must be 'any' or 'all', "
            f"got {quantifier!r}"
        )
    for k, v in equals.items():
        if not k.strip():
            raise ValueError(
                "Filter.list_contains: kwarg keys must be non-empty strings"
            )
        if not isinstance(v, (str, list)):
            raise TypeError(
                f"Filter.list_contains kwarg {k!r}: value must be str or "
                f"list[str], got {type(v).__name__}"
            )
    sub_filters: tuple[Filter, ...] = (
        tuple(item_filters)
        if item_filters
        else tuple(
            cls.equals(k, v, resource_type=resource_type) for k, v in equals.items()
        )
    )
    if not sub_filters:
        raise ValueError(
            "Filter.list_contains requires at least one inner condition"
        )
    for sub in sub_filters:
        if sub._operator == "list_contains":
            raise ValueError(
                "Filter.list_contains does not support nested list_contains filters"
            )
    return cls(
        _property=property,
        _operator="list_contains",
        _value=None,
        _property_type="object",
        _resource_type=resource_type,
        _list_item_filters=sub_filters,
        _list_item_quantifier=quantifier,
    )

mixpanel_data.GroupBy dataclass

GroupBy(
    property: str | CustomPropertyRef | InlineCustomProperty,
    property_type: CustomPropertyType = "string",
    bucket_size: int | float | None = None,
    bucket_min: int | float | None = None,
    bucket_max: int | float | None = None,
    _list_item_mode: ListItemGroupMode | None = None,
)

Specifies a property breakdown with optional numeric bucketing.

Used with Workspace.query() to break down results by property values. String properties are broken down by distinct values; numeric properties can be bucketed into ranges.

ATTRIBUTE DESCRIPTION
property

Property to break down by (name, ref, or inline).

TYPE: str | CustomPropertyRef | InlineCustomProperty

property_type

Data type of the property. Default: "string".

TYPE: CustomPropertyType

bucket_size

Bucket width for numeric properties.

TYPE: int | float | None

bucket_min

Minimum value for numeric buckets.

TYPE: int | float | None

bucket_max

Maximum value for numeric buckets.

TYPE: int | float | None

Example
from mixpanel_data import GroupBy

# String breakdown
g1 = GroupBy("country")

# Numeric bucketed breakdown
g2 = GroupBy(
    "revenue",
    property_type="number",
    bucket_size=50,
    bucket_min=0,
    bucket_max=500,
)

property instance-attribute

property: str | CustomPropertyRef | InlineCustomProperty

Property to break down by (name, ref, or inline).

property_type class-attribute instance-attribute

property_type: CustomPropertyType = 'string'

Data type of the property. One of the four scalar types.

Note: list-item breakdowns set _list_item_mode instead — the wire builder hardcodes propertyType: "object" for that branch independently of this field.

bucket_size class-attribute instance-attribute

bucket_size: int | float | None = None

Bucket width for numeric properties.

bucket_min class-attribute instance-attribute

bucket_min: int | float | None = None

Minimum value for numeric buckets.

bucket_max class-attribute instance-attribute

bucket_max: int | float | None = None

Maximum value for numeric buckets.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If property is an empty string (GB1), bucket_size is not positive (GB2), bucket_min >= bucket_max (GB3), _list_item_mode is combined with bucketing (GB4), or _list_item_mode is set but property is not a plain str (GB5).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If property is an empty string (GB1),
            bucket_size is not positive (GB2),
            bucket_min >= bucket_max (GB3),
            ``_list_item_mode`` is combined with bucketing (GB4),
            or ``_list_item_mode`` is set but ``property`` is not a
            plain ``str`` (GB5).
    """
    if isinstance(self.property, str) and not self.property.strip():
        raise ValueError("GroupBy.property must be a non-empty string")
    if self.bucket_size is not None and self.bucket_size <= 0:
        raise ValueError(
            f"GroupBy.bucket_size must be positive, got {self.bucket_size}"
        )
    if (
        self.bucket_min is not None
        and self.bucket_max is not None
        and self.bucket_min >= self.bucket_max
    ):
        raise ValueError(
            f"GroupBy.bucket_min ({self.bucket_min}) must be less than "
            f"bucket_max ({self.bucket_max})"
        )
    if self._list_item_mode is not None:
        if any(
            b is not None
            for b in (self.bucket_size, self.bucket_min, self.bucket_max)
        ):
            raise ValueError("GroupBy.list_item is incompatible with bucketing")
        if not isinstance(self.property, str):
            raise ValueError(
                "GroupBy.list_item requires property to be a plain str, "
                f"got {type(self.property).__name__}"
            )

list_item classmethod

list_item(
    property: str, sub: str, *, sub_type: CustomPropertyType = "string"
) -> GroupBy

Break down by a subproperty of objects inside a list property.

Mirrors the Mixpanel UI's cart.Brand / cart.Category breakdown for list-of-object properties (e.g. cart is a list of {"Brand": str, "Category": str, "Price": int} items). Each list item contributes one count per distinct subproperty value it carries.

PARAMETER DESCRIPTION
property

Name of the list-of-object property.

TYPE: str

sub

Subproperty name to break down by.

TYPE: str

sub_type

Data type of the subproperty. Default: "string".

TYPE: CustomPropertyType DEFAULT: 'string'

RETURNS DESCRIPTION
GroupBy

GroupBy whose serialization emits a listItemGroup

GroupBy

structure in the bookmark JSON.

RAISES DESCRIPTION
ValueError

If sub is empty after stripping (via ListItemGroupMode.__post_init__), if sub_type is not one of the four CustomPropertyType values, or if any GroupBy.__post_init__ invariant fails (see :meth:__post_init__ Raises section).

Example
from mixpanel_data import GroupBy

# Break down Cart Viewed events by cart.Brand
g1 = GroupBy.list_item("cart", "Brand")

# Break down by a numeric subproperty
g2 = GroupBy.list_item("cart", "Price", sub_type="number")
Source code in src/mixpanel_data/types.py
@classmethod
def list_item(
    cls,
    property: str,
    sub: str,
    *,
    sub_type: CustomPropertyType = "string",
) -> GroupBy:
    """Break down by a subproperty of objects inside a list property.

    Mirrors the Mixpanel UI's ``cart.Brand`` / ``cart.Category``
    breakdown for list-of-object properties (e.g. ``cart`` is a
    list of ``{"Brand": str, "Category": str, "Price": int}``
    items). Each list item contributes one count per distinct
    subproperty value it carries.

    Args:
        property: Name of the list-of-object property.
        sub: Subproperty name to break down by.
        sub_type: Data type of the subproperty. Default:
            ``"string"``.

    Returns:
        ``GroupBy`` whose serialization emits a ``listItemGroup``
        structure in the bookmark JSON.

    Raises:
        ValueError: If ``sub`` is empty after stripping (via
            ``ListItemGroupMode.__post_init__``), if ``sub_type``
            is not one of the four ``CustomPropertyType`` values,
            or if any ``GroupBy.__post_init__`` invariant fails
            (see :meth:`__post_init__` Raises section).

    Example:
        ```python
        from mixpanel_data import GroupBy

        # Break down Cart Viewed events by cart.Brand
        g1 = GroupBy.list_item("cart", "Brand")

        # Break down by a numeric subproperty
        g2 = GroupBy.list_item("cart", "Price", sub_type="number")
        ```
    """
    return cls(
        property=property,
        _list_item_mode=ListItemGroupMode(sub=sub, sub_type=sub_type),
    )

mixpanel_data.ListItemGroupMode dataclass

ListItemGroupMode(sub: str, sub_type: CustomPropertyType)

Discriminator for GroupBy.list_item — sub-property name + scalar type.

Pairs the subproperty name with its inferred scalar type so they cannot be set independently. Used as the optional _list_item_mode field on GroupBy; presence of this field marks a GroupBy as a list-item breakdown.

ATTRIBUTE DESCRIPTION
sub

Subproperty name (must be non-empty after stripping).

TYPE: str

sub_type

Subproperty data type. One of the four CustomPropertyType values.

TYPE: CustomPropertyType

Example
from mixpanel_data import GroupBy, ListItemGroupMode

# Constructed indirectly via the classmethod (preferred)
g = GroupBy.list_item("cart", "Brand")
assert g._list_item_mode == ListItemGroupMode(sub="Brand", sub_type="string")

sub instance-attribute

sub: str

Subproperty name as it appears inside each object.

sub_type instance-attribute

sub_type: CustomPropertyType

Subproperty data type, matching :data:CustomPropertyType.

__post_init__

__post_init__() -> None

Validate sub is non-empty and sub_type is a known scalar type.

RAISES DESCRIPTION
ValueError

If sub is empty after stripping or sub_type is not one of the four CustomPropertyType values.

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate sub is non-empty and sub_type is a known scalar type.

    Raises:
        ValueError: If ``sub`` is empty after stripping or
            ``sub_type`` is not one of the four
            ``CustomPropertyType`` values.
    """
    if not self.sub.strip():
        raise ValueError("ListItemGroupMode.sub must be a non-empty string")
    if self.sub_type not in ("string", "number", "boolean", "datetime"):
        raise ValueError(
            "ListItemGroupMode.sub_type must be one of "
            "'string'/'number'/'boolean'/'datetime', "
            f"got {self.sub_type!r}"
        )

mixpanel_data.QueryResult dataclass

QueryResult(
    computed_at: str,
    from_date: str,
    to_date: str,
    headers: list[str] = list(),
    series: dict[str, Any] = dict(),
    params: dict[str, Any] = dict(),
    meta: dict[str, Any] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Structured output from a Workspace.query() execution.

Contains the query response data with lazy DataFrame conversion. The series structure varies by query mode:

  • Timeseries: {metric_name: {date_string: value}}
  • Total: {metric_name: {"all": value}}
ATTRIBUTE DESCRIPTION
computed_at

When the query was computed (ISO format).

TYPE: str

from_date

Effective start date from response.

TYPE: str

to_date

Effective end date from response.

TYPE: str

headers

Column headers from the insights response.

TYPE: list[str]

series

Query result data (structure varies by mode).

TYPE: dict[str, Any]

params

Generated bookmark params sent to API (for debugging/persistence).

TYPE: dict[str, Any]

meta

Response metadata (sampling factor, limits hit).

TYPE: dict[str, Any]

Example
result = ws.query("Login", math="unique", last=7)

# DataFrame access
print(result.df.head())

# Inspect generated params
print(result.params)

# Save as a report
ws.create_bookmark(CreateBookmarkParams(
    name="Login Uniques (7d)",
    bookmark_type="insights",
    params=result.params,
))

computed_at instance-attribute

computed_at: str

When the query was computed (ISO format).

from_date instance-attribute

from_date: str

Effective start date from response.

to_date instance-attribute

to_date: str

Effective end date from response.

headers class-attribute instance-attribute

headers: list[str] = field(default_factory=list)

Column headers from the insights response.

series class-attribute instance-attribute

series: dict[str, Any] = field(default_factory=dict)

Query result data.

For timeseries: {metric_name: {date_string: value}} For total: {metric_name: {"all": value}}

params class-attribute instance-attribute

params: dict[str, Any] = field(default_factory=dict)

Generated bookmark params sent to API (for debugging/persistence).

meta class-attribute instance-attribute

meta: dict[str, Any] = field(default_factory=dict)

Response metadata. Conforms to :class:QueryMeta (sampling_factor, is_cached, computation_time, query_id).

df property

df: DataFrame

Convert to DataFrame.

For timeseries mode: columns are date, event, count. For total mode: columns are event, count. For segmented timeseries (with group_by): columns are date, event, segment, count. For segmented total (with group_by): columns are event, segment, count.

RETURNS DESCRIPTION
DataFrame

Normalized DataFrame with one row per (date, metric, segment)

DataFrame

combination. Segmented responses are detected automatically

DataFrame

by checking whether inner values are dicts (segment nesting)

DataFrame

or scalars (flat response).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all QueryResult fields.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all QueryResult fields.
    """
    return {
        "computed_at": self.computed_at,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "headers": self.headers,
        "series": self.series,
        "params": self.params,
        "meta": self.meta,
    }

Cohort Query Types

Types for cohort-scoped queries — filter by cohort, break down by cohort membership, or track cohort size as a metric across all query engines.

mixpanel_data.CohortBreakdown dataclass

CohortBreakdown(
    cohort: int | CohortDefinition,
    name: str | None = None,
    include_negated: bool = True,
)

Break down query results by cohort membership.

Represents a cohort-based breakdown dimension for use in the group_by= parameter of query(), query_funnel(), and query_retention().

Accepts either a saved cohort ID (int) or an inline CohortDefinition. When include_negated=True (default), both "In Cohort" and "Not In Cohort" segments are shown.

ATTRIBUTE DESCRIPTION
cohort

Saved cohort ID (positive integer) or inline CohortDefinition.

TYPE: int | CohortDefinition

name

Display name. Optional for saved cohorts; recommended for inline definitions.

TYPE: str | None

include_negated

Whether to include a "Not In" segment. Default: True.

TYPE: bool

Example
from mixpanel_data import CohortBreakdown

# Segment by saved cohort
result = ws.query("Purchase", group_by=CohortBreakdown(123, "Power Users"))

# Without "Not In" segment
result = ws.query(
    "Purchase",
    group_by=CohortBreakdown(123, "Power Users", include_negated=False),
)

cohort instance-attribute

cohort: int | CohortDefinition

Saved cohort ID or inline definition.

name class-attribute instance-attribute

name: str | None = None

Display name for the cohort.

include_negated class-attribute instance-attribute

include_negated: bool = True

Whether to include a 'Not In' segment.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If cohort ID is not positive (CB1) or name is empty when provided (CB2).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If cohort ID is not positive (CB1) or name
            is empty when provided (CB2).
    """
    _validate_cohort_args(self.cohort, self.name)

mixpanel_data.CohortMetric dataclass

CohortMetric(cohort: int | CohortDefinition, name: str | None = None)

Track cohort size over time as an event metric.

Represents a cohort size metric for use in the events= parameter of query() (insights only). Produces a show clause with behavior.type: "cohort" in the bookmark JSON.

Cannot be used with query_funnel(), query_retention(), or query_flow() (CM4 — insights only).

Inline CohortDefinition is not supported (CM5 — server returns 500). Use a saved cohort ID instead. This is enforced at construction.

ATTRIBUTE DESCRIPTION
cohort

Saved cohort ID (positive integer) or inline CohortDefinition.

TYPE: int | CohortDefinition

name

Display name / series label. Optional for saved cohorts; recommended for inline definitions.

TYPE: str | None

Example
from mixpanel_data import CohortMetric, Metric, Formula

# Track cohort growth
result = ws.query(CohortMetric(123, "Power Users"), last=90, unit="week")

# Mix with event metrics and formulas
result = ws.query(
    [Metric("Login", math="unique"), CohortMetric(123, "Power Users")],
    formula="(B / A) * 100",
    formula_label="Power User %",
)

cohort instance-attribute

cohort: int | CohortDefinition

Saved cohort ID or inline definition.

name class-attribute instance-attribute

name: str | None = None

Display name / series label.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If cohort ID is not positive (CM1), name is empty when provided (CM2), or cohort is an inline CohortDefinition (CM5 — server returns 500).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If cohort ID is not positive (CM1), name
            is empty when provided (CM2), or cohort is an inline
            ``CohortDefinition`` (CM5 — server returns 500).
    """
    _validate_cohort_args(self.cohort, self.name)
    # CM5: Inline CohortDefinition causes server-side 500.
    if isinstance(self.cohort, CohortDefinition):
        raise ValueError(
            "CohortMetric does not support inline CohortDefinition "
            "(server returns 500). Use a saved cohort ID instead."
        )

Custom Property Query Types

Types for using saved or inline custom properties as property references in query breakdowns, filters, and metric measurement. See Custom Properties in Queries for usage guide.

mixpanel_data.CustomPropertyRef dataclass

CustomPropertyRef(id: int)

A reference to a persisted custom property by its integer ID.

Used in GroupBy.property, Filter class methods, and Metric.property to reference a custom property that was previously created and saved in Mixpanel.

ATTRIBUTE DESCRIPTION
id

The custom property's server-assigned ID (must be positive).

TYPE: int

Example
from mixpanel_data import CustomPropertyRef, GroupBy

ref = CustomPropertyRef(42)
g = GroupBy(property=ref, property_type="number")

id instance-attribute

id: int

The custom property's server-assigned ID.

mixpanel_data.InlineCustomProperty dataclass

InlineCustomProperty(
    formula: str,
    inputs: dict[str, PropertyInput],
    property_type: Literal["string", "number", "boolean", "datetime"]
    | None = None,
    resource_type: Literal["events", "people"] = "events",
)

An ephemeral computed property defined by a formula and input references.

Defines a custom property inline at query time without persisting it to Mixpanel. The formula uses variables (A-Z) that map to concrete properties via the inputs dict.

Can be used in GroupBy.property, Filter class methods, and Metric.property to compute derived values on the fly.

ATTRIBUTE DESCRIPTION
formula

Expression in Mixpanel's formula language (max 20,000 chars).

TYPE: str

inputs

Mapping from single uppercase letters (A-Z) to property references.

TYPE: dict[str, PropertyInput]

property_type

Result type of the formula. None defers to the containing type (e.g., GroupBy.property_type). Default: None.

TYPE: Literal['string', 'number', 'boolean', 'datetime'] | None

resource_type

Data domain — "events" or "people". Uses plural form to match Mixpanel's top-level customProperty schema. Default: "events".

TYPE: Literal['events', 'people']

Example
from mixpanel_data import InlineCustomProperty, PropertyInput

# Explicit construction
icp = InlineCustomProperty(
    formula="A * B",
    inputs={
        "A": PropertyInput("price", type="number"),
        "B": PropertyInput("quantity", type="number"),
    },
    property_type="number",
)

# Convenience constructor for all-numeric inputs
icp = InlineCustomProperty.numeric("A * B", A="price", B="quantity")

formula instance-attribute

formula: str

Expression in Mixpanel's formula language.

inputs instance-attribute

inputs: dict[str, PropertyInput]

Mapping from single uppercase letters (A-Z) to property references.

property_type class-attribute instance-attribute

property_type: Literal['string', 'number', 'boolean', 'datetime'] | None = None

Result type of the formula; None defers to containing type.

resource_type class-attribute instance-attribute

resource_type: Literal['events', 'people'] = 'events'

Data domain (plural form for top-level customProperty schema).

numeric classmethod

numeric(formula: str, /, **properties: str) -> InlineCustomProperty

Create an all-numeric-input inline custom property.

Convenience constructor that creates PropertyInput entries with type="number" and resource_type="event" for each keyword argument, and sets property_type="number".

PARAMETER DESCRIPTION
formula

Expression in Mixpanel's formula language.

TYPE: str

**properties

Mapping of variable letters to property names. Each key becomes an input key, each value becomes the property name.

TYPE: str DEFAULT: {}

RETURNS DESCRIPTION
InlineCustomProperty

InlineCustomProperty with all-numeric inputs and

InlineCustomProperty

property_type="number".

Example
# Revenue = price * quantity
icp = InlineCustomProperty.numeric("A * B", A="price", B="quantity")
assert icp.inputs["A"].type == "number"
assert icp.property_type == "number"
Source code in src/mixpanel_data/types.py
@classmethod
def numeric(
    cls,
    formula: str,
    /,
    **properties: str,
) -> InlineCustomProperty:
    """Create an all-numeric-input inline custom property.

    Convenience constructor that creates ``PropertyInput`` entries
    with ``type="number"`` and ``resource_type="event"`` for each
    keyword argument, and sets ``property_type="number"``.

    Args:
        formula: Expression in Mixpanel's formula language.
        **properties: Mapping of variable letters to property names.
            Each key becomes an input key, each value becomes the
            property name.

    Returns:
        InlineCustomProperty with all-numeric inputs and
        ``property_type="number"``.

    Example:
        ```python
        # Revenue = price * quantity
        icp = InlineCustomProperty.numeric("A * B", A="price", B="quantity")
        assert icp.inputs["A"].type == "number"
        assert icp.property_type == "number"
        ```
    """
    inputs = {
        key: PropertyInput(name=value, type="number")
        for key, value in properties.items()
    }
    return cls(
        formula=formula,
        inputs=inputs,
        property_type="number",
    )

mixpanel_data.PropertyInput dataclass

PropertyInput(
    name: str,
    type: Literal["string", "number", "boolean", "datetime", "list"] = "string",
    resource_type: Literal["event", "user"] = "event",
)

A raw property reference mapping a formula variable to a named property.

Used as an entry in :attr:InlineCustomProperty.inputs to bind a formula variable (A-Z) to a concrete Mixpanel event or user property.

ATTRIBUTE DESCRIPTION
name

The raw property name (e.g., "price", "$browser").

TYPE: str

type

Property data type. Default: "string".

TYPE: Literal['string', 'number', 'boolean', 'datetime', 'list']

resource_type

Property domain — "event" or "user". Uses singular form to match Mixpanel's composedProperties schema. Default: "event".

TYPE: Literal['event', 'user']

Example
from mixpanel_data import PropertyInput

pi = PropertyInput("price", type="number")
pi_user = PropertyInput("email", resource_type="user")

name instance-attribute

name: str

The raw property name.

type class-attribute instance-attribute

type: Literal['string', 'number', 'boolean', 'datetime', 'list'] = 'string'

Property data type.

resource_type class-attribute instance-attribute

resource_type: Literal['event', 'user'] = 'event'

Property domain (singular form for composedProperties schema).

Advanced Query Types

Types for advanced query features — period-over-period comparison, frequency analysis, and frequency filtering across query engines.

mixpanel_data.TimeComparison dataclass

TimeComparison(
    type: TimeComparisonType,
    unit: TimeComparisonUnit | None = None,
    date: str | None = None,
)

Overlay a comparison time period on insights, funnel, or retention queries.

Enables period-over-period analysis by specifying how the comparison window is determined. Three modes are supported:

  • relative: Compare against a prior period offset by unit (e.g. previous month, previous week).
  • absolute-start: Compare against a window starting on a fixed date (date), running the same duration as the primary range.
  • absolute-end: Compare against a window ending on a fixed date.

Use the factory class methods rather than constructing directly:

  • TimeComparison.relative(unit)
  • TimeComparison.absolute_start(date)
  • TimeComparison.absolute_end(date)
ATTRIBUTE DESCRIPTION
type

Discriminant — "relative", "absolute-start", or "absolute-end".

TYPE: TimeComparisonType

unit

Time unit for relative comparison. Required when type="relative", must be None otherwise.

TYPE: TimeComparisonUnit | None

date

ISO date (YYYY-MM-DD) for absolute comparison. Required when type is "absolute-start" or "absolute-end", must be None otherwise.

TYPE: str | None

RAISES DESCRIPTION
ValueError

If validation rules TC1-TC3 are violated during construction.

Example
from mixpanel_data.types import TimeComparison

# Compare against previous month
tc = TimeComparison.relative("month")

# Compare against window starting on a fixed date
tc = TimeComparison.absolute_start("2026-01-01")

# Compare against window ending on a fixed date
tc = TimeComparison.absolute_end("2026-12-31")

type instance-attribute

type: TimeComparisonType

Discriminant — "relative", "absolute-start", or "absolute-end".

unit class-attribute instance-attribute

unit: TimeComparisonUnit | None = None

Time unit for relative comparison (day, week, month, quarter, year).

date class-attribute instance-attribute

date: str | None = None

ISO date (YYYY-MM-DD) for absolute comparison.

__post_init__

__post_init__() -> None

Validate construction arguments (rules TC1-TC3).

RAISES DESCRIPTION
ValueError

If type="relative" and unit is None (TC1), or type="relative" and date is set (TC1), or type is absolute and date is None (TC2), or type is absolute and unit is set (TC2), or date does not match YYYY-MM-DD format (TC3).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments (rules TC1-TC3).

    Raises:
        ValueError: If type="relative" and unit is None (TC1),
            or type="relative" and date is set (TC1),
            or type is absolute and date is None (TC2),
            or type is absolute and unit is set (TC2),
            or date does not match YYYY-MM-DD format (TC3).
    """
    # TC0: type must be a valid TimeComparisonType
    valid_types = {"relative", "absolute-start", "absolute-end"}
    if self.type not in valid_types:
        raise ValueError(
            f"TimeComparison type must be one of {sorted(valid_types)}, "
            f"got {self.type!r}"
        )
    if self.type == "relative":
        # TC1: relative requires unit, rejects date
        if self.unit is None:
            raise ValueError(
                "TimeComparison type='relative' requires unit to be set "
                "(e.g., TimeComparison.relative('month'))"
            )
        # TC1b: unit must be a valid TimeComparisonUnit
        valid_units = {"day", "week", "month", "quarter", "year"}
        if self.unit not in valid_units:
            raise ValueError(
                f"TimeComparison unit must be one of {sorted(valid_units)}, "
                f"got {self.unit!r}"
            )
        if self.date is not None:
            raise ValueError(
                "TimeComparison type='relative' does not accept date; "
                "use absolute-start or absolute-end for date-based comparison"
            )
    else:
        # TC2: absolute-start / absolute-end requires date, rejects unit
        if self.date is None:
            raise ValueError(
                f"TimeComparison type={self.type!r} requires date to be set "
                f"(e.g., TimeComparison.absolute_start('2026-01-01'))"
            )
        if self.unit is not None:
            raise ValueError(
                f"TimeComparison type={self.type!r} does not accept unit; "
                f"unit is only valid for type='relative'"
            )
        # TC3: date must be a valid YYYY-MM-DD calendar date
        if not _DATE_RE.match(self.date):
            raise ValueError(
                f"TimeComparison date must be in YYYY-MM-DD format, "
                f"got {self.date!r}"
            )
        # TC3b: verify it's a real calendar date (e.g. reject 2026-02-30)
        try:
            import datetime

            datetime.date.fromisoformat(self.date)
        except ValueError:
            raise ValueError(
                f"TimeComparison date is not a valid calendar date: {self.date!r}"
            ) from None

relative classmethod

relative(unit: TimeComparisonUnit) -> TimeComparison

Create a relative time comparison.

Compares against a prior period offset by the given unit (e.g. previous month, previous week).

PARAMETER DESCRIPTION
unit

Time unit for the comparison offset. One of "day", "week", "month", "quarter", "year".

TYPE: TimeComparisonUnit

RETURNS DESCRIPTION
TimeComparison

A TimeComparison with type="relative" and the

TimeComparison

specified unit.

Example
tc = TimeComparison.relative("month")
# type="relative", unit="month", date=None
Source code in src/mixpanel_data/types.py
@classmethod
def relative(cls, unit: TimeComparisonUnit) -> TimeComparison:
    """Create a relative time comparison.

    Compares against a prior period offset by the given unit
    (e.g. previous month, previous week).

    Args:
        unit: Time unit for the comparison offset. One of
            ``"day"``, ``"week"``, ``"month"``, ``"quarter"``,
            ``"year"``.

    Returns:
        A ``TimeComparison`` with ``type="relative"`` and the
        specified ``unit``.

    Example:
        ```python
        tc = TimeComparison.relative("month")
        # type="relative", unit="month", date=None
        ```
    """
    return cls(type="relative", unit=unit)

absolute_start classmethod

absolute_start(date: str) -> TimeComparison

Create an absolute-start time comparison.

Compares against a window that starts on the given date, running the same duration as the primary query range.

PARAMETER DESCRIPTION
date

Start date in YYYY-MM-DD format.

TYPE: str

RETURNS DESCRIPTION
TimeComparison

A TimeComparison with type="absolute-start" and

TimeComparison

the specified date.

RAISES DESCRIPTION
ValueError

If date is not in YYYY-MM-DD format (TC3).

Example
tc = TimeComparison.absolute_start("2026-01-01")
# type="absolute-start", unit=None, date="2026-01-01"
Source code in src/mixpanel_data/types.py
@classmethod
def absolute_start(cls, date: str) -> TimeComparison:
    """Create an absolute-start time comparison.

    Compares against a window that starts on the given date,
    running the same duration as the primary query range.

    Args:
        date: Start date in YYYY-MM-DD format.

    Returns:
        A ``TimeComparison`` with ``type="absolute-start"`` and
        the specified ``date``.

    Raises:
        ValueError: If date is not in YYYY-MM-DD format (TC3).

    Example:
        ```python
        tc = TimeComparison.absolute_start("2026-01-01")
        # type="absolute-start", unit=None, date="2026-01-01"
        ```
    """
    return cls(type="absolute-start", date=date)

absolute_end classmethod

absolute_end(date: str) -> TimeComparison

Create an absolute-end time comparison.

Compares against a window that ends on the given date, running the same duration as the primary query range.

PARAMETER DESCRIPTION
date

End date in YYYY-MM-DD format.

TYPE: str

RETURNS DESCRIPTION
TimeComparison

A TimeComparison with type="absolute-end" and

TimeComparison

the specified date.

RAISES DESCRIPTION
ValueError

If date is not in YYYY-MM-DD format (TC3).

Example
tc = TimeComparison.absolute_end("2026-12-31")
# type="absolute-end", unit=None, date="2026-12-31"
Source code in src/mixpanel_data/types.py
@classmethod
def absolute_end(cls, date: str) -> TimeComparison:
    """Create an absolute-end time comparison.

    Compares against a window that ends on the given date,
    running the same duration as the primary query range.

    Args:
        date: End date in YYYY-MM-DD format.

    Returns:
        A ``TimeComparison`` with ``type="absolute-end"`` and
        the specified ``date``.

    Raises:
        ValueError: If date is not in YYYY-MM-DD format (TC3).

    Example:
        ```python
        tc = TimeComparison.absolute_end("2026-12-31")
        # type="absolute-end", unit=None, date="2026-12-31"
        ```
    """
    return cls(type="absolute-end", date=date)

mixpanel_data.FrequencyBreakdown dataclass

FrequencyBreakdown(
    event: str,
    bucket_size: int = 1,
    bucket_min: int = 0,
    bucket_max: int = 10,
    label: str | None = None,
)

Break down query results by how often users performed an event.

Used with Workspace.query() / build_params() in the group_by= parameter to segment users by event frequency.

ATTRIBUTE DESCRIPTION
event

Event name to count frequency for.

TYPE: str

bucket_size

Width of each frequency bucket. Default: 1.

TYPE: int

bucket_min

Minimum frequency value. Default: 0.

TYPE: int

bucket_max

Maximum frequency value. Default: 10.

TYPE: int

label

Display label for the breakdown. None generates "<event> Frequency" (e.g., "Purchase Frequency").

TYPE: str | None

RAISES DESCRIPTION
ValueError

If validation rules FB1-FB4 are violated.

Example
from mixpanel_data import FrequencyBreakdown

# How often users purchased (0-10 in increments of 1)
result = ws.query("Login", group_by=FrequencyBreakdown("Purchase"))

# Custom buckets: 0-50 in increments of 5
result = ws.query(
    "Login",
    group_by=FrequencyBreakdown(
        "Purchase", bucket_size=5, bucket_min=0, bucket_max=50
    ),
)

event instance-attribute

event: str

Event name to count frequency for.

bucket_size class-attribute instance-attribute

bucket_size: int = 1

Width of each frequency bucket.

bucket_min class-attribute instance-attribute

bucket_min: int = 0

Minimum frequency value.

bucket_max class-attribute instance-attribute

bucket_max: int = 10

Maximum frequency value.

label class-attribute instance-attribute

label: str | None = None

Display label for the breakdown.

__post_init__

__post_init__() -> None

Validate construction arguments (rules FB1-FB4).

RAISES DESCRIPTION
ValueError

If event is empty (FB1), bucket_size is not positive (FB2), bucket_min >= bucket_max (FB3), or bucket_min is negative (FB4).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments (rules FB1-FB4).

    Raises:
        ValueError: If event is empty (FB1), bucket_size is not
            positive (FB2), bucket_min >= bucket_max (FB3), or
            bucket_min is negative (FB4).
    """
    # FB1: event must be non-empty
    if not self.event.strip():
        raise ValueError("FrequencyBreakdown.event must be a non-empty string")
    # FB2: bucket_size must be positive
    if self.bucket_size <= 0:
        raise ValueError(
            f"FrequencyBreakdown.bucket_size must be positive, "
            f"got {self.bucket_size}"
        )
    # FB4: bucket_min must be non-negative (check before FB3 for clarity)
    if self.bucket_min < 0:
        raise ValueError(
            f"FrequencyBreakdown.bucket_min must be non-negative, "
            f"got {self.bucket_min}"
        )
    # FB3: bucket_min must be < bucket_max
    if self.bucket_min >= self.bucket_max:
        raise ValueError(
            f"FrequencyBreakdown.bucket_min ({self.bucket_min}) must be "
            f"less than bucket_max ({self.bucket_max})"
        )

mixpanel_data.FrequencyFilter dataclass

FrequencyFilter(
    event: str,
    value: int | float,
    operator: FrequencyFilterOperator = "is at least",
    date_range_value: int | None = None,
    date_range_unit: Literal["day", "week", "month"] | None = None,
    event_filters: list[Filter] | None = None,
    label: str | None = None,
)

Filter query results by how often users performed an event.

Used with Workspace.query() / build_params() in the where= parameter to restrict results to users meeting a frequency threshold.

ATTRIBUTE DESCRIPTION
event

Event name to count frequency for.

TYPE: str

operator

Comparison operator. Default: "is at least".

TYPE: FrequencyFilterOperator

value

Threshold value for the comparison.

TYPE: int | float

date_range_value

Lookback window size. Must be paired with date_range_unit.

TYPE: int | None

date_range_unit

Lookback window unit ("day", "week", "month"). Must be paired with date_range_value.

TYPE: Literal['day', 'week', 'month'] | None

event_filters

Property filters applied to the frequency event before counting.

TYPE: list[Filter] | None

label

Display label for the filter.

TYPE: str | None

RAISES DESCRIPTION
ValueError

If validation rules FF1-FF5 are violated.

Example
from mixpanel_data import FrequencyFilter

# Users who logged in at least 5 times
result = ws.query("Purchase", where=FrequencyFilter("Login", value=5))

# Users who purchased 3+ times in the last 30 days
result = ws.query(
    "Login",
    where=FrequencyFilter(
        "Purchase",
        value=3,
        date_range_value=30,
        date_range_unit="day",
    ),
)

event instance-attribute

event: str

Event name to count frequency for.

value instance-attribute

value: int | float

Threshold value for the comparison.

operator class-attribute instance-attribute

operator: FrequencyFilterOperator = 'is at least'

Comparison operator.

date_range_value class-attribute instance-attribute

date_range_value: int | None = None

Lookback window size.

date_range_unit class-attribute instance-attribute

date_range_unit: Literal['day', 'week', 'month'] | None = None

Lookback window unit.

event_filters class-attribute instance-attribute

event_filters: list[Filter] | None = None

Property filters applied to the frequency event.

label class-attribute instance-attribute

label: str | None = None

Display label for the filter.

__post_init__

__post_init__() -> None

Validate construction arguments (rules FF1-FF5).

RAISES DESCRIPTION
ValueError

If event is empty (FF1), operator is invalid (FF2), value is negative (FF3), date_range_value and date_range_unit are not both set or both None (FF4), or date_range_value is not positive when set (FF5).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments (rules FF1-FF5).

    Raises:
        ValueError: If event is empty (FF1), operator is invalid
            (FF2), value is negative (FF3), date_range_value and
            date_range_unit are not both set or both None (FF4),
            or date_range_value is not positive when set (FF5).
    """
    from mixpanel_data._internal.bookmark_enums import (
        VALID_FREQUENCY_FILTER_OPERATORS,
    )

    # FF1: event must be non-empty
    if not self.event.strip():
        raise ValueError("FrequencyFilter.event must be a non-empty string")
    # FF2: operator must be valid
    if self.operator not in VALID_FREQUENCY_FILTER_OPERATORS:
        valid = ", ".join(sorted(VALID_FREQUENCY_FILTER_OPERATORS))
        raise ValueError(
            f"FrequencyFilter.operator must be one of: {valid}; "
            f"got {self.operator!r}"
        )
    # FF3: value must be non-negative
    if self.value < 0:
        raise ValueError(
            f"FrequencyFilter.value must be non-negative, got {self.value}"
        )
    # FF4: date_range_value and date_range_unit must both be set or both None
    has_value = self.date_range_value is not None
    has_unit = self.date_range_unit is not None
    if has_value != has_unit:
        raise ValueError(
            "FrequencyFilter.date_range_value and date_range_unit must "
            "both be set or both be None; got date_range_value="
            f"{self.date_range_value!r}, date_range_unit="
            f"{self.date_range_unit!r}"
        )
    # FF5: date_range_value must be positive if set
    if self.date_range_value is not None and self.date_range_value <= 0:
        raise ValueError(
            f"FrequencyFilter.date_range_value must be positive when set, "
            f"got {self.date_range_value}"
        )

Cohort Definition Types

Types for building inline cohort definitions programmatically — used with Filter.in_cohort(), CohortBreakdown, and CohortMetric.

mixpanel_data.CohortDefinition dataclass

CohortDefinition(*criteria: CohortCriteria | CohortDefinition)

A composed set of criteria combined with AND/OR logic.

Produces valid Mixpanel cohort definition JSON (legacy selector + behaviors format) via to_dict(). Behavior keys are globally re-indexed to ensure uniqueness across arbitrary nesting.

Example
from mixpanel_data import CohortCriteria, CohortDefinition

cohort = CohortDefinition.all_of(
    CohortCriteria.has_property("plan", "premium"),
    CohortCriteria.did_event("Purchase", at_least=3, within_days=30),
)
result = cohort.to_dict()
# {"selector": {...}, "behaviors": {"bhvr_0": {...}}}

Create a definition combining criteria with AND logic.

Equivalent to CohortDefinition.all_of(*criteria).

PARAMETER DESCRIPTION
*criteria

One or more criteria or nested definitions.

TYPE: CohortCriteria | CohortDefinition DEFAULT: ()

RAISES DESCRIPTION
ValueError

If no criteria are provided (CD9).

Source code in src/mixpanel_data/types.py
def __init__(
    self,
    *criteria: CohortCriteria | CohortDefinition,
) -> None:
    """Create a definition combining criteria with AND logic.

    Equivalent to ``CohortDefinition.all_of(*criteria)``.

    Args:
        *criteria: One or more criteria or nested definitions.

    Raises:
        ValueError: If no criteria are provided (CD9).
    """
    if not criteria:
        raise ValueError("CohortDefinition requires at least one criterion")
    object.__setattr__(self, "_criteria", criteria)
    object.__setattr__(self, "_operator", "and")

all_of classmethod

all_of(*criteria: CohortCriteria | CohortDefinition) -> CohortDefinition

Combine criteria and/or definitions with AND logic.

PARAMETER DESCRIPTION
*criteria

One or more criteria or nested definitions.

TYPE: CohortCriteria | CohortDefinition DEFAULT: ()

RETURNS DESCRIPTION
CohortDefinition

CohortDefinition with AND combinator.

RAISES DESCRIPTION
ValueError

If no criteria are provided (CD9).

Source code in src/mixpanel_data/types.py
@classmethod
def all_of(
    cls,
    *criteria: CohortCriteria | CohortDefinition,
) -> CohortDefinition:
    """Combine criteria and/or definitions with AND logic.

    Args:
        *criteria: One or more criteria or nested definitions.

    Returns:
        CohortDefinition with AND combinator.

    Raises:
        ValueError: If no criteria are provided (CD9).
    """
    if not criteria:
        raise ValueError("CohortDefinition requires at least one criterion")
    instance = cls.__new__(cls)
    object.__setattr__(instance, "_criteria", criteria)
    object.__setattr__(instance, "_operator", "and")
    return instance

any_of classmethod

any_of(*criteria: CohortCriteria | CohortDefinition) -> CohortDefinition

Combine criteria and/or definitions with OR logic.

PARAMETER DESCRIPTION
*criteria

One or more criteria or nested definitions.

TYPE: CohortCriteria | CohortDefinition DEFAULT: ()

RETURNS DESCRIPTION
CohortDefinition

CohortDefinition with OR combinator.

RAISES DESCRIPTION
ValueError

If no criteria are provided (CD9).

Source code in src/mixpanel_data/types.py
@classmethod
def any_of(
    cls,
    *criteria: CohortCriteria | CohortDefinition,
) -> CohortDefinition:
    """Combine criteria and/or definitions with OR logic.

    Args:
        *criteria: One or more criteria or nested definitions.

    Returns:
        CohortDefinition with OR combinator.

    Raises:
        ValueError: If no criteria are provided (CD9).
    """
    if not criteria:
        raise ValueError("CohortDefinition requires at least one criterion")
    instance = cls.__new__(cls)
    object.__setattr__(instance, "_criteria", criteria)
    object.__setattr__(instance, "_operator", "or")
    return instance

to_dict

to_dict() -> dict[str, Any]

Serialize to Mixpanel cohort definition format.

Produces {"selector": {...}, "behaviors": {...}} with globally re-indexed behavior keys (bhvr_0, bhvr_1, ...) ensuring uniqueness across arbitrary nesting depth.

RETURNS DESCRIPTION
dict[str, Any]

Dict with selector expression tree and behaviors map.

Example
cohort = CohortDefinition.all_of(
    CohortCriteria.has_property("plan", "premium"),
    CohortCriteria.did_event("Purchase", at_least=3, within_days=30),
)
data = cohort.to_dict()
# {"selector": {"operator": "and", "children": [...]},
#  "behaviors": {"bhvr_0": {...}}}

# Pass directly to cohort CRUD:
ws.create_cohort(CreateCohortParams(
    name="Premium Purchasers",
    definition=data,
))
Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize to Mixpanel cohort definition format.

    Produces ``{"selector": {...}, "behaviors": {...}}`` with globally
    re-indexed behavior keys (``bhvr_0``, ``bhvr_1``, ...) ensuring
    uniqueness across arbitrary nesting depth.

    Returns:
        Dict with ``selector`` expression tree and ``behaviors`` map.

    Example:
        ```python
        cohort = CohortDefinition.all_of(
            CohortCriteria.has_property("plan", "premium"),
            CohortCriteria.did_event("Purchase", at_least=3, within_days=30),
        )
        data = cohort.to_dict()
        # {"selector": {"operator": "and", "children": [...]},
        #  "behaviors": {"bhvr_0": {...}}}

        # Pass directly to cohort CRUD:
        ws.create_cohort(CreateCohortParams(
            name="Premium Purchasers",
            definition=data,
        ))
        ```
    """
    # CD10: Behavior key uniqueness is enforced by sequential re-indexing
    # (bhvr_0, bhvr_1, ...) during tree traversal below.
    behaviors: dict[str, Any] = {}
    counter = [0]  # mutable container for closure

    def _collect_and_build(
        item: CohortCriteria | CohortDefinition,
    ) -> dict[str, Any]:
        """Recursively build selector tree and collect behaviors.

        Args:
            item: Criterion or nested definition to process.

        Returns:
            Selector node dict (leaf or combinator).
        """
        if isinstance(item, CohortCriteria):
            # Deep copy: operand may be a mutable list (e.g. has_property
            # with list value), so shallow dict() is not sufficient.
            node = copy.deepcopy(item._selector_node)
            if item._behavior_key is not None and item._behavior is not None:
                new_key = f"bhvr_{counter[0]}"
                counter[0] += 1
                behaviors[new_key] = copy.deepcopy(item._behavior)
                node["value"] = new_key
            return node
        # CohortDefinition: recurse into children
        children = [_collect_and_build(c) for c in item._criteria]
        return {
            "operator": item._operator,
            "children": children,
        }

    selector = _collect_and_build(self)
    return {"selector": selector, "behaviors": behaviors}

mixpanel_data.CohortCriteria dataclass

CohortCriteria(
    _selector_node: dict[str, Any],
    _behavior_key: str | None,
    _behavior: dict[str, Any] | None,
)

A single atomic condition for cohort membership.

Constructed exclusively via class methods — never instantiate directly. Produces selector nodes and behavior entries for the Mixpanel cohort definition format (legacy selector + behaviors JSON).

Example
from mixpanel_data import CohortCriteria

# Behavioral criterion
c = CohortCriteria.did_event("Purchase", at_least=3, within_days=30)

# Property criterion
c = CohortCriteria.has_property("plan", "premium")

# Cohort reference
c = CohortCriteria.in_cohort(456)

did_event classmethod

did_event(
    event: str,
    *,
    at_least: int | None = None,
    at_most: int | None = None,
    exactly: int | None = None,
    within_days: int | None = None,
    within_weeks: int | None = None,
    within_months: int | None = None,
    from_date: str | None = None,
    to_date: str | None = None,
    where: Filter | list[Filter] | None = None,
    aggregation: CohortAggregationType | None = None,
    aggregation_property: str | None = None,
) -> CohortCriteria

Create a behavioral criterion based on event frequency.

PARAMETER DESCRIPTION
event

Event name (must be non-empty).

TYPE: str

at_least

Minimum event count (>=).

TYPE: int | None DEFAULT: None

at_most

Maximum event count (<=).

TYPE: int | None DEFAULT: None

exactly

Exact event count (==).

TYPE: int | None DEFAULT: None

within_days

Rolling window in days.

TYPE: int | None DEFAULT: None

within_weeks

Rolling window in weeks.

TYPE: int | None DEFAULT: None

within_months

Rolling window in months.

TYPE: int | None DEFAULT: None

from_date

Absolute start date (YYYY-MM-DD).

TYPE: str | None DEFAULT: None

to_date

Absolute end date (YYYY-MM-DD).

TYPE: str | None DEFAULT: None

where

Event property filter(s).

TYPE: Filter | list[Filter] | None DEFAULT: None

aggregation

Aggregation operator for property-based thresholds (total, unique, average, min, max, median). Must be paired with aggregation_property.

TYPE: CohortAggregationType | None DEFAULT: None

aggregation_property

Event property to aggregate (e.g., "amount"). Must be paired with aggregation.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria with behavioral selector node and behavior entry.

RAISES DESCRIPTION
ValueError

If no frequency param or multiple are set, frequency is negative, event name is empty/whitespace, time constraints are missing or conflicting, dates are malformed/misordered, or aggregation and aggregation_property are not both set or both None (CA1/CA2).

Source code in src/mixpanel_data/types.py
@classmethod
def did_event(
    cls,
    event: str,
    *,
    at_least: int | None = None,
    at_most: int | None = None,
    exactly: int | None = None,
    within_days: int | None = None,
    within_weeks: int | None = None,
    within_months: int | None = None,
    from_date: str | None = None,
    to_date: str | None = None,
    where: Filter | list[Filter] | None = None,
    aggregation: CohortAggregationType | None = None,
    aggregation_property: str | None = None,
) -> CohortCriteria:
    """Create a behavioral criterion based on event frequency.

    Args:
        event: Event name (must be non-empty).
        at_least: Minimum event count (``>=``).
        at_most: Maximum event count (``<=``).
        exactly: Exact event count (``==``).
        within_days: Rolling window in days.
        within_weeks: Rolling window in weeks.
        within_months: Rolling window in months.
        from_date: Absolute start date (YYYY-MM-DD).
        to_date: Absolute end date (YYYY-MM-DD).
        where: Event property filter(s).
        aggregation: Aggregation operator for property-based thresholds
            (total, unique, average, min, max, median). Must be paired
            with ``aggregation_property``.
        aggregation_property: Event property to aggregate (e.g.,
            ``"amount"``). Must be paired with ``aggregation``.

    Returns:
        CohortCriteria with behavioral selector node and behavior entry.

    Raises:
        ValueError: If no frequency param or multiple are set, frequency is
            negative, event name is empty/whitespace, time constraints are
            missing or conflicting, dates are malformed/misordered, or
            aggregation and aggregation_property are not both set or both
            None (CA1/CA2).
    """
    # CD4: Event name must be non-empty
    if not event or not event.strip():
        raise ValueError("event name must be non-empty")

    # CA1/CA2: aggregation and aggregation_property must both be set or both None
    if (aggregation is None) != (aggregation_property is None):
        raise ValueError(
            "aggregation and aggregation_property must both be set or both be None"
        )

    if aggregation_property is not None and not aggregation_property.strip():
        raise ValueError("aggregation_property must be a non-empty string")

    # CD1: Exactly one frequency param required
    freq_params = {
        "at_least": at_least,
        "at_most": at_most,
        "exactly": exactly,
    }
    set_freqs = {k: v for k, v in freq_params.items() if v is not None}
    if len(set_freqs) != 1:
        raise ValueError("exactly one of at_least, at_most, exactly must be set")

    freq_name, freq_value = next(iter(set_freqs.items()))

    # CD2: Frequency param must be non-negative
    if freq_value < 0:
        raise ValueError("frequency value must be >= 0")

    # Map frequency param to selector operator
    freq_operator_map = {
        "at_least": ">=",
        "at_most": "<=",
        "exactly": "==",
    }
    selector_operator = freq_operator_map[freq_name]

    # CD3: Exactly one time constraint required
    rolling_params = {
        "within_days": within_days,
        "within_weeks": within_weeks,
        "within_months": within_months,
    }
    set_rolling = {k: v for k, v in rolling_params.items() if v is not None}
    has_date_range = from_date is not None or to_date is not None

    if not set_rolling and not has_date_range:
        raise ValueError(
            "exactly one time constraint required "
            "(within_days/weeks/months or from_date+to_date)"
        )
    if set_rolling and has_date_range:
        raise ValueError(
            "exactly one time constraint required "
            "(within_days/weeks/months or from_date+to_date)"
        )
    if len(set_rolling) > 1:
        raise ValueError(
            "exactly one time constraint required "
            "(within_days/weeks/months or from_date+to_date)"
        )

    # Build behavior entry
    behavior_key = "bhvr_0"  # placeholder, re-indexed by to_dict()

    event_selector: dict[str, Any] = {
        "event": event,
        "selector": None,
    }
    if where is not None:
        where_list = [where] if isinstance(where, Filter) else where
        if where_list:
            event_selector["selector"] = _build_event_selector(where_list)

    count_dict: dict[str, Any] = {
        "event_selector": event_selector,
        "type": "absolute",
    }

    # Add aggregation fields when set
    if aggregation is not None and aggregation_property is not None:
        count_dict["aggregationOperator"] = aggregation
        count_dict["property"] = aggregation_property

    behavior: dict[str, Any] = {
        "count": count_dict,
    }

    if set_rolling:
        rolling_name, rolling_value = next(iter(set_rolling.items()))
        if rolling_value <= 0:
            raise ValueError("time window value must be positive")
        unit_map = {
            "within_days": "day",
            "within_weeks": "week",
            "within_months": "month",
        }
        behavior["window"] = {
            "unit": unit_map[rolling_name],
            "value": rolling_value,
        }
    else:
        # Absolute date range
        # CD5: from_date requires to_date (and vice versa)
        if from_date is not None and to_date is None:
            raise ValueError("from_date requires to_date")
        if to_date is not None and from_date is None:
            raise ValueError("to_date requires from_date")

        # CD6: Dates must be YYYY-MM-DD
        # from_date and to_date are guaranteed non-None here:
        # has_date_range is True and CD5 guards above reject mismatched pairs.
        if from_date is None or to_date is None:  # pragma: no cover
            raise ValueError(
                "exactly one time constraint required "
                "(within_days/weeks/months or from_date+to_date)"
            )
        _validate_cohort_date(from_date)
        _validate_cohort_date(to_date)
        if dt_date.fromisoformat(from_date) > dt_date.fromisoformat(to_date):
            raise ValueError("from_date must be before or equal to to_date")

        behavior["from_date"] = from_date
        behavior["to_date"] = to_date

    selector_node: dict[str, Any] = {
        "property": "behaviors",
        "value": behavior_key,
        "operator": selector_operator,
        "operand": freq_value,
    }

    return cls(
        _selector_node=selector_node,
        _behavior_key=behavior_key,
        _behavior=behavior,
    )

did_not_do_event classmethod

did_not_do_event(
    event: str,
    *,
    within_days: int | None = None,
    within_weeks: int | None = None,
    within_months: int | None = None,
    from_date: str | None = None,
    to_date: str | None = None,
) -> CohortCriteria

Create a criterion for users who did NOT perform an event.

Shorthand for did_event(event, exactly=0, ...).

PARAMETER DESCRIPTION
event

Event name.

TYPE: str

within_days

Rolling window in days.

TYPE: int | None DEFAULT: None

within_weeks

Rolling window in weeks.

TYPE: int | None DEFAULT: None

within_months

Rolling window in months.

TYPE: int | None DEFAULT: None

from_date

Absolute start date (YYYY-MM-DD).

TYPE: str | None DEFAULT: None

to_date

Absolute end date (YYYY-MM-DD).

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria equivalent to did_event(event, exactly=0, ...).

RAISES DESCRIPTION
ValueError

On constraint violations.

Source code in src/mixpanel_data/types.py
@classmethod
def did_not_do_event(
    cls,
    event: str,
    *,
    within_days: int | None = None,
    within_weeks: int | None = None,
    within_months: int | None = None,
    from_date: str | None = None,
    to_date: str | None = None,
) -> CohortCriteria:
    """Create a criterion for users who did NOT perform an event.

    Shorthand for ``did_event(event, exactly=0, ...)``.

    Args:
        event: Event name.
        within_days: Rolling window in days.
        within_weeks: Rolling window in weeks.
        within_months: Rolling window in months.
        from_date: Absolute start date (YYYY-MM-DD).
        to_date: Absolute end date (YYYY-MM-DD).

    Returns:
        CohortCriteria equivalent to ``did_event(event, exactly=0, ...)``.

    Raises:
        ValueError: On constraint violations.
    """
    return cls.did_event(
        event,
        exactly=0,
        within_days=within_days,
        within_weeks=within_weeks,
        within_months=within_months,
        from_date=from_date,
        to_date=to_date,
    )

has_property classmethod

has_property(
    property: str,
    value: str | int | float | bool | list[str],
    *,
    operator: Literal[
        "equals",
        "not_equals",
        "contains",
        "not_contains",
        "greater_than",
        "less_than",
        "is_set",
        "is_not_set",
    ] = "equals",
    property_type: Literal[
        "string", "number", "boolean", "datetime", "list"
    ] = "string",
) -> CohortCriteria

Create a property-based criterion.

PARAMETER DESCRIPTION
property

Property name (must be non-empty).

TYPE: str

value

Value to compare against.

TYPE: str | int | float | bool | list[str]

operator

Comparison operator. Default: "equals".

TYPE: Literal['equals', 'not_equals', 'contains', 'not_contains', 'greater_than', 'less_than', 'is_set', 'is_not_set'] DEFAULT: 'equals'

property_type

Data type of the property. Default: "string".

TYPE: Literal['string', 'number', 'boolean', 'datetime', 'list'] DEFAULT: 'string'

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria with property selector node.

RAISES DESCRIPTION
ValueError

If property name is empty (CD7).

Source code in src/mixpanel_data/types.py
@classmethod
def has_property(
    cls,
    property: str,
    value: str | int | float | bool | list[str],
    *,
    operator: Literal[
        "equals",
        "not_equals",
        "contains",
        "not_contains",
        "greater_than",
        "less_than",
        "is_set",
        "is_not_set",
    ] = "equals",
    property_type: Literal[
        "string",
        "number",
        "boolean",
        "datetime",
        "list",
    ] = "string",
) -> CohortCriteria:
    """Create a property-based criterion.

    Args:
        property: Property name (must be non-empty).
        value: Value to compare against.
        operator: Comparison operator. Default: ``"equals"``.
        property_type: Data type of the property. Default: ``"string"``.

    Returns:
        CohortCriteria with property selector node.

    Raises:
        ValueError: If property name is empty (CD7).
    """
    # CD7: Property name must be non-empty
    if not property or not property.strip():
        raise ValueError("property name must be non-empty")

    selector_operator = _PROPERTY_OPERATOR_MAP[operator]

    selector_node: dict[str, Any] = {
        "property": "user",
        "value": property,
        "operator": selector_operator,
        "operand": value,
        "type": property_type,
    }

    return cls(
        _selector_node=selector_node,
        _behavior_key=None,
        _behavior=None,
    )

property_is_set classmethod

property_is_set(property: str) -> CohortCriteria

Check if a user property exists.

Shorthand for has_property(property, "", operator="is_set").

PARAMETER DESCRIPTION
property

Property name.

TYPE: str

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria checking property existence.

RAISES DESCRIPTION
ValueError

If property name is empty (CD7).

Source code in src/mixpanel_data/types.py
@classmethod
def property_is_set(cls, property: str) -> CohortCriteria:
    """Check if a user property exists.

    Shorthand for ``has_property(property, "", operator="is_set")``.

    Args:
        property: Property name.

    Returns:
        CohortCriteria checking property existence.

    Raises:
        ValueError: If property name is empty (CD7).
    """
    return cls.has_property(property, "", operator="is_set")

property_is_not_set classmethod

property_is_not_set(property: str) -> CohortCriteria

Check if a user property does not exist.

Shorthand for has_property(property, "", operator="is_not_set").

PARAMETER DESCRIPTION
property

Property name.

TYPE: str

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria checking property non-existence.

RAISES DESCRIPTION
ValueError

If property name is empty (CD7).

Source code in src/mixpanel_data/types.py
@classmethod
def property_is_not_set(cls, property: str) -> CohortCriteria:
    """Check if a user property does not exist.

    Shorthand for ``has_property(property, "", operator="is_not_set")``.

    Args:
        property: Property name.

    Returns:
        CohortCriteria checking property non-existence.

    Raises:
        ValueError: If property name is empty (CD7).
    """
    return cls.has_property(property, "", operator="is_not_set")

in_cohort classmethod

in_cohort(cohort_id: int) -> CohortCriteria

Create a criterion for membership in a saved cohort.

PARAMETER DESCRIPTION
cohort_id

Cohort ID (must be positive integer).

TYPE: int

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria with cohort reference selector node.

RAISES DESCRIPTION
ValueError

If cohort_id is not a positive integer (CD8).

Source code in src/mixpanel_data/types.py
@classmethod
def in_cohort(cls, cohort_id: int) -> CohortCriteria:
    """Create a criterion for membership in a saved cohort.

    Args:
        cohort_id: Cohort ID (must be positive integer).

    Returns:
        CohortCriteria with cohort reference selector node.

    Raises:
        ValueError: If cohort_id is not a positive integer (CD8).
    """
    if cohort_id <= 0:
        raise ValueError("cohort_id must be a positive integer")

    selector_node: dict[str, Any] = {
        "property": "cohort",
        "value": cohort_id,
        "operator": "in",
    }

    return cls(
        _selector_node=selector_node,
        _behavior_key=None,
        _behavior=None,
    )

not_in_cohort classmethod

not_in_cohort(cohort_id: int) -> CohortCriteria

Create a criterion for non-membership in a saved cohort.

PARAMETER DESCRIPTION
cohort_id

Cohort ID (must be positive integer).

TYPE: int

RETURNS DESCRIPTION
CohortCriteria

CohortCriteria with cohort exclusion selector node.

RAISES DESCRIPTION
ValueError

If cohort_id is not a positive integer (CD8).

Source code in src/mixpanel_data/types.py
@classmethod
def not_in_cohort(cls, cohort_id: int) -> CohortCriteria:
    """Create a criterion for non-membership in a saved cohort.

    Args:
        cohort_id: Cohort ID (must be positive integer).

    Returns:
        CohortCriteria with cohort exclusion selector node.

    Raises:
        ValueError: If cohort_id is not a positive integer (CD8).
    """
    if cohort_id <= 0:
        raise ValueError("cohort_id must be a positive integer")

    selector_node: dict[str, Any] = {
        "property": "cohort",
        "value": cohort_id,
        "operator": "not in",
    }

    return cls(
        _selector_node=selector_node,
        _behavior_key=None,
        _behavior=None,
    )

Funnel Query Types

Types for Workspace.query_funnel() — typed funnel conversion analysis with step definitions, exclusions, and conversion windows.

mixpanel_data.FunnelStep dataclass

FunnelStep(
    event: str,
    label: str | None = None,
    filters: list[Filter] | None = None,
    filters_combinator: FiltersCombinator = "all",
    order: FunnelOrder | None = None,
)

A single step in a funnel query.

Use plain event-name strings for simple funnels. Use FunnelStep objects when you need per-step filters, labels, or ordering overrides.

ATTRIBUTE DESCRIPTION
event

Mixpanel event name for this funnel step.

TYPE: str

label

Display label for this step. Defaults to the event name when None.

TYPE: str | None

filters

Per-step filter conditions. Each Filter restricts which events count for this step. None means no filters.

TYPE: list[Filter] | None

filters_combinator

How per-step filters combine. "all" requires all filters to match (AND logic). "any" requires any filter to match (OR logic).

TYPE: FiltersCombinator

order

Per-step ordering override. Only meaningful when the top-level funnel order is "any". None inherits the top-level order.

TYPE: FunnelOrder | None

Example
from mixpanel_data import FunnelStep, Filter

# Simple step (equivalent to just using "Signup" string)
step1 = FunnelStep("Signup")

# Step with per-step filter and label
step2 = FunnelStep(
    "Purchase",
    label="High-Value Purchase",
    filters=[Filter.greater_than("amount", 50)],
)

ws.query_funnel([step1, step2])

event instance-attribute

event: str

Mixpanel event name for this funnel step.

label class-attribute instance-attribute

label: str | None = None

Display label for this step (defaults to event name).

filters class-attribute instance-attribute

filters: list[Filter] | None = None

Per-step filter conditions.

filters_combinator class-attribute instance-attribute

filters_combinator: FiltersCombinator = 'all'

How per-step filters combine (AND/OR).

order class-attribute instance-attribute

order: FunnelOrder | None = None

Per-step ordering override (only meaningful with top-level order='any').

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If event is empty or contains control characters (FS1).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If event is empty or contains control characters (FS1).
    """
    _validate_event_name(self.event, "FunnelStep")

mixpanel_data.Exclusion dataclass

Exclusion(event: str, from_step: int = 0, to_step: int | None = None)

An event to exclude between funnel steps.

Users who perform the excluded event within the specified step range are removed from the funnel. Use plain strings for full-range exclusions; use Exclusion objects when you need to target specific step ranges.

ATTRIBUTE DESCRIPTION
event

Event name to exclude between steps.

TYPE: str

from_step

Start of exclusion range (0-indexed, inclusive). Defaults to 0 (first step).

TYPE: int

to_step

End of exclusion range (0-indexed, inclusive). None means up to the last step in the funnel.

TYPE: int | None

Example
from mixpanel_data import Exclusion

# Exclude between all steps (same as using string "Logout")
ex1 = Exclusion("Logout")

# Exclude only between steps 1 and 2
ex2 = Exclusion("Refund", from_step=1, to_step=2)

ws.query_funnel(
    ["Signup", "Add to Cart", "Purchase"],
    exclusions=[ex1, ex2],
)

event instance-attribute

event: str

Event name to exclude between steps.

from_step class-attribute instance-attribute

from_step: int = 0

Start of exclusion range (0-indexed, inclusive).

to_step class-attribute instance-attribute

to_step: int | None = None

End of exclusion range (0-indexed, inclusive). None = last step.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If event is empty (EX1), from_step is negative (EX2), or to_step < from_step (EX3).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If event is empty (EX1), from_step is negative
            (EX2), or to_step < from_step (EX3).
    """
    _validate_event_name(self.event, "Exclusion")
    if self.from_step < 0:
        raise ValueError(f"Exclusion.from_step must be >= 0, got {self.from_step}")
    if self.to_step is not None and self.to_step < self.from_step:
        raise ValueError(
            f"Exclusion.to_step ({self.to_step}) must be >= "
            f"from_step ({self.from_step})"
        )

mixpanel_data.HoldingConstant dataclass

HoldingConstant(
    property: str, resource_type: Literal["events", "people"] = "events"
)

A property to hold constant across all funnel steps.

When a property is held constant, only users whose property value is the same at every funnel step are counted as converting. For example, holding "platform" constant means a user who signed up on iOS but purchased on web is not counted as converting.

ATTRIBUTE DESCRIPTION
property

Property name to hold constant across steps.

TYPE: str

resource_type

Whether this is an event property or a user-profile property. Defaults to "events".

TYPE: Literal['events', 'people']

Example
from mixpanel_data import HoldingConstant

# Hold an event property constant (default)
hc1 = HoldingConstant("platform")

# Hold a user-profile property constant
hc2 = HoldingConstant("plan_tier", resource_type="people")

ws.query_funnel(
    ["Signup", "Purchase"],
    holding_constant=[hc1, hc2],
)

property instance-attribute

property: str

Property name to hold constant across steps.

resource_type class-attribute instance-attribute

resource_type: Literal['events', 'people'] = 'events'

Whether this is an event property or user-profile property.

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If property is empty (HC1).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If property is empty (HC1).
    """
    if not self.property or not self.property.strip():
        raise ValueError("HoldingConstant.property must be a non-empty string")

mixpanel_data.FunnelQueryResult dataclass

FunnelQueryResult(
    computed_at: str,
    from_date: str,
    to_date: str,
    steps_data: list[dict[str, Any]] = list(),
    series: dict[str, Any] = dict(),
    params: dict[str, Any] = dict(),
    meta: dict[str, Any] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Result of a funnel query via the insights API.

Contains step-level conversion data, timing information, the generated bookmark params (for debugging or persisting as a saved report), and a lazy DataFrame conversion.

Unlike FunnelResult (which wraps the legacy funnel API), this type wraps the richer bookmark-based insights API response and provides additional fields like avg_time, avg_time_from_start, and the params dict.

ATTRIBUTE DESCRIPTION
computed_at

When the query was computed (ISO format).

TYPE: str

from_date

Effective start date from the response.

TYPE: str

to_date

Effective end date from the response.

TYPE: str

steps_data

Step-level results. Each dict contains keys: event, count, step_conv_ratio, overall_conv_ratio, avg_time, avg_time_from_start.

TYPE: list[dict[str, Any]]

series

Raw series data from the API (for advanced use).

TYPE: dict[str, Any]

params

Generated bookmark params sent to the API (for debugging or persistence via create_bookmark).

TYPE: dict[str, Any]

meta

Response metadata (e.g. sampling_factor, is_cached).

TYPE: dict[str, Any]

Example
result = ws.query_funnel(["Signup", "Purchase"])

# Overall conversion
print(result.overall_conversion_rate)  # e.g. 0.12

# DataFrame view
print(result.df)
#   step  event   count  step_conv_ratio  overall_conv_ratio  ...

# Save as a report
ws.create_bookmark(CreateBookmarkParams(
    name="Signup → Purchase Funnel",
    bookmark_type="funnels",
    params=result.params,
))

computed_at instance-attribute

computed_at: str

When the query was computed (ISO format).

from_date instance-attribute

from_date: str

Effective start date from the response.

to_date instance-attribute

to_date: str

Effective end date from the response.

steps_data class-attribute instance-attribute

steps_data: list[dict[str, Any]] = field(default_factory=list)

Step-level results. Each dict conforms to :class:FunnelStepData (event, count, step_conv_ratio, overall_conv_ratio, avg_time, avg_time_from_start).

series class-attribute instance-attribute

series: dict[str, Any] = field(default_factory=dict)

Raw series data from the API.

params class-attribute instance-attribute

params: dict[str, Any] = field(default_factory=dict)

Generated bookmark params sent to API.

meta class-attribute instance-attribute

meta: dict[str, Any] = field(default_factory=dict)

Response metadata. Conforms to :class:QueryMeta (sampling_factor, is_cached, computation_time, query_id).

overall_conversion_rate property

overall_conversion_rate: float

End-to-end conversion rate from first to last step.

RETURNS DESCRIPTION
float

Float between 0.0 and 1.0 representing the fraction of

float

users who completed all funnel steps. Returns 0.0 if

float

steps_data is empty.

df property

df: DataFrame

Convert to DataFrame with one row per funnel step.

Columns: step, event, count, step_conv_ratio, overall_conv_ratio, avg_time, avg_time_from_start.

RETURNS DESCRIPTION
DataFrame

Normalized DataFrame with one row per step.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all FunnelQueryResult fields.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all FunnelQueryResult fields.
    """
    return {
        "computed_at": self.computed_at,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "steps_data": self.steps_data,
        "series": self.series,
        "params": self.params,
        "meta": self.meta,
    }

Retention Query Types

Types for Workspace.query_retention() — typed retention analysis with event pairs, custom buckets, alignment modes, and segmentation.

mixpanel_data.RetentionEvent dataclass

RetentionEvent(
    event: str,
    filters: list[Filter] | None = None,
    filters_combinator: FiltersCombinator = "all",
)

An event specification for retention queries.

Wraps an event name with optional per-event filters. Use plain event-name strings for simple retention queries. Use RetentionEvent objects when you need per-event filter conditions.

ATTRIBUTE DESCRIPTION
event

Mixpanel event name.

TYPE: str

filters

Per-event filter conditions. Each Filter restricts which events count. None means no filters.

TYPE: list[Filter] | None

filters_combinator

How per-event filters combine. "all" requires all filters to match (AND logic). "any" requires any filter to match (OR logic).

TYPE: FiltersCombinator

Example
from mixpanel_data import RetentionEvent, Filter

# Simple event (equivalent to just using "Signup" string)
born = RetentionEvent("Signup")

# Event with per-event filter
born = RetentionEvent(
    "Signup",
    filters=[Filter.equals("source", "organic")],
)

ws.query_retention(born, "Login")

event instance-attribute

event: str

Mixpanel event name.

filters class-attribute instance-attribute

filters: list[Filter] | None = None

Per-event filter conditions.

filters_combinator class-attribute instance-attribute

filters_combinator: FiltersCombinator = 'all'

How per-event filters combine (AND/OR).

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If event is empty or contains control characters (RE1).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If event is empty or contains control characters (RE1).
    """
    _validate_event_name(self.event, "RetentionEvent")

mixpanel_data.RetentionAlignment module-attribute

RetentionAlignment = Literal['birth', 'interval_start']

Retention alignment mode.

+------------------+----------------------------------------------+ | Value | Meaning | +==================+==============================================+ | birth | Align to each cohort's born date (default) | +------------------+----------------------------------------------+ | interval_start | Align all cohorts to the same start date | +------------------+----------------------------------------------+

mixpanel_data.RetentionMode module-attribute

RetentionMode = Literal['curve', 'trends', 'table']

Display mode for retention query results.

+--------+----------------------------------------------+ | Value | Meaning | +========+==============================================+ | curve | Retention curve (default) | +--------+----------------------------------------------+ | trends | Trend lines over time | +--------+----------------------------------------------+ | table | Tabular cohort x bucket grid | +--------+----------------------------------------------+

mixpanel_data.RetentionMathType module-attribute

RetentionMathType = Literal['retention_rate', 'unique', 'total', 'average']

Aggregation function for retention query metrics.

+----------------+----------------------------------------------+ | Value | Meaning | +================+==============================================+ | retention_rate | Percentage of users retained (default) | +----------------+----------------------------------------------+ | unique | Raw count of retained users | +----------------+----------------------------------------------+ | total | Total event count per retention bucket | +----------------+----------------------------------------------+ | average | Average of a numeric property per bucket | +----------------+----------------------------------------------+

Maps directly to the measurement.math field in bookmark JSON.

mixpanel_data.RetentionQueryResult dataclass

RetentionQueryResult(
    computed_at: str,
    from_date: str,
    to_date: str,
    cohorts: dict[str, dict[str, Any]] = dict(),
    average: dict[str, Any] = dict(),
    params: dict[str, Any] = dict(),
    meta: dict[str, Any] = dict(),
    segments: dict[str, dict[str, dict[str, Any]]] = dict(),
    segment_averages: dict[str, dict[str, Any]] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Result of a retention query via the insights API.

Contains cohort-level retention data, the generated bookmark params (for debugging or persisting as a saved report), and a lazy DataFrame conversion. Supports both unsegmented and segmented (group_by) queries.

ATTRIBUTE DESCRIPTION
computed_at

When the query was computed (ISO format).

TYPE: str

from_date

Effective start date from the response.

TYPE: str

to_date

Effective end date from the response.

TYPE: str

cohorts

Aggregate cohort-level retention data. Keys are cohort date strings (YYYY-MM-DD), values are dicts with first (cohort size), counts (list of retained user counts per bucket), and rates (list of retention rates per bucket). For segmented queries, this contains the $overall aggregate.

TYPE: dict[str, dict[str, Any]]

average

Synthetic $average cohort data. Same structure as individual cohort entries.

TYPE: dict[str, Any]

params

Generated bookmark params sent to the API (for debugging or persistence via create_bookmark).

TYPE: dict[str, Any]

meta

Response metadata (e.g. sampling_factor, is_cached).

TYPE: dict[str, Any]

segments

Per-segment cohort data. Maps segment name to a dict of cohort_date → {first, counts, rates}. Empty for unsegmented queries.

TYPE: dict[str, dict[str, dict[str, Any]]]

segment_averages

Per-segment $average cohort data. Maps segment name to {first, counts, rates}. Empty for unsegmented queries.

TYPE: dict[str, dict[str, Any]]

Example
# Unsegmented retention
result = ws.query_retention("Signup", "Login")
print(result.df)
#   cohort_date  bucket  count  rate

# Segmented retention
result = ws.query_retention(
    "Signup", "Login", group_by="platform"
)
print(result.df)
#   segment  cohort_date  bucket  count  rate
for name, cohorts in result.segments.items():
    print(f"{name}: {len(cohorts)} cohorts")

computed_at instance-attribute

computed_at: str

When the query was computed (ISO format).

from_date instance-attribute

from_date: str

Effective start date from the response.

to_date instance-attribute

to_date: str

Effective end date from the response.

cohorts class-attribute instance-attribute

cohorts: dict[str, dict[str, Any]] = field(default_factory=dict)

Cohort-level retention data. Each value conforms to :class:RetentionCohortData (first, counts, rates).

For segmented queries, this contains the $overall aggregate.

average class-attribute instance-attribute

average: dict[str, Any] = field(default_factory=dict)

Synthetic $average cohort data. Conforms to :class:RetentionCohortData.

params class-attribute instance-attribute

params: dict[str, Any] = field(default_factory=dict)

Generated bookmark params sent to API.

meta class-attribute instance-attribute

meta: dict[str, Any] = field(default_factory=dict)

Response metadata. Conforms to :class:QueryMeta.

segments class-attribute instance-attribute

segments: dict[str, dict[str, dict[str, Any]]] = field(default_factory=dict)

Per-segment cohort data. Each inner value conforms to :class:RetentionCohortData (first, counts, rates).

Empty for unsegmented queries. Populated when group_by is used and the API returns breakdown segments alongside $overall.

segment_averages class-attribute instance-attribute

segment_averages: dict[str, dict[str, Any]] = field(default_factory=dict)

Per-segment $average cohort data. Each value conforms to :class:RetentionCohortData.

Empty for unsegmented queries.

df property

df: DataFrame

Convert to DataFrame with one row per (cohort_date, bucket) pair.

For unsegmented queries, columns are: cohort_date, bucket, count, rate.

For segmented queries (when segments is non-empty), columns are: segment, cohort_date, bucket, count, rate.

RETURNS DESCRIPTION
DataFrame

Normalized DataFrame. Empty DataFrame with correct columns

DataFrame

if data is empty.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all RetentionQueryResult fields.

dict[str, Any]

Includes segments and segment_averages only

dict[str, Any]

when non-empty.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all RetentionQueryResult fields.
        Includes ``segments`` and ``segment_averages`` only
        when non-empty.
    """
    d: dict[str, Any] = {
        "computed_at": self.computed_at,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "cohorts": self.cohorts,
        "average": self.average,
        "params": self.params,
        "meta": self.meta,
    }
    if self.segments:
        d["segments"] = self.segments
    if self.segment_averages:
        d["segment_averages"] = self.segment_averages
    return d

Flow Query Types

Types for Workspace.query_flow() — typed flow path analysis with step definitions, direction controls, and visualization modes.

mixpanel_data.FlowStep dataclass

FlowStep(
    event: str,
    forward: int | None = None,
    reverse: int | None = None,
    label: str | None = None,
    filters: list[Filter] | None = None,
    filters_combinator: FiltersCombinator = "all",
    session_event: FlowSessionEvent | None = None,
)

An anchor event in a flow query with per-step configuration.

Each flow step identifies a specific event and optional constraints (forward/reverse step counts, filters) that define a node in the flow analysis.

ATTRIBUTE DESCRIPTION
event

The event name to anchor this step on.

TYPE: str

forward

Maximum number of forward steps to trace from this event. None means use the query-level default.

TYPE: int | None

reverse

Maximum number of reverse steps to trace from this event. None means use the query-level default.

TYPE: int | None

label

Optional display label for this step. If None, the event name is used as the label.

TYPE: str | None

filters

Optional list of Filter conditions to narrow the events matching this step. None means no per-step filtering.

TYPE: list[Filter] | None

filters_combinator

How to combine multiple filters — "all" requires every filter to match (AND), "any" requires at least one (OR). Defaults to "all".

TYPE: FiltersCombinator

session_event

Optional session anchor type — "start" or "end". When set, the event field must match the corresponding session event name ("$session_start" or "$session_end"). None means this is a regular event step. Default: None.

TYPE: FlowSessionEvent | None

Example
step = FlowStep(
    "Purchase",
    forward=5,
    reverse=3,
    label="Buy",
    filters=[Filter.equals("country", "US")],
    filters_combinator="all",
)

# Session anchor step
session_step = FlowStep(
    "$session_start",
    session_event="start",
)

__post_init__

__post_init__() -> None

Validate construction arguments.

RAISES DESCRIPTION
ValueError

If event is empty or contains control characters (FL1), forward/reverse is outside 0-5 range (FL2), or session_event conflicts with event name (FS1).

Source code in src/mixpanel_data/types.py
def __post_init__(self) -> None:
    """Validate construction arguments.

    Raises:
        ValueError: If event is empty or contains control characters
            (FL1), forward/reverse is outside 0-5 range (FL2), or
            session_event conflicts with event name (FS1).
    """
    _validate_event_name(self.event, "FlowStep")
    if self.forward is not None and not 0 <= self.forward <= 5:
        raise ValueError(
            f"FlowStep.forward must be in range 0-5, got {self.forward}"
        )
    if self.reverse is not None and not 0 <= self.reverse <= 5:
        raise ValueError(
            f"FlowStep.reverse must be in range 0-5, got {self.reverse}"
        )
    # FS1: Validate session_event / event consistency
    if self.session_event is not None:
        expected_event = (
            "$session_start" if self.session_event == "start" else "$session_end"
        )
        if self.event != expected_event:
            raise ValueError(
                f"FlowStep.session_event={self.session_event!r} requires "
                f"event={expected_event!r}, got {self.event!r}"
            )

mixpanel_data.FlowTreeNode dataclass

FlowTreeNode(
    event: str,
    type: FlowNodeType,
    step_number: int,
    total_count: int,
    drop_off_count: int = 0,
    converted_count: int = 0,
    anchor_type: FlowAnchorType = "NORMAL",
    is_computed: bool = False,
    children: tuple[FlowTreeNode, ...] = (),
    time_percentiles_from_start: dict[str, Any] = dict(),
    time_percentiles_from_prev: dict[str, Any] = dict(),
)

A node in a recursive flow prefix tree.

Represents a single event in a flow path tree returned by the Mixpanel Flows API when using mode="tree". Each node tracks aggregate counts (total, drop-off, converted) and optionally timing percentiles. Children represent subsequent events in the flow.

The tree preserves full path context — unlike the sankey graph which merges nodes at the same step position, each tree node is unique to its specific path from root.

ATTRIBUTE DESCRIPTION
event

The event name at this position in the flow.

TYPE: str

type

Node type — "ANCHOR", "NORMAL", "DROPOFF", "PRUNED", "FORWARD", or "REVERSE".

TYPE: FlowNodeType

step_number

Zero-based step index in the flow.

TYPE: int

total_count

Total number of users reaching this node.

TYPE: int

drop_off_count

Number of users who dropped off at this node.

TYPE: int

converted_count

Number of users who continued past this node.

TYPE: int

anchor_type

Anchor classification — "NORMAL", "RELATIVE_REVERSE", or "RELATIVE_FORWARD".

TYPE: FlowAnchorType

is_computed

Whether this is a computed/custom event.

TYPE: bool

children

Child nodes representing subsequent events. Defaults to an empty tuple.

TYPE: tuple[FlowTreeNode, ...]

time_percentiles_from_start

Timing percentile data from flow start to this node. Empty dict if timing data is not enabled.

TYPE: dict[str, Any]

time_percentiles_from_prev

Timing percentile data from the previous node to this node. Empty dict if timing data is not enabled.

TYPE: dict[str, Any]

Example
root = FlowTreeNode(
    event="Login", type="ANCHOR", step_number=0,
    total_count=1000, drop_off_count=50, converted_count=950,
    children=(
        FlowTreeNode(
            event="Search", type="NORMAL", step_number=1,
            total_count=600,
        ),
    ),
)
root.depth          # 1
root.conversion_rate  # 0.95
root.all_paths()    # [[root, search_node]]

depth property

depth: int

Maximum depth of the subtree rooted at this node.

A leaf node has depth 0. A node with one level of children has depth 1, and so on.

RETURNS DESCRIPTION
int

Non-negative integer representing the longest path from

int

this node to any leaf descendant.

Example
leaf = FlowTreeNode(
    event="Purchase", type="ANCHOR",
    step_number=0, total_count=100,
)
leaf.depth  # 0

node_count property

node_count: int

Total number of nodes in the subtree including this node.

RETURNS DESCRIPTION
int

Positive integer (always >= 1).

Example
node.node_count  # 7

leaf_count property

leaf_count: int

Number of leaf nodes (nodes with no children) in the subtree.

RETURNS DESCRIPTION
int

Positive integer (always >= 1).

Example
node.leaf_count  # 4

conversion_rate property

conversion_rate: float

Fraction of users who converted at this node.

Computed as converted_count / total_count. Returns 0.0 when total_count is zero to avoid division errors.

RETURNS DESCRIPTION
float

Float in [0.0, 1.0].

Example
node.conversion_rate  # 0.95

drop_off_rate property

drop_off_rate: float

Fraction of users who dropped off at this node.

Computed as drop_off_count / total_count. Returns 0.0 when total_count is zero to avoid division errors.

RETURNS DESCRIPTION
float

Float in [0.0, 1.0].

Example
node.drop_off_rate  # 0.05

all_paths

all_paths() -> list[list[FlowTreeNode]]

Return all root-to-leaf paths through this subtree.

Each path is a list of FlowTreeNode objects from this node down to a leaf, preserving the full node chain so callers can inspect counts, rates, and timing along each path.

RETURNS DESCRIPTION
list[list[FlowTreeNode]]

List of paths, where each path is a list of nodes. The

list[list[FlowTreeNode]]

number of paths equals leaf_count.

Example
for path in root.all_paths():
    events = [n.event for n in path]
    print(" -> ".join(events))
# Login -> Search -> Purchase
# Login -> Search -> DROPOFF
# Login -> Browse -> Purchase
# Login -> DROPOFF
Source code in src/mixpanel_data/types.py
def all_paths(self) -> list[list[FlowTreeNode]]:
    """Return all root-to-leaf paths through this subtree.

    Each path is a list of ``FlowTreeNode`` objects from this node
    down to a leaf, preserving the full node chain so callers can
    inspect counts, rates, and timing along each path.

    Returns:
        List of paths, where each path is a list of nodes. The
        number of paths equals ``leaf_count``.

    Example:
        ```python
        for path in root.all_paths():
            events = [n.event for n in path]
            print(" -> ".join(events))
        # Login -> Search -> Purchase
        # Login -> Search -> DROPOFF
        # Login -> Browse -> Purchase
        # Login -> DROPOFF
        ```
    """
    if not self.children:
        return [[self]]
    paths: list[list[FlowTreeNode]] = []
    for child in self.children:
        for child_path in child.all_paths():
            paths.append([self, *child_path])
    return paths

find

find(event: str) -> list[FlowTreeNode]

Find all nodes matching an event name via depth-first search.

PARAMETER DESCRIPTION
event

The event name to search for.

TYPE: str

RETURNS DESCRIPTION
list[FlowTreeNode]

List of matching FlowTreeNode objects. Empty list if

list[FlowTreeNode]

no nodes match.

Example
purchases = root.find("Purchase")
# [FlowTreeNode(event="Purchase", ...), ...]
Source code in src/mixpanel_data/types.py
def find(self, event: str) -> list[FlowTreeNode]:
    """Find all nodes matching an event name via depth-first search.

    Args:
        event: The event name to search for.

    Returns:
        List of matching ``FlowTreeNode`` objects. Empty list if
        no nodes match.

    Example:
        ```python
        purchases = root.find("Purchase")
        # [FlowTreeNode(event="Purchase", ...), ...]
        ```
    """
    results: list[FlowTreeNode] = []
    if self.event == event:
        results.append(self)
    for child in self.children:
        results.extend(child.find(event))
    return results

flatten

flatten() -> list[FlowTreeNode]

Return all nodes in pre-order (depth-first) traversal.

The root node appears first, followed by its children's subtrees in order.

RETURNS DESCRIPTION
list[FlowTreeNode]

List of all nodes in the subtree. Length equals

list[FlowTreeNode]

node_count.

Example
for node in root.flatten():
    print(f"{node.event}: {node.total_count}")
Source code in src/mixpanel_data/types.py
def flatten(self) -> list[FlowTreeNode]:
    """Return all nodes in pre-order (depth-first) traversal.

    The root node appears first, followed by its children's subtrees
    in order.

    Returns:
        List of all nodes in the subtree. Length equals
        ``node_count``.

    Example:
        ```python
        for node in root.flatten():
            print(f"{node.event}: {node.total_count}")
        ```
    """
    result: list[FlowTreeNode] = [self]
    for child in self.children:
        result.extend(child.flatten())
    return result

to_dict

to_dict() -> dict[str, Any]

Serialize the tree node recursively to a dictionary.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all node attributes and recursively

dict[str, Any]

serialized children. Suitable for JSON serialization.

Example
d = node.to_dict()
d["event"]     # "Login"
d["children"]  # [{"event": "Search", ...}, ...]
Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize the tree node recursively to a dictionary.

    Returns:
        Dictionary with all node attributes and recursively
        serialized children. Suitable for JSON serialization.

    Example:
        ```python
        d = node.to_dict()
        d["event"]     # "Login"
        d["children"]  # [{"event": "Search", ...}, ...]
        ```
    """
    return {
        "event": self.event,
        "type": self.type,
        "step_number": self.step_number,
        "total_count": self.total_count,
        "drop_off_count": self.drop_off_count,
        "converted_count": self.converted_count,
        "anchor_type": self.anchor_type,
        "is_computed": self.is_computed,
        "children": [c.to_dict() for c in self.children],
        "time_percentiles_from_start": self.time_percentiles_from_start,
        "time_percentiles_from_prev": self.time_percentiles_from_prev,
    }

render

render(_prefix: str = '', _is_last: bool = True, _is_root: bool = True) -> str

Render the tree as an ASCII string for debugging.

Uses box-drawing characters (├──, └──, ) to display the tree hierarchy with event names and counts.

PARAMETER DESCRIPTION
_prefix

Internal prefix for recursive indentation. Do not pass this argument directly.

TYPE: str DEFAULT: ''

_is_last

Internal flag for connector selection. Do not pass this argument directly.

TYPE: bool DEFAULT: True

_is_root

Internal flag distinguishing the root call from recursive children. Do not pass directly.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
str

Multi-line string representation of the tree.

Example
print(root.render())
# Login (1000)
# ├── Search (600)
# │   ├── Purchase (400)
# │   └── DROPOFF (100)
# ├── Browse (300)
# │   └── Purchase (200)
# └── DROPOFF (50)
Source code in src/mixpanel_data/types.py
def render(
    self,
    _prefix: str = "",
    _is_last: bool = True,
    _is_root: bool = True,
) -> str:
    """Render the tree as an ASCII string for debugging.

    Uses box-drawing characters (``\u251c\u2500\u2500``, ``\u2514\u2500\u2500``, ``\u2502``) to display
    the tree hierarchy with event names and counts.

    Args:
        _prefix: Internal prefix for recursive indentation.
            Do not pass this argument directly.
        _is_last: Internal flag for connector selection.
            Do not pass this argument directly.
        _is_root: Internal flag distinguishing the root call
            from recursive children. Do not pass directly.

    Returns:
        Multi-line string representation of the tree.

    Example:
        ```python
        print(root.render())
        # Login (1000)
        # \u251c\u2500\u2500 Search (600)
        # \u2502   \u251c\u2500\u2500 Purchase (400)
        # \u2502   \u2514\u2500\u2500 DROPOFF (100)
        # \u251c\u2500\u2500 Browse (300)
        # \u2502   \u2514\u2500\u2500 Purchase (200)
        # \u2514\u2500\u2500 DROPOFF (50)
        ```
    """
    if _is_root:
        line = f"{self.event} ({self.total_count})\n"
        child_prefix = ""
    else:
        connector = "\u2514\u2500\u2500 " if _is_last else "\u251c\u2500\u2500 "
        line = f"{_prefix}{connector}{self.event} ({self.total_count})\n"
        child_prefix = _prefix + ("    " if _is_last else "\u2502   ")

    for i, child in enumerate(self.children):
        is_last_child = i == len(self.children) - 1
        line += child.render(
            _prefix=child_prefix, _is_last=is_last_child, _is_root=False
        )

    return line

to_anytree

to_anytree() -> Any

Convert to an anytree.AnyNode tree with parent references.

Creates a parallel anytree representation of this subtree. Each anytree node carries the same attributes (event, type, counts, etc.) and gains parent references, path resolution, and rendering capabilities from the anytree library.

RETURNS DESCRIPTION
Any

An anytree.AnyNode root with the full subtree attached.

Any

Use node.parent, node.path, node.children,

Any

and anytree.RenderTree for navigation and display.

Example
from anytree import RenderTree, findall

at = root.to_anytree()
print(RenderTree(at))

# Parent references
purchase = findall(at, filter_=lambda n: n.event == "Purchase")[0]
purchase.parent.event  # "Search"
[n.event for n in purchase.path]  # ["Login", "Search", "Purchase"]
Source code in src/mixpanel_data/types.py
def to_anytree(self) -> Any:
    """Convert to an ``anytree.AnyNode`` tree with parent references.

    Creates a parallel anytree representation of this subtree. Each
    anytree node carries the same attributes (event, type, counts,
    etc.) and gains parent references, path resolution, and rendering
    capabilities from the anytree library.

    Returns:
        An ``anytree.AnyNode`` root with the full subtree attached.
        Use ``node.parent``, ``node.path``, ``node.children``,
        and ``anytree.RenderTree`` for navigation and display.

    Example:
        ```python
        from anytree import RenderTree, findall

        at = root.to_anytree()
        print(RenderTree(at))

        # Parent references
        purchase = findall(at, filter_=lambda n: n.event == "Purchase")[0]
        purchase.parent.event  # "Search"
        [n.event for n in purchase.path]  # ["Login", "Search", "Purchase"]
        ```
    """
    return self._build_anytree_node(parent=None)

mixpanel_data.FlowQueryResult dataclass

FlowQueryResult(
    computed_at: str,
    steps: list[dict[str, Any]] = list(),
    flows: list[dict[str, Any]] = list(),
    breakdowns: list[dict[str, Any]] = list(),
    overall_conversion_rate: float = 0.0,
    params: dict[str, Any] = dict(),
    meta: dict[str, Any] = dict(),
    mode: Literal["sankey", "paths", "tree"] = "sankey",
    trees: list[FlowTreeNode] = list(),
    *,
    _df_cache: DataFrame | None = None,
    _nodes_df_cache: DataFrame | None = None,
    _edges_df_cache: DataFrame | None = None,
    _graph_cache: DiGraph[str] | None = None,
    _trees_df_cache: DataFrame | None = None,
    _anytree_cache: list[object] | None = None,
)

Bases: ResultWithDataFrame

Result of an ad-hoc flow query.

Holds the raw flow analysis data returned by the Mixpanel API, including step nodes, flow edges, breakdowns, and overall conversion.

ATTRIBUTE DESCRIPTION
computed_at

ISO-8601 timestamp when the query was computed.

TYPE: str

steps

List of step-node dicts from the API response.

TYPE: list[dict[str, Any]]

flows

List of flow-edge dicts describing transitions between steps.

TYPE: list[dict[str, Any]]

breakdowns

List of breakdown dicts when a breakdown property is used.

TYPE: list[dict[str, Any]]

overall_conversion_rate

Overall conversion rate across the flow (0.0 to 1.0).

TYPE: float

params

The query parameters that produced this result.

TYPE: dict[str, Any]

meta

API metadata (sampling factor, request timing, etc.).

TYPE: dict[str, Any]

mode

The flow visualization mode — "sankey" for Sankey diagrams, "paths" for top-paths analysis, or "tree" for prefix tree analysis.

TYPE: Literal['sankey', 'paths', 'tree']

Example
result = FlowQueryResult(
    computed_at="2025-01-15T10:00:00",
    steps=[{"event": "Login", "count": 100}],
    flows=[{"path": ["Login", "Purchase"], "count": 30}],
    overall_conversion_rate=0.3,
)
result.to_dict()
# {"computed_at": "2025-01-15T10:00:00", ...}

steps class-attribute instance-attribute

steps: list[dict[str, Any]] = field(default_factory=list)

Step-node dicts. Each conforms to :class:FlowStepNode.

flows class-attribute instance-attribute

flows: list[dict[str, Any]] = field(default_factory=list)

Flow-edge dicts. Each conforms to :class:FlowEdge.

meta class-attribute instance-attribute

meta: dict[str, Any] = field(default_factory=dict)

Response metadata. Conforms to :class:QueryMeta.

nodes_df property

nodes_df: DataFrame

Extract a flat DataFrame of nodes from sankey step data.

Each row represents a single node in the flow graph, with columns for step index, event name, node type, count, anchor type, custom event flag, and conversion rate change.

The totalCount field in the API response is a string and is parsed to int here.

RETURNS DESCRIPTION
DataFrame

DataFrame with columns: step, event, type,

DataFrame

count, anchor_type, is_custom_event,

DataFrame

conversion_rate_change. Returns an empty DataFrame with

DataFrame

the correct columns when steps is empty.

Example
result = workspace.query_flow(steps=[FlowStep("Login")])
result.nodes_df
#    step   event   type  count anchor_type  ...
# 0     0   Login  ANCHOR   100      NORMAL  ...

edges_df property

edges_df: DataFrame

Extract a flat DataFrame of edges from sankey step data.

Each row represents a directed edge between two nodes in the flow graph, with columns for source step/event, target step/event, edge count, and target node type.

The totalCount field in the API response is a string and is parsed to int here.

RETURNS DESCRIPTION
DataFrame

DataFrame with columns: source_step, source_event,

DataFrame

target_step, target_event, count, target_type.

DataFrame

Returns an empty DataFrame with the correct columns when

DataFrame

steps is empty.

Example
result = workspace.query_flow(steps=[FlowStep("Login")])
result.edges_df
#    source_step source_event  target_step target_event  count target_type
# 0            0        Login            1       Search     80      NORMAL

graph property

graph: DiGraph

Build a networkx directed graph from sankey step data.

Nodes are keyed as "{event}@{step}" to distinguish the same event appearing at different steps (e.g. "Login@0" vs "Login@2"). Each node carries step, event, type, count, and anchor_type attributes. Each edge carries count and type attributes.

The graph is lazily constructed on first access and cached for subsequent calls.

RETURNS DESCRIPTION
DiGraph

A networkx.DiGraph representing the flow. Returns an

DiGraph

empty graph when steps is empty.

Example
result = workspace.query_flow(steps=[FlowStep("Login")])
G = result.graph
G.nodes["Login@0"]["count"]
# 100

df property

df: DataFrame

Mode-aware DataFrame from flow data.

For sankey mode, returns the same DataFrame as nodes_df (one row per node with step, event, type, count, etc.).

For paths mode, returns a tabular DataFrame with one row per step in each flow path, including path_index, step, event, type, and count columns.

RETURNS DESCRIPTION
DataFrame

DataFrame built from nodes (sankey) or flow paths (paths).

DataFrame

Returns an empty DataFrame if no data is available.

Example
result = workspace.query_flow(
    steps=[FlowStep("Login")], mode="sankey"
)
result.df.columns
# Index(['step', 'event', 'type', 'count', ...])

anytree property

anytree: list[Any]

Lazily-cached list of anytree.AnyNode roots from tree data.

Each FlowTreeNode in trees is converted to an anytree node tree via to_anytree(), enabling parent references, path resolution, and RenderTree display.

RETURNS DESCRIPTION
list[Any]

List of anytree.AnyNode root nodes. Empty list when

list[Any]

trees is empty.

Example
result = ws.query_flow("Login", mode="tree")
for root in result.anytree:
    from anytree import RenderTree
    print(RenderTree(root))

top_transitions

top_transitions(n: int = 10) -> list[tuple[str, str, int]]

Return the N highest-traffic transitions between events.

Uses the edges DataFrame to find the most common transitions, sorted by count descending.

PARAMETER DESCRIPTION
n

Maximum number of transitions to return. Default: 10.

TYPE: int DEFAULT: 10

RETURNS DESCRIPTION
list[tuple[str, str, int]]

List of (source_node, target_node, count) tuples sorted

list[tuple[str, str, int]]

by count descending, where each node is formatted as

list[tuple[str, str, int]]

"{event}@{step}" (e.g. "Login@0"). Returns empty

list[tuple[str, str, int]]

list if no edges exist.

Example
result = ws.query_flow("Login", forward=3)
for src, tgt, count in result.top_transitions(n=5):
    print(f"{src} -> {tgt}: {count}")
# Login@0 -> Search@1: 150
Source code in src/mixpanel_data/types.py
def top_transitions(self, n: int = 10) -> list[tuple[str, str, int]]:
    """Return the N highest-traffic transitions between events.

    Uses the edges DataFrame to find the most common transitions,
    sorted by count descending.

    Args:
        n: Maximum number of transitions to return. Default: 10.

    Returns:
        List of (source_node, target_node, count) tuples sorted
        by count descending, where each node is formatted as
        ``"{event}@{step}"`` (e.g. ``"Login@0"``). Returns empty
        list if no edges exist.

    Example:
        ```python
        result = ws.query_flow("Login", forward=3)
        for src, tgt, count in result.top_transitions(n=5):
            print(f"{src} -> {tgt}: {count}")
        # Login@0 -> Search@1: 150
        ```
    """
    edf = self.edges_df
    if edf.empty:
        return []
    sorted_df = edf.sort_values("count", ascending=False).head(n)
    return [
        (f"{se}@{ss}", f"{te}@{ts}", int(c))
        for se, ss, te, ts, c in zip(
            sorted_df["source_event"],
            sorted_df["source_step"],
            sorted_df["target_event"],
            sorted_df["target_step"],
            sorted_df["count"],
            strict=True,
        )
    ]

drop_off_summary

drop_off_summary() -> dict[str, Any]

Per-step drop-off counts and rates.

Analyzes each step to identify drop-off nodes (type == "DROPOFF") and calculates the drop-off rate relative to total traffic at that step.

RETURNS DESCRIPTION
dict[str, Any]

Dict mapping step keys (e.g., "step_0") to dicts with:

dict[str, Any]
  • total: Total count at that step
dict[str, Any]
  • dropoff: Count of users who dropped off
dict[str, Any]
  • rate: Drop-off rate (0.0 to 1.0)
dict[str, Any]

Returns empty dict if no steps exist.

Example
result = ws.query_flow("Login", forward=3)
for step, info in result.drop_off_summary().items():
    print(f"{step}: {info['rate']:.0%} drop-off")
Source code in src/mixpanel_data/types.py
def drop_off_summary(self) -> dict[str, Any]:
    """Per-step drop-off counts and rates.

    Analyzes each step to identify drop-off nodes (type == "DROPOFF")
    and calculates the drop-off rate relative to total traffic at
    that step.

    Returns:
        Dict mapping step keys (e.g., "step_0") to dicts with:
        - total: Total count at that step
        - dropoff: Count of users who dropped off
        - rate: Drop-off rate (0.0 to 1.0)
        Returns empty dict if no steps exist.

    Example:
        ```python
        result = ws.query_flow("Login", forward=3)
        for step, info in result.drop_off_summary().items():
            print(f"{step}: {info['rate']:.0%} drop-off")
        ```
    """
    if not self.steps:
        return {}
    summary: dict[str, Any] = {}
    for step_idx, step in enumerate(self.steps):
        total = 0
        dropoff = 0
        for node in step.get("nodes", []):
            count = _safe_int(node.get("totalCount", "0"))
            node_type = node.get("type", "")
            total += count
            # Count dropoff edges only from non-DROPOFF nodes.
            # DROPOFF nodes represent prior-step dropoffs carried
            # forward; their self-edges would double-count.
            if node_type != "DROPOFF":
                for edge in node.get("edges", []):
                    if edge.get("type") == "DROPOFF":
                        dropoff += _safe_int(edge.get("totalCount", "0"))
        rate = dropoff / total if total > 0 else 0.0
        summary[f"step_{step_idx}"] = {
            "total": total,
            "dropoff": dropoff,
            "rate": rate,
        }
    return summary

to_dict

to_dict() -> dict[str, Any]

Serialize the flow query result for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all FlowQueryResult fields suitable for

dict[str, Any]

JSON serialization.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize the flow query result for JSON output.

    Returns:
        Dictionary with all FlowQueryResult fields suitable for
        JSON serialization.
    """
    return {
        "computed_at": self.computed_at,
        "steps": self.steps,
        "flows": self.flows,
        "breakdowns": self.breakdowns,
        "overall_conversion_rate": self.overall_conversion_rate,
        "params": self.params,
        "meta": self.meta,
        "mode": self.mode,
        "trees": [t.to_dict() for t in self.trees],
    }

Legacy Query Results

mixpanel_data.SegmentationResult dataclass

SegmentationResult(
    event: str,
    from_date: str,
    to_date: str,
    unit: Literal["day", "week", "month"],
    segment_property: str | None,
    total: int,
    series: dict[str, dict[str, int]] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Result of a segmentation query.

Contains time-series data for an event, optionally segmented by a property.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

event instance-attribute

event: str

Queried event name.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

unit instance-attribute

unit: Literal['day', 'week', 'month']

Time unit for aggregation.

segment_property instance-attribute

segment_property: str | None

Property used for segmentation (None if total only).

total instance-attribute

total: int

Total count across all segments and time periods.

series class-attribute instance-attribute

series: dict[str, dict[str, int]] = field(default_factory=dict)

Time series data by segment.

Structure: {segment_name: {date_string: count}} Example: {"US": {"2024-01-01": 150, "2024-01-02": 200}, "EU": {...}} For unsegmented queries, segment_name is "total".

df property

df: DataFrame

Convert to DataFrame with columns: date, segment, count.

For unsegmented queries, segment column is 'total'.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "unit": self.unit,
        "segment_property": self.segment_property,
        "total": self.total,
        "series": self.series,
    }

mixpanel_data.FunnelResult dataclass

FunnelResult(
    funnel_id: int,
    funnel_name: str,
    from_date: str,
    to_date: str,
    conversion_rate: float,
    steps: list[FunnelResultStep] = list(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Result of a funnel query.

Contains step-by-step conversion data for a funnel.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

funnel_id instance-attribute

funnel_id: int

Funnel identifier.

funnel_name instance-attribute

funnel_name: str

Funnel display name.

from_date instance-attribute

from_date: str

Query start date.

to_date instance-attribute

to_date: str

Query end date.

conversion_rate instance-attribute

conversion_rate: float

Overall conversion rate (0.0 to 1.0).

steps class-attribute instance-attribute

steps: list[FunnelResultStep] = field(default_factory=list)

Step-by-step breakdown.

df property

df: DataFrame

Convert to DataFrame with columns: step, event, count, conversion_rate.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "funnel_id": self.funnel_id,
        "funnel_name": self.funnel_name,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "conversion_rate": self.conversion_rate,
        "steps": [step.to_dict() for step in self.steps],
    }

mixpanel_data.FunnelResultStep dataclass

FunnelResultStep(event: str, count: int, conversion_rate: float)

Single step result in a legacy funnel query response.

event instance-attribute

event: str

Event name for this step.

count instance-attribute

count: int

Number of users at this step.

conversion_rate instance-attribute

conversion_rate: float

Conversion rate from previous step (0.0 to 1.0).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "count": self.count,
        "conversion_rate": self.conversion_rate,
    }

mixpanel_data.RetentionResult dataclass

RetentionResult(
    born_event: str,
    return_event: str,
    from_date: str,
    to_date: str,
    unit: Literal["day", "week", "month"],
    cohorts: list[CohortInfo] = list(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Result of a retention query.

Contains cohort-based retention data.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

born_event instance-attribute

born_event: str

Event that defines cohort membership.

return_event instance-attribute

return_event: str

Event that defines return.

from_date instance-attribute

from_date: str

Query start date.

to_date instance-attribute

to_date: str

Query end date.

unit instance-attribute

unit: Literal['day', 'week', 'month']

Time unit for retention periods.

cohorts class-attribute instance-attribute

cohorts: list[CohortInfo] = field(default_factory=list)

Cohort retention data.

df property

df: DataFrame

Convert to DataFrame with columns: cohort_date, cohort_size, period_N.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "born_event": self.born_event,
        "return_event": self.return_event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "unit": self.unit,
        "cohorts": [cohort.to_dict() for cohort in self.cohorts],
    }

mixpanel_data.CohortInfo dataclass

CohortInfo(date: str, size: int, retention: list[float] = list())

Retention data for a single cohort.

date instance-attribute

date: str

Cohort date (when users were 'born').

size instance-attribute

size: int

Number of users in cohort.

retention class-attribute instance-attribute

retention: list[float] = field(default_factory=list)

Retention percentages by period (0.0 to 1.0).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "date": self.date,
        "size": self.size,
        "retention": self.retention,
    }

mixpanel_data.JQLResult dataclass

JQLResult(_raw: list[Any] = list(), *, _df_cache: DataFrame | None = None)

Bases: ResultWithDataFrame

Result of a JQL query.

JQL (JavaScript Query Language) allows custom queries against Mixpanel data.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

The df property intelligently detects JQL result patterns (groupBy, percentiles, simple dicts) and converts them to clean tabular format.

raw property

raw: list[Any]

Raw result data from JQL execution.

df property

df: DataFrame

Convert result to DataFrame with intelligent structure detection.

The conversion strategy depends on the detected JQL result pattern:

groupBy results (detected by {key: [...], value: X} structure): - Keys expanded to columns: key_0, key_1, key_2, ... - Single value: "value" column - Multiple reducers (value array): value_0, value_1, value_2, ... - Additional fields (from .map()): preserved as-is - Example: {"key": ["US"], "value": 100, "name": "USA"} -> columns: key_0, value, name

Nested percentile results ([[{percentile: X, value: Y}, ...]]): - Outer list unwrapped, inner dicts converted directly

Simple list of dicts (already well-structured): - Converted directly to DataFrame preserving all fields

Fallback for other structures (scalars, mixed types, incompatible dicts): - Safely wrapped in single "value" column to prevent data loss - Used when structure doesn't match known patterns

RAISES DESCRIPTION
ValueError

If groupBy structure has inconsistent value types across rows (some scalar, some array) which indicates malformed query results.

RETURNS DESCRIPTION
DataFrame

DataFrame representation, cached after first access.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "raw": self._raw,
        "row_count": len(self._raw),
    }

Discovery Types

mixpanel_data.FunnelInfo dataclass

FunnelInfo(funnel_id: int, name: str)

A saved funnel definition.

Represents a funnel saved in Mixpanel that can be queried using the funnel() method.

funnel_id instance-attribute

funnel_id: int

Unique identifier for funnel queries.

name instance-attribute

name: str

Human-readable funnel name.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "funnel_id": self.funnel_id,
        "name": self.name,
    }

mixpanel_data.SavedCohort dataclass

SavedCohort(
    id: int,
    name: str,
    count: int,
    description: str,
    created: str,
    is_visible: bool,
)

A saved cohort definition.

Represents a user cohort saved in Mixpanel for profile filtering.

id instance-attribute

id: int

Unique identifier for profile filtering.

name instance-attribute

name: str

Human-readable cohort name.

count instance-attribute

count: int

Current number of users in cohort.

description instance-attribute

description: str

Optional description (may be empty string).

created instance-attribute

created: str

Creation timestamp (YYYY-MM-DD HH:mm:ss).

is_visible instance-attribute

is_visible: bool

Whether cohort is visible in Mixpanel UI.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "id": self.id,
        "name": self.name,
        "count": self.count,
        "description": self.description,
        "created": self.created,
        "is_visible": self.is_visible,
    }

mixpanel_data.TopEvent dataclass

TopEvent(event: str, count: int, percent_change: float)

Today's event activity data.

Represents an event's current activity including count and trend.

ATTRIBUTE DESCRIPTION
event

Event name.

TYPE: str

count

Today's event count.

TYPE: int

percent_change

Change vs yesterday (-1.0 to +infinity).

TYPE: float

Example
top = ws.top_events(limit=10)
for t in top:
    print(f"{t.event}: {t.count:,} ({t.percent_change:+.1%})")

event instance-attribute

event: str

Event name.

count instance-attribute

count: int

Today's event count.

percent_change instance-attribute

percent_change: float

Change vs yesterday (-1.0 to +infinity).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "count": self.count,
        "percent_change": self.percent_change,
    }

Subproperty Discovery Types

Types for Workspace.subproperties() — schema discovery for list-of-object event properties. See Subproperties for usage.

mixpanel_data.SubPropertyInfo dataclass

SubPropertyInfo(
    name: str,
    type: CustomPropertyType,
    sample_values: tuple[str | int | float | bool, ...],
)

Discovered subproperty of a list-of-object event property.

Returned by :meth:Workspace.subproperties to describe the inner structure of properties whose values are lists of objects (e.g. cart is a list of {"Brand": str, "Category": str, "Price": int} items). Use the name and type to construct :meth:GroupBy.list_item and :meth:Filter.list_contains calls.

ATTRIBUTE DESCRIPTION
name

Subproperty name as it appears inside each object.

TYPE: str

type

Inferred data type. Mixed sub-value types collapse to "string" (a UserWarning is emitted at discovery time).

TYPE: CustomPropertyType

sample_values

Up to 5 distinct sample values observed across the sampled rows.

TYPE: tuple[str | int | float | bool, ...]

Example
for sp in ws.subproperties("cart", event="Cart Viewed"):
    print(sp.name, sp.type, sp.sample_values)
# Brand string ('nike', 'puma', 'h&m')
# Category string ('hats', 'jeans', 'shoes')
# Item ID number (35317, 35318)
# Price number (51, 87, 102)

name instance-attribute

name: str

Subproperty name as it appears inside each object.

type instance-attribute

type: CustomPropertyType

Inferred data type, suitable for GroupBy.list_item(sub_type=...).

sample_values instance-attribute

sample_values: tuple[str | int | float | bool, ...]

Up to 5 distinct sample values observed across the sampled rows.

to_dict

to_dict() -> dict[str, Any]

Serialize the subproperty info as a plain dict for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dict with name (str), type (str), and

dict[str, Any]

sample_values (list of scalars) keys, suitable for

dict[str, Any]

JSON serialization.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize the subproperty info as a plain dict for JSON output.

    Returns:
        Dict with ``name`` (str), ``type`` (str), and
        ``sample_values`` (list of scalars) keys, suitable for
        JSON serialization.
    """
    return {
        "name": self.name,
        "type": self.type,
        "sample_values": list(self.sample_values),
    }

Lexicon Types

mixpanel_data.LexiconSchema dataclass

LexiconSchema(entity_type: str, name: str, schema_json: LexiconDefinition)

Complete schema definition from Mixpanel Lexicon.

Represents a documented event or profile property definition from the Mixpanel data dictionary.

entity_type instance-attribute

entity_type: str

Type of entity (e.g., 'event', 'profile', 'custom_event', 'group', etc.).

name instance-attribute

name: str

Name of the event or profile property.

schema_json instance-attribute

schema_json: LexiconDefinition

Full schema definition.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with entity_type, name, and schema_json.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with entity_type, name, and schema_json.
    """
    return {
        "entity_type": self.entity_type,
        "name": self.name,
        "schema_json": self.schema_json.to_dict(),
    }

mixpanel_data.LexiconDefinition dataclass

LexiconDefinition(
    description: str | None,
    properties: dict[str, LexiconProperty],
    metadata: LexiconMetadata | None,
)

Full schema definition for an event or profile property in Lexicon.

Contains the structural definition including description, properties, and platform-specific metadata.

description instance-attribute

description: str | None

Human-readable description of the entity.

properties instance-attribute

properties: dict[str, LexiconProperty]

Property definitions keyed by property name.

metadata instance-attribute

metadata: LexiconMetadata | None

Optional Mixpanel-specific metadata for the entity.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with properties, and optionally description and metadata.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with properties, and optionally description and metadata.
    """
    result: dict[str, Any] = {
        "properties": {k: v.to_dict() for k, v in self.properties.items()},
    }
    if self.description is not None:
        result["description"] = self.description
    if self.metadata is not None:
        result["metadata"] = self.metadata.to_dict()
    return result

mixpanel_data.LexiconProperty dataclass

LexiconProperty(
    type: str, description: str | None, metadata: LexiconMetadata | None
)

Schema definition for a single property in a Lexicon schema.

Describes the type and metadata for an event or profile property.

type instance-attribute

type: str

JSON Schema type (string, number, boolean, array, object, integer, null).

description instance-attribute

description: str | None

Human-readable description of the property.

metadata instance-attribute

metadata: LexiconMetadata | None

Optional Mixpanel-specific metadata.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with type, and optionally description and metadata.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with type, and optionally description and metadata.
    """
    result: dict[str, Any] = {"type": self.type}
    if self.description is not None:
        result["description"] = self.description
    if self.metadata is not None:
        result["metadata"] = self.metadata.to_dict()
    return result

mixpanel_data.LexiconMetadata dataclass

LexiconMetadata(
    source: str | None,
    display_name: str | None,
    tags: list[str],
    hidden: bool,
    dropped: bool,
    contacts: list[str],
    team_contacts: list[str],
)

Mixpanel-specific metadata for Lexicon schemas and properties.

Contains platform-specific information about how schemas and properties are displayed and organized in the Mixpanel UI.

source instance-attribute

source: str | None

Origin of the schema definition (e.g., 'api', 'csv', 'ui').

display_name instance-attribute

display_name: str | None

Human-readable display name in Mixpanel UI.

tags instance-attribute

tags: list[str]

Categorization tags for organization.

hidden instance-attribute

hidden: bool

Whether hidden from Mixpanel UI.

dropped instance-attribute

dropped: bool

Whether data is dropped/ignored.

contacts instance-attribute

contacts: list[str]

Owner email addresses.

team_contacts instance-attribute

team_contacts: list[str]

Team ownership labels.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all metadata fields.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all metadata fields.
    """
    return {
        "source": self.source,
        "display_name": self.display_name,
        "tags": self.tags,
        "hidden": self.hidden,
        "dropped": self.dropped,
        "contacts": self.contacts,
        "team_contacts": self.team_contacts,
    }

Event Analytics Results

mixpanel_data.EventCountsResult dataclass

EventCountsResult(
    events: list[str],
    from_date: str,
    to_date: str,
    unit: Literal["day", "week", "month"],
    type: Literal["general", "unique", "average"],
    series: dict[str, dict[str, int]],
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Time-series event count data.

Contains aggregate counts for multiple events over time with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

events instance-attribute

events: list[str]

Queried event names.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

unit instance-attribute

unit: Literal['day', 'week', 'month']

Time unit for aggregation.

type instance-attribute

type: Literal['general', 'unique', 'average']

Counting method used.

series instance-attribute

series: dict[str, dict[str, int]]

Time series data: {event_name: {date: count}}.

df property

df: DataFrame

Convert to DataFrame with columns: date, event, count.

Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "events": self.events,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "unit": self.unit,
        "type": self.type,
        "series": self.series,
    }

mixpanel_data.PropertyCountsResult dataclass

PropertyCountsResult(
    event: str,
    property_name: str,
    from_date: str,
    to_date: str,
    unit: Literal["day", "week", "month"],
    type: Literal["general", "unique", "average"],
    series: dict[str, dict[str, int]],
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Time-series property value distribution data.

Contains aggregate counts by property values over time with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

event instance-attribute

event: str

Queried event name.

property_name instance-attribute

property_name: str

Property used for segmentation.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

unit instance-attribute

unit: Literal['day', 'week', 'month']

Time unit for aggregation.

type instance-attribute

type: Literal['general', 'unique', 'average']

Counting method used.

series instance-attribute

series: dict[str, dict[str, int]]

Time series data by property value.

Structure: {property_value: {date: count}} Example: {"US": {"2024-01-01": 150, "2024-01-02": 200}, "EU": {...}}

df property

df: DataFrame

Convert to DataFrame with columns: date, value, count.

Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "property_name": self.property_name,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "unit": self.unit,
        "type": self.type,
        "series": self.series,
    }

Advanced Query Results

mixpanel_data.UserEvent dataclass

UserEvent(event: str, time: datetime, properties: dict[str, Any] = dict())

Single event in a user's activity feed.

Represents one event from a user's event history with timestamp and all associated properties.

event instance-attribute

event: str

Event name.

time instance-attribute

time: datetime

Event timestamp (UTC).

properties class-attribute instance-attribute

properties: dict[str, Any] = field(default_factory=dict)

All event properties including system properties.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "time": self.time.isoformat(),
        "properties": self.properties,
    }

mixpanel_data.ActivityFeedResult dataclass

ActivityFeedResult(
    distinct_ids: list[str],
    from_date: str | None,
    to_date: str | None,
    events: list[UserEvent] = list(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Collection of user events from activity feed query.

Contains chronological event history for one or more users with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

distinct_ids instance-attribute

distinct_ids: list[str]

Queried user identifiers.

from_date instance-attribute

from_date: str | None

Start date filter (YYYY-MM-DD), None if not specified.

to_date instance-attribute

to_date: str | None

End date filter (YYYY-MM-DD), None if not specified.

events class-attribute instance-attribute

events: list[UserEvent] = field(default_factory=list)

Event history (chronological order).

df property

df: DataFrame

Convert to DataFrame with columns: event, time, distinct_id, + properties.

Flattens event properties into individual columns. Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "distinct_ids": self.distinct_ids,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "event_count": len(self.events),
        "events": [e.to_dict() for e in self.events],
    }

mixpanel_data.FrequencyResult dataclass

FrequencyResult(
    event: str | None,
    from_date: str,
    to_date: str,
    unit: Literal["day", "week", "month"],
    addiction_unit: Literal["hour", "day"],
    data: dict[str, list[int]] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Event frequency distribution (addiction analysis).

Contains frequency arrays showing how many users performed events in N time periods, with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

event instance-attribute

event: str | None

Filtered event name (None = all events).

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

unit instance-attribute

unit: Literal['day', 'week', 'month']

Overall time period.

addiction_unit instance-attribute

addiction_unit: Literal['hour', 'day']

Measurement granularity.

data class-attribute instance-attribute

data: dict[str, list[int]] = field(default_factory=dict)

Frequency arrays by date.

Structure: {date: [count_1, count_2, ...]} Example: {"2024-01-01": [100, 50, 25, 10]}

Each array shows user counts by frequency: - Index 0: users active exactly 1 time - Index 1: users active exactly 2 times - Index N: users active exactly N+1 times

df property

df: DataFrame

Convert to DataFrame with columns: date, period_1, period_2, ...

Each period_N column shows users active in at least N time periods. Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "unit": self.unit,
        "addiction_unit": self.addiction_unit,
        "data": self.data,
    }

mixpanel_data.NumericBucketResult dataclass

NumericBucketResult(
    event: str,
    from_date: str,
    to_date: str,
    property_expr: str,
    unit: Literal["hour", "day"],
    series: dict[str, dict[str, int]] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Events segmented into numeric property ranges.

Contains time-series data bucketed by automatically determined numeric ranges, with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

event instance-attribute

event: str

Queried event name.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

property_expr instance-attribute

property_expr: str

The 'on' expression used for bucketing.

unit instance-attribute

unit: Literal['hour', 'day']

Time aggregation unit.

series class-attribute instance-attribute

series: dict[str, dict[str, int]] = field(default_factory=dict)

Bucket data: {range_string: {date: count}}.

df property

df: DataFrame

Convert to DataFrame with columns: date, bucket, count.

Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "property_expr": self.property_expr,
        "unit": self.unit,
        "series": self.series,
    }

mixpanel_data.NumericSumResult dataclass

NumericSumResult(
    event: str,
    from_date: str,
    to_date: str,
    property_expr: str,
    unit: Literal["hour", "day"],
    results: dict[str, float] = dict(),
    computed_at: str | None = None,
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Sum of numeric property values per time unit.

Contains daily or hourly sum totals for a numeric property with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

event instance-attribute

event: str

Queried event name.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

property_expr instance-attribute

property_expr: str

The 'on' expression summed.

unit instance-attribute

unit: Literal['hour', 'day']

Time aggregation unit.

results class-attribute instance-attribute

results: dict[str, float] = field(default_factory=dict)

Sum values: {date: sum}.

computed_at class-attribute instance-attribute

computed_at: str | None = None

Computation timestamp (if provided by API).

df property

df: DataFrame

Convert to DataFrame with columns: date, sum.

Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    result: dict[str, Any] = {
        "event": self.event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "property_expr": self.property_expr,
        "unit": self.unit,
        "results": self.results,
    }
    if self.computed_at is not None:
        result["computed_at"] = self.computed_at
    return result

mixpanel_data.NumericAverageResult dataclass

NumericAverageResult(
    event: str,
    from_date: str,
    to_date: str,
    property_expr: str,
    unit: Literal["hour", "day"],
    results: dict[str, float] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Average of numeric property values per time unit.

Contains daily or hourly average values for a numeric property with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

event instance-attribute

event: str

Queried event name.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

property_expr instance-attribute

property_expr: str

The 'on' expression averaged.

unit instance-attribute

unit: Literal['hour', 'day']

Time aggregation unit.

results class-attribute instance-attribute

results: dict[str, float] = field(default_factory=dict)

Average values: {date: average}.

df property

df: DataFrame

Convert to DataFrame with columns: date, average.

Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output."""
    return {
        "event": self.event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "property_expr": self.property_expr,
        "unit": self.unit,
        "results": self.results,
    }

Bookmark Types

mixpanel_data.BookmarkInfo dataclass

BookmarkInfo(
    id: int,
    name: str,
    type: BookmarkType,
    project_id: int,
    created: str,
    modified: str,
    workspace_id: int | None = None,
    dashboard_id: int | None = None,
    description: str | None = None,
    creator_id: int | None = None,
    creator_name: str | None = None,
)

Metadata for a saved report (bookmark) from the Mixpanel Bookmarks API.

Represents a saved Insights, Funnel, Retention, or Flows report that can be queried using query_saved_report() or query_saved_flows().

ATTRIBUTE DESCRIPTION
id

Unique bookmark identifier.

TYPE: int

name

User-defined report name.

TYPE: str

type

Report type (insights, funnels, retention, flows, launch-analysis).

TYPE: BookmarkType

project_id

Parent Mixpanel project ID.

TYPE: int

created

Creation timestamp (ISO format).

TYPE: str

modified

Last modification timestamp (ISO format).

TYPE: str

workspace_id

Optional workspace ID if scoped to a workspace.

TYPE: int | None

dashboard_id

Optional parent dashboard ID if linked to a dashboard.

TYPE: int | None

description

Optional user-provided description.

TYPE: str | None

creator_id

Optional creator's user ID.

TYPE: int | None

creator_name

Optional creator's display name.

TYPE: str | None

id instance-attribute

id: int

Unique bookmark identifier.

name instance-attribute

name: str

User-defined report name.

type instance-attribute

type: BookmarkType

Report type.

project_id instance-attribute

project_id: int

Parent Mixpanel project ID.

created instance-attribute

created: str

Creation timestamp (ISO format).

modified instance-attribute

modified: str

Last modification timestamp (ISO format).

workspace_id class-attribute instance-attribute

workspace_id: int | None = None

Workspace ID if scoped to a workspace.

dashboard_id class-attribute instance-attribute

dashboard_id: int | None = None

Parent dashboard ID if linked to a dashboard.

description class-attribute instance-attribute

description: str | None = None

User-provided description.

creator_id class-attribute instance-attribute

creator_id: int | None = None

Creator's user ID.

creator_name class-attribute instance-attribute

creator_name: str | None = None

Creator's display name.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all bookmark metadata fields.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all bookmark metadata fields.
    """
    result: dict[str, Any] = {
        "id": self.id,
        "name": self.name,
        "type": self.type,
        "project_id": self.project_id,
        "created": self.created,
        "modified": self.modified,
    }
    if self.workspace_id is not None:
        result["workspace_id"] = self.workspace_id
    if self.dashboard_id is not None:
        result["dashboard_id"] = self.dashboard_id
    if self.description is not None:
        result["description"] = self.description
    if self.creator_id is not None:
        result["creator_id"] = self.creator_id
    if self.creator_name is not None:
        result["creator_name"] = self.creator_name
    return result

mixpanel_data.SavedReportResult dataclass

SavedReportResult(
    bookmark_id: int,
    computed_at: str,
    from_date: str,
    to_date: str,
    headers: list[str] = list(),
    series: dict[str, Any] = dict(),
    _df_cache: DataFrame | None = None,
)

Data from a saved report (Insights, Retention, or Funnel).

Contains data from a pre-configured saved report with automatic report type detection and lazy DataFrame conversion support.

The report_type property automatically detects the report type based on headers: "$retention" indicates retention, "$funnel" indicates funnel, otherwise it's an insights report.

ATTRIBUTE DESCRIPTION
bookmark_id

Saved report identifier.

TYPE: int

computed_at

When report was computed (ISO format).

TYPE: str

from_date

Report start date.

TYPE: str

to_date

Report end date.

TYPE: str

headers

Report column headers (used for type detection).

TYPE: list[str]

series

Report data (structure varies by report type).

TYPE: dict[str, Any]

bookmark_id instance-attribute

bookmark_id: int

Saved report identifier.

computed_at instance-attribute

computed_at: str

When report was computed (ISO format).

from_date instance-attribute

from_date: str

Report start date.

to_date instance-attribute

to_date: str

Report end date.

headers class-attribute instance-attribute

headers: list[str] = field(default_factory=list)

Report column headers (used for type detection).

series class-attribute instance-attribute

series: dict[str, Any] = field(default_factory=dict)

Report data (structure varies by report type).

For Insights reports: {event_name: {date: count}} For Retention reports: {series_name: {date: {segment: {first, counts, rates}}}} For Funnel reports: {count: {...}, overall_conv_ratio: {...}, ...}

report_type property

report_type: SavedReportType

Detect the report type from headers.

RETURNS DESCRIPTION
SavedReportType

'retention' if headers contain '$retention',

SavedReportType

'funnel' if headers contain '$funnel',

SavedReportType

'flows' if headers contain '$flows',

SavedReportType

'insights' otherwise.

df property

df: DataFrame

Convert to DataFrame.

For Insights reports: columns are date, event, count. For Retention/Funnel reports: flattens the nested structure.

Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all report fields including detected report_type.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all report fields including detected report_type.
    """
    return {
        "bookmark_id": self.bookmark_id,
        "computed_at": self.computed_at,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "headers": self.headers,
        "series": self.series,
        "report_type": self.report_type,
    }

mixpanel_data.FlowsResult dataclass

FlowsResult(
    bookmark_id: int,
    computed_at: str,
    steps: list[dict[str, Any]] = list(),
    breakdowns: list[dict[str, Any]] = list(),
    overall_conversion_rate: float = 0.0,
    metadata: dict[str, Any] = dict(),
    *,
    _df_cache: DataFrame | None = None,
)

Bases: ResultWithDataFrame

Data from a saved Flows report.

Contains user path/navigation data from a pre-configured Flows report with lazy DataFrame conversion support.

Inherits from ResultWithDataFrame to provide: - Lazy DataFrame caching via _df_cache field - Normalized table output via to_table_dict() method

ATTRIBUTE DESCRIPTION
bookmark_id

Saved report identifier.

TYPE: int

computed_at

When report was computed (ISO format).

TYPE: str

steps

Flow step data with event sequences and counts.

TYPE: list[dict[str, Any]]

breakdowns

Path breakdown data showing user flow distribution.

TYPE: list[dict[str, Any]]

overall_conversion_rate

End-to-end conversion rate (0.0 to 1.0).

TYPE: float

metadata

Additional API metadata from the response.

TYPE: dict[str, Any]

bookmark_id instance-attribute

bookmark_id: int

Saved report identifier.

computed_at instance-attribute

computed_at: str

When report was computed (ISO format).

steps class-attribute instance-attribute

steps: list[dict[str, Any]] = field(default_factory=list)

Flow step data with event sequences and counts.

breakdowns class-attribute instance-attribute

breakdowns: list[dict[str, Any]] = field(default_factory=list)

Path breakdown data showing user flow distribution.

overall_conversion_rate class-attribute instance-attribute

overall_conversion_rate: float = 0.0

End-to-end conversion rate (0.0 to 1.0).

metadata class-attribute instance-attribute

metadata: dict[str, Any] = field(default_factory=dict)

Additional API metadata from the response.

df property

df: DataFrame

Convert steps to DataFrame.

Returns DataFrame with columns derived from step data structure. Conversion is lazy - computed on first access and cached.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all flows report fields.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all flows report fields.
    """
    return {
        "bookmark_id": self.bookmark_id,
        "computed_at": self.computed_at,
        "steps": self.steps,
        "breakdowns": self.breakdowns,
        "overall_conversion_rate": self.overall_conversion_rate,
        "metadata": self.metadata,
    }

JQL Discovery Types

mixpanel_data.PropertyDistributionResult dataclass

PropertyDistributionResult(
    event: str,
    property_name: str,
    from_date: str,
    to_date: str,
    total_count: int,
    values: tuple[PropertyValueCount, ...],
    _df_cache: DataFrame | None = None,
)

Distribution of values for a property from JQL analysis.

Contains the top N values for a property with their counts and percentages, enabling quick understanding of property value distribution without processing all raw events.

ATTRIBUTE DESCRIPTION
event

The event type analyzed.

TYPE: str

property_name

The property name analyzed.

TYPE: str

from_date

Query start date (YYYY-MM-DD).

TYPE: str

to_date

Query end date (YYYY-MM-DD).

TYPE: str

total_count

Total number of events with this property defined.

TYPE: int

values

Top values with counts and percentages.

TYPE: tuple[PropertyValueCount, ...]

event instance-attribute

event: str

Event type analyzed.

property_name instance-attribute

property_name: str

Property name analyzed.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

total_count instance-attribute

total_count: int

Total events with this property defined.

values instance-attribute

values: tuple[PropertyValueCount, ...]

Top values with counts and percentages.

df property

df: DataFrame

Convert to DataFrame with columns: value, count, percentage.

Conversion is lazy - computed on first access and cached.

RETURNS DESCRIPTION
DataFrame

DataFrame with value distribution data.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all distribution data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all distribution data.
    """
    return {
        "event": self.event,
        "property_name": self.property_name,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "total_count": self.total_count,
        "values": [v.to_dict() for v in self.values],
    }

mixpanel_data.PropertyValueCount dataclass

PropertyValueCount(
    value: str | int | float | bool | None, count: int, percentage: float
)

A single value and its count from property distribution analysis.

Represents one row in a property value distribution, showing the value, its occurrence count, and percentage of total.

ATTRIBUTE DESCRIPTION
value

The property value (can be string, number, bool, or None).

TYPE: str | int | float | bool | None

count

Number of occurrences of this value.

TYPE: int

percentage

Percentage of total events (0.0 to 100.0).

TYPE: float

value instance-attribute

value: str | int | float | bool | None

The property value.

count instance-attribute

count: int

Number of occurrences.

percentage instance-attribute

percentage: float

Percentage of total (0.0 to 100.0).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with value, count, and percentage.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with value, count, and percentage.
    """
    return {
        "value": self.value,
        "count": self.count,
        "percentage": self.percentage,
    }

mixpanel_data.NumericPropertySummaryResult dataclass

NumericPropertySummaryResult(
    event: str,
    property_name: str,
    from_date: str,
    to_date: str,
    count: int,
    min: float,
    max: float,
    sum: float,
    avg: float,
    stddev: float,
    percentiles: dict[int, float],
)

Statistical summary of a numeric property from JQL analysis.

Contains min, max, sum, average, standard deviation, and percentiles for a numeric property, enabling understanding of value distributions without processing all raw events.

ATTRIBUTE DESCRIPTION
event

The event type analyzed.

TYPE: str

property_name

The property name analyzed.

TYPE: str

from_date

Query start date (YYYY-MM-DD).

TYPE: str

to_date

Query end date (YYYY-MM-DD).

TYPE: str

count

Number of events with this property defined.

TYPE: int

min

Minimum value.

TYPE: float

max

Maximum value.

TYPE: float

sum

Sum of all values.

TYPE: float

avg

Average value.

TYPE: float

stddev

Standard deviation.

TYPE: float

percentiles

Percentile values keyed by percentile number.

TYPE: dict[int, float]

event instance-attribute

event: str

Event type analyzed.

property_name instance-attribute

property_name: str

Property name analyzed.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

count instance-attribute

count: int

Number of events with this property defined.

min instance-attribute

min: float

Minimum value.

max instance-attribute

max: float

Maximum value.

sum instance-attribute

sum: float

Sum of all values.

avg instance-attribute

avg: float

Average value.

stddev instance-attribute

stddev: float

Standard deviation.

percentiles instance-attribute

percentiles: dict[int, float]

Percentile values keyed by percentile number (e.g., {50: 98.0}).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all numeric summary data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all numeric summary data.
    """
    return {
        "event": self.event,
        "property_name": self.property_name,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "count": self.count,
        "min": self.min,
        "max": self.max,
        "sum": self.sum,
        "avg": self.avg,
        "stddev": self.stddev,
        "percentiles": {str(k): v for k, v in self.percentiles.items()},
    }

mixpanel_data.DailyCountsResult dataclass

DailyCountsResult(
    from_date: str,
    to_date: str,
    events: tuple[str, ...] | None,
    counts: tuple[DailyCount, ...],
    _df_cache: DataFrame | None = None,
)

Time-series event counts by day from JQL analysis.

Contains daily event counts for quick activity trend analysis without complex segmentation setup.

ATTRIBUTE DESCRIPTION
from_date

Query start date (YYYY-MM-DD).

TYPE: str

to_date

Query end date (YYYY-MM-DD).

TYPE: str

events

Event types included (None for all events).

TYPE: tuple[str, ...] | None

counts

Daily counts for each event.

TYPE: tuple[DailyCount, ...]

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

events instance-attribute

events: tuple[str, ...] | None

Event types included (None for all events).

counts instance-attribute

counts: tuple[DailyCount, ...]

Daily counts for each event.

df property

df: DataFrame

Convert to DataFrame with columns: date, event, count.

Conversion is lazy - computed on first access and cached.

RETURNS DESCRIPTION
DataFrame

DataFrame with daily counts data.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all daily counts data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all daily counts data.
    """
    return {
        "from_date": self.from_date,
        "to_date": self.to_date,
        "events": list(self.events) if self.events else None,
        "counts": [c.to_dict() for c in self.counts],
    }

mixpanel_data.DailyCount dataclass

DailyCount(date: str, event: str, count: int)

Event count for a single date from daily counts analysis.

Represents one row in a daily counts result, showing date, event, and count.

ATTRIBUTE DESCRIPTION
date

Date string (YYYY-MM-DD).

TYPE: str

event

Event name.

TYPE: str

count

Number of occurrences on this date.

TYPE: int

date instance-attribute

date: str

Date string (YYYY-MM-DD).

event instance-attribute

event: str

Event name.

count instance-attribute

count: int

Number of occurrences.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with date, event, and count.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with date, event, and count.
    """
    return {
        "date": self.date,
        "event": self.event,
        "count": self.count,
    }

mixpanel_data.EngagementDistributionResult dataclass

EngagementDistributionResult(
    from_date: str,
    to_date: str,
    events: tuple[str, ...] | None,
    total_users: int,
    buckets: tuple[EngagementBucket, ...],
    _df_cache: DataFrame | None = None,
)

User engagement distribution from JQL analysis.

Shows how many users performed N events, helping understand user engagement patterns without processing all raw events.

ATTRIBUTE DESCRIPTION
from_date

Query start date (YYYY-MM-DD).

TYPE: str

to_date

Query end date (YYYY-MM-DD).

TYPE: str

events

Event types included (None for all events).

TYPE: tuple[str, ...] | None

total_users

Total number of distinct users.

TYPE: int

buckets

Engagement buckets with user counts.

TYPE: tuple[EngagementBucket, ...]

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

events instance-attribute

events: tuple[str, ...] | None

Event types included (None for all events).

total_users instance-attribute

total_users: int

Total number of distinct users.

buckets instance-attribute

buckets: tuple[EngagementBucket, ...]

Engagement buckets with user counts.

df property

df: DataFrame

Convert to DataFrame with engagement bucket columns.

Conversion is lazy - computed on first access and cached.

RETURNS DESCRIPTION
DataFrame

DataFrame with engagement distribution data.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all engagement distribution data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all engagement distribution data.
    """
    return {
        "from_date": self.from_date,
        "to_date": self.to_date,
        "events": list(self.events) if self.events else None,
        "total_users": self.total_users,
        "buckets": [b.to_dict() for b in self.buckets],
    }

mixpanel_data.EngagementBucket dataclass

EngagementBucket(
    bucket_min: int, bucket_label: str, user_count: int, percentage: float
)

User count in an engagement bucket from engagement analysis.

Represents one bucket in a user engagement distribution, showing how many users performed events in a certain frequency range.

ATTRIBUTE DESCRIPTION
bucket_min

Minimum events in this bucket.

TYPE: int

bucket_label

Human-readable label (e.g., "1", "2-5", "100+").

TYPE: str

user_count

Number of users in this bucket.

TYPE: int

percentage

Percentage of total users (0.0 to 100.0).

TYPE: float

bucket_min instance-attribute

bucket_min: int

Minimum events in this bucket.

bucket_label instance-attribute

bucket_label: str

Human-readable label (e.g., '1', '2-5', '100+').

user_count instance-attribute

user_count: int

Number of users in this bucket.

percentage instance-attribute

percentage: float

Percentage of total users (0.0 to 100.0).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with bucket data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with bucket data.
    """
    return {
        "bucket_min": self.bucket_min,
        "bucket_label": self.bucket_label,
        "user_count": self.user_count,
        "percentage": self.percentage,
    }

mixpanel_data.PropertyCoverageResult dataclass

PropertyCoverageResult(
    event: str,
    from_date: str,
    to_date: str,
    total_events: int,
    coverage: tuple[PropertyCoverage, ...],
    _df_cache: DataFrame | None = None,
)

Property coverage analysis result from JQL.

Shows which properties are consistently populated vs sparse, helping understand data quality before writing queries.

ATTRIBUTE DESCRIPTION
event

The event type analyzed.

TYPE: str

from_date

Query start date (YYYY-MM-DD).

TYPE: str

to_date

Query end date (YYYY-MM-DD).

TYPE: str

total_events

Total number of events analyzed.

TYPE: int

coverage

Coverage statistics for each property.

TYPE: tuple[PropertyCoverage, ...]

event instance-attribute

event: str

Event type analyzed.

from_date instance-attribute

from_date: str

Query start date (YYYY-MM-DD).

to_date instance-attribute

to_date: str

Query end date (YYYY-MM-DD).

total_events instance-attribute

total_events: int

Total number of events analyzed.

coverage instance-attribute

coverage: tuple[PropertyCoverage, ...]

Coverage statistics for each property.

df property

df: DataFrame

Convert to DataFrame with property coverage columns.

Conversion is lazy - computed on first access and cached.

RETURNS DESCRIPTION
DataFrame

DataFrame with property coverage data.

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with all coverage data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with all coverage data.
    """
    return {
        "event": self.event,
        "from_date": self.from_date,
        "to_date": self.to_date,
        "total_events": self.total_events,
        "coverage": [c.to_dict() for c in self.coverage],
    }

mixpanel_data.PropertyCoverage dataclass

PropertyCoverage(
    property: str,
    defined_count: int,
    null_count: int,
    coverage_percentage: float,
)

Coverage statistics for a single property from coverage analysis.

Shows how often a property is defined vs null for a given event type.

ATTRIBUTE DESCRIPTION
property

Property name.

TYPE: str

defined_count

Number of events with this property defined.

TYPE: int

null_count

Number of events with this property null/undefined.

TYPE: int

coverage_percentage

Percentage of events with property defined (0.0-100.0).

TYPE: float

property instance-attribute

property: str

Property name.

defined_count instance-attribute

defined_count: int

Number of events with property defined.

null_count instance-attribute

null_count: int

Number of events with property null/undefined.

coverage_percentage instance-attribute

coverage_percentage: float

Percentage with property defined (0.0 to 100.0).

to_dict

to_dict() -> dict[str, Any]

Serialize for JSON output.

RETURNS DESCRIPTION
dict[str, Any]

Dictionary with coverage data.

Source code in src/mixpanel_data/types.py
def to_dict(self) -> dict[str, Any]:
    """Serialize for JSON output.

    Returns:
        Dictionary with coverage data.
    """
    return {
        "property": self.property,
        "defined_count": self.defined_count,
        "null_count": self.null_count,
        "coverage_percentage": self.coverage_percentage,
    }

Dashboard CRUD Types

mixpanel_data.Dashboard

Bases: BaseModel

A Mixpanel dashboard as returned by the App API.

Represents the full dashboard entity including metadata, permissions, and optional layout/content fields. Extra fields from API evolution are preserved via extra="allow".

ATTRIBUTE DESCRIPTION
id

Unique dashboard identifier.

TYPE: int

title

Dashboard title.

TYPE: str

description

Dashboard description.

TYPE: str | None

is_private

Whether the dashboard is private.

TYPE: bool

is_restricted

Whether the dashboard has restricted access.

TYPE: bool

creator_id

ID of the dashboard creator.

TYPE: int | None

creator_name

Name of the dashboard creator.

TYPE: str | None

creator_email

Email of the dashboard creator.

TYPE: str | None

created

Creation timestamp (lenient parsing).

TYPE: datetime | None

modified

Last modification timestamp.

TYPE: datetime | None

is_favorited

Whether the current user has favorited this dashboard.

TYPE: bool

pinned_date

Date the dashboard was pinned, if any.

TYPE: str | None

layout_version

Layout version metadata.

TYPE: Any | None

unique_view_count

Number of unique viewers.

TYPE: int | None

total_view_count

Total view count.

TYPE: int | None

last_modified_by_id

ID of the last modifier.

TYPE: int | None

last_modified_by_name

Name of the last modifier.

TYPE: str | None

last_modified_by_email

Email of the last modifier.

TYPE: str | None

filters

Dashboard-level filters.

TYPE: list[Any] | None

breakdowns

Dashboard-level breakdowns.

TYPE: list[Any] | None

time_filter

Dashboard-level time filter.

TYPE: Any | None

generation_type

How the dashboard was generated.

TYPE: str | None

parent_dashboard_id

Parent dashboard ID for nested dashboards.

TYPE: int | None

child_dashboards

Child dashboard references.

TYPE: list[Any] | None

can_update_basic

Permission flag.

TYPE: bool

can_share

Permission flag.

TYPE: bool

can_view

Permission flag.

TYPE: bool

can_update_restricted

Permission flag.

TYPE: bool

can_update_visibility

Permission flag.

TYPE: bool

is_superadmin

Whether current user is superadmin.

TYPE: bool

allow_staff_override

Whether staff override is allowed.

TYPE: bool

can_pin

Whether current user can pin.

TYPE: bool

is_shared_with_project

Whether shared with the project.

TYPE: bool

creator

Creator identifier string.

TYPE: str | None

ancestors

Ancestor dashboard references.

TYPE: list[Any]

layout

Dashboard layout data.

TYPE: Any | None

contents

Dashboard contents data.

TYPE: Any | None

num_active_public_links

Number of active public links.

TYPE: int | None

new_content

New content data.

TYPE: Any | None

template_type

Template type if created from a template.

TYPE: str | None

Example
dashboard = Dashboard(
    id=1, title="Q1 Metrics", is_private=False,
    is_restricted=False, is_favorited=False,
    can_update_basic=True, can_share=True, can_view=True,
    can_update_restricted=False, can_update_visibility=False,
    is_superadmin=False, allow_staff_override=False,
    can_pin=True, is_shared_with_project=True, ancestors=[],
)
assert dashboard.title == "Q1 Metrics"

id instance-attribute

id: int

Unique dashboard identifier.

title instance-attribute

title: str

Dashboard title.

description class-attribute instance-attribute

description: str | None = None

Dashboard description.

is_private class-attribute instance-attribute

is_private: bool = False

Whether the dashboard is private.

is_restricted class-attribute instance-attribute

is_restricted: bool = False

Whether the dashboard has restricted access.

creator_id class-attribute instance-attribute

creator_id: int | None = None

ID of the dashboard creator.

creator_name class-attribute instance-attribute

creator_name: str | None = None

Name of the dashboard creator.

creator_email class-attribute instance-attribute

creator_email: str | None = None

Email of the dashboard creator.

created class-attribute instance-attribute

created: datetime | None = None

Creation timestamp.

modified class-attribute instance-attribute

modified: datetime | None = None

Last modification timestamp.

is_favorited class-attribute instance-attribute

is_favorited: bool = False

Whether the current user has favorited this dashboard.

pinned_date class-attribute instance-attribute

pinned_date: str | None = None

Date the dashboard was pinned, if any.

layout_version class-attribute instance-attribute

layout_version: Any | None = None

Layout version metadata.

unique_view_count class-attribute instance-attribute

unique_view_count: int | None = None

Number of unique viewers.

total_view_count class-attribute instance-attribute

total_view_count: int | None = None

Total view count.

last_modified_by_id class-attribute instance-attribute

last_modified_by_id: int | None = None

ID of the last modifier.

last_modified_by_name class-attribute instance-attribute

last_modified_by_name: str | None = None

Name of the last modifier.

last_modified_by_email class-attribute instance-attribute

last_modified_by_email: str | None = None

Email of the last modifier.

filters class-attribute instance-attribute

filters: list[Any] | None = None

Dashboard-level filters.

breakdowns class-attribute instance-attribute

breakdowns: list[Any] | None = None

Dashboard-level breakdowns.

time_filter class-attribute instance-attribute

time_filter: Any | None = None

Dashboard-level time filter.

generation_type class-attribute instance-attribute

generation_type: str | None = None

How the dashboard was generated.

parent_dashboard_id class-attribute instance-attribute

parent_dashboard_id: int | None = None

Parent dashboard ID for nested dashboards.

child_dashboards class-attribute instance-attribute

child_dashboards: list[Any] | None = None

Child dashboard references.

can_update_basic class-attribute instance-attribute

can_update_basic: bool = False

Permission: can update basic fields.

can_share class-attribute instance-attribute

can_share: bool = False

Permission: can share.

can_view class-attribute instance-attribute

can_view: bool = False

Permission: can view.

can_update_restricted class-attribute instance-attribute

can_update_restricted: bool = False

Permission: can update restricted fields.

can_update_visibility class-attribute instance-attribute

can_update_visibility: bool = False

Permission: can update visibility.

is_superadmin class-attribute instance-attribute

is_superadmin: bool = False

Whether current user is superadmin.

allow_staff_override class-attribute instance-attribute

allow_staff_override: bool = False

Whether staff override is allowed.

can_pin class-attribute instance-attribute

can_pin: bool = False

Whether current user can pin.

is_shared_with_project class-attribute instance-attribute

is_shared_with_project: bool = False

Whether shared with the project.

creator class-attribute instance-attribute

creator: str | None = None

Creator identifier string.

ancestors class-attribute instance-attribute

ancestors: list[Any] = Field(default_factory=list)

Ancestor dashboard references.

layout class-attribute instance-attribute

layout: Any | None = None

Dashboard layout data.

contents class-attribute instance-attribute

contents: Any | None = None

Dashboard contents data.

num_active_public_links: int | None = None

Number of active public links.

new_content class-attribute instance-attribute

new_content: Any | None = None

New content data.

template_type class-attribute instance-attribute

template_type: str | None = None

Template type if created from a template.

mixpanel_data.CreateDashboardParams

Bases: BaseModel

Parameters for creating a new dashboard.

ATTRIBUTE DESCRIPTION
title

Dashboard title (required).

TYPE: str

description

Dashboard description.

TYPE: str | None

is_private

Whether the dashboard should be private.

TYPE: bool | None

is_restricted

Whether the dashboard should have restricted access.

TYPE: bool | None

filters

Dashboard-level filters.

TYPE: list[Any] | None

breakdowns

Dashboard-level breakdowns.

TYPE: list[Any] | None

time_filter

Dashboard-level time filter.

TYPE: Any | None

duplicate

ID of dashboard to duplicate.

TYPE: int | None

rows

Initial dashboard content with layout. Each row contains 1-4 content items (text cards or reports). Items in the same row are placed side-by-side with auto-distributed widths. This is the recommended way to create dashboards with proper layout — adding content after creation via update_dashboard() places each item in its own full-width row, and layout restructuring (merging items into shared rows) is not supported via PATCH.

TYPE: list[DashboardRow] | None

Example
import json

params = CreateDashboardParams(
    title="Product Health",
    rows=[
        DashboardRow(contents=[
            DashboardRowContent(
                content_type="text",
                content_params={"markdown": "<h2>Overview</h2>"},
            ),
        ]),
        DashboardRow(contents=[
            DashboardRowContent(
                content_type="report",
                content_params={"bookmark": {
                    "name": "DAU", "type": "insights",
                    "params": json.dumps(dau_result.params),
                }},
            ),
            DashboardRowContent(
                content_type="report",
                content_params={"bookmark": {
                    "name": "Signups", "type": "insights",
                    "params": json.dumps(signup_result.params),
                }},
            ),
        ]),
    ],
)

title instance-attribute

title: str

Dashboard title (required).

description class-attribute instance-attribute

description: str | None = None

Dashboard description.

is_private class-attribute instance-attribute

is_private: bool | None = None

Whether the dashboard should be private.

is_restricted class-attribute instance-attribute

is_restricted: bool | None = None

Whether the dashboard should have restricted access.

filters class-attribute instance-attribute

filters: list[Any] | None = None

Dashboard-level filters.

breakdowns class-attribute instance-attribute

breakdowns: list[Any] | None = None

Dashboard-level breakdowns.

time_filter class-attribute instance-attribute

time_filter: Any | None = None

Dashboard-level time filter.

duplicate class-attribute instance-attribute

duplicate: int | None = None

ID of dashboard to duplicate.

rows class-attribute instance-attribute

rows: list[DashboardRow] | None = None

Initial content rows with layout. Each row has 1-4 content items.

mixpanel_data.UpdateDashboardParams

Bases: BaseModel

Parameters for updating an existing dashboard.

All fields are optional — only provided fields are sent to the API.

ATTRIBUTE DESCRIPTION
title

New dashboard title.

TYPE: str | None

description

New dashboard description.

TYPE: str | None

is_private

New privacy setting.

TYPE: bool | None

is_restricted

New restriction setting.

TYPE: bool | None

filters

New dashboard-level filters.

TYPE: list[Any] | None

breakdowns

New dashboard-level breakdowns.

TYPE: list[Any] | None

time_filter

New dashboard-level time filter.

TYPE: Any | None

layout

New dashboard layout data.

TYPE: Any | None

content

New dashboard content data.

TYPE: Any | None

Example
params = UpdateDashboardParams(title="Q1 Metrics v2")
data = params.model_dump(exclude_none=True)
# {"title": "Q1 Metrics v2"}

title class-attribute instance-attribute

title: str | None = None

New dashboard title.

description class-attribute instance-attribute

description: str | None = None

New dashboard description.

is_private class-attribute instance-attribute

is_private: bool | None = None

New privacy setting.

is_restricted class-attribute instance-attribute

is_restricted: bool | None = None

New restriction setting.

filters class-attribute instance-attribute

filters: list[Any] | None = None

New dashboard-level filters.

breakdowns class-attribute instance-attribute

breakdowns: list[Any] | None = None

New dashboard-level breakdowns.

time_filter class-attribute instance-attribute

time_filter: Any | None = None

New dashboard-level time filter.

layout class-attribute instance-attribute

layout: Any | None = None

New dashboard layout data.

content class-attribute instance-attribute

content: Any | None = None

New dashboard content data.

mixpanel_data.BlueprintTemplate

Bases: BaseModel

A dashboard blueprint template.

ATTRIBUTE DESCRIPTION
title_key

Template title key.

TYPE: str

description_key

Template description key.

TYPE: str

alternative_description_key

Alternative description key.

TYPE: str | None

number_of_reports

Number of reports in the template.

TYPE: int | None

Example
template = BlueprintTemplate(
    title_key="onboarding", description_key="Get started"
)

title_key instance-attribute

title_key: str

Template title key.

description_key instance-attribute

description_key: str

Template description key.

alternative_description_key class-attribute instance-attribute

alternative_description_key: str | None = None

Alternative description key.

number_of_reports class-attribute instance-attribute

number_of_reports: int | None = None

Number of reports in the template.

mixpanel_data.BlueprintConfig

Bases: BaseModel

Configuration for a dashboard blueprint.

ATTRIBUTE DESCRIPTION
variables

Template variable mappings.

TYPE: dict[str, str]

Example
config = BlueprintConfig(variables={"event": "Signup"})

variables instance-attribute

variables: dict[str, str]

Template variable mappings.

mixpanel_data.BlueprintCard

Bases: BaseModel

A card in a blueprint dashboard.

ATTRIBUTE DESCRIPTION
card_type

Card type (serialized as "type").

TYPE: str

text_card_id

Text card ID, if applicable.

TYPE: int | None

bookmark_id

Bookmark ID, if applicable.

TYPE: int | None

markdown

Markdown content for text cards.

TYPE: str | None

name

Card name.

TYPE: str | None

params

Card parameters.

TYPE: dict[str, Any] | None

Example
card = BlueprintCard(card_type="report", bookmark_id=123)
data = card.model_dump(by_alias=True, exclude_none=True)
# {"type": "report", "bookmark_id": 123}

card_type class-attribute instance-attribute

card_type: str = Field(alias='type')

Card type (serialized as "type").

text_card_id class-attribute instance-attribute

text_card_id: int | None = None

Text card ID, if applicable.

bookmark_id class-attribute instance-attribute

bookmark_id: int | None = None

Bookmark ID, if applicable.

markdown class-attribute instance-attribute

markdown: str | None = None

Markdown content for text cards.

name class-attribute instance-attribute

name: str | None = None

Card name.

params class-attribute instance-attribute

params: dict[str, Any] | None = None

Card parameters.

mixpanel_data.BlueprintFinishParams

Bases: BaseModel

Parameters for finalizing a blueprint dashboard.

ATTRIBUTE DESCRIPTION
dashboard_id

ID of the blueprint dashboard to finalize.

TYPE: int

cards

List of cards to include.

TYPE: list[BlueprintCard]

Example
params = BlueprintFinishParams(
    dashboard_id=1,
    cards=[BlueprintCard(card_type="report", bookmark_id=123)],
)

dashboard_id instance-attribute

dashboard_id: int

ID of the blueprint dashboard to finalize.

cards instance-attribute

cards: list[BlueprintCard]

List of cards to include.

mixpanel_data.CreateRcaDashboardParams

Bases: BaseModel

Parameters for creating an RCA dashboard.

ATTRIBUTE DESCRIPTION
rca_source_id

Source ID for RCA analysis.

TYPE: int

rca_source_data

Source data configuration.

TYPE: RcaSourceData

Example
params = CreateRcaDashboardParams(
    rca_source_id=42,
    rca_source_data=RcaSourceData(source_type="anomaly"),
)

rca_source_id instance-attribute

rca_source_id: int

Source ID for RCA analysis.

rca_source_data instance-attribute

rca_source_data: RcaSourceData

Source data configuration.

mixpanel_data.RcaSourceData

Bases: BaseModel

Source data for RCA dashboard creation.

ATTRIBUTE DESCRIPTION
source_type

Source type (serialized as "type").

TYPE: str

date

Date string.

TYPE: str | None

metric_source

Whether this is a metric source.

TYPE: bool | None

Example
data = RcaSourceData(source_type="anomaly", date="2025-01-01")
dumped = data.model_dump(by_alias=True, exclude_none=True)
# {"type": "anomaly", "date": "2025-01-01"}

source_type class-attribute instance-attribute

source_type: str = Field(alias='type')

Source type (serialized as "type").

date class-attribute instance-attribute

date: str | None = None

Date string.

metric_source class-attribute instance-attribute

metric_source: bool | None = None

Whether this is a metric source.

mixpanel_data.UpdateReportLinkParams

Bases: BaseModel

Parameters for updating a report link on a dashboard.

ATTRIBUTE DESCRIPTION
link_type

Link type (serialized as "type").

TYPE: str

Example
params = UpdateReportLinkParams(link_type="embedded")
data = params.model_dump(by_alias=True, exclude_none=True)
# {"type": "embedded"}
link_type: str = Field(alias='type')

Link type (serialized as "type").

mixpanel_data.UpdateTextCardParams

Bases: BaseModel

Parameters for updating a text card on a dashboard.

ATTRIBUTE DESCRIPTION
markdown

Markdown content for the text card.

TYPE: str | None

Example
params = UpdateTextCardParams(markdown="# Hello")

markdown class-attribute instance-attribute

markdown: str | None = None

Markdown content for the text card.

Report CRUD Types

mixpanel_data.Bookmark

Bases: BaseModel

A Mixpanel bookmark (saved report) as returned by the App API.

Represents the full bookmark entity including query parameters, metadata, and permissions. The bookmark_type field is aliased from "type" in the API response.

ATTRIBUTE DESCRIPTION
id

Unique bookmark identifier.

TYPE: int

project_id

Parent project identifier.

TYPE: int | None

name

Bookmark name.

TYPE: str

bookmark_type

Report type (aliased from "type").

TYPE: str

description

Bookmark description.

TYPE: str | None

icon

Bookmark icon.

TYPE: str | None

params

Query parameters (JSON value defining the report).

TYPE: dict[str, Any] | None

dashboard_id

Associated dashboard ID.

TYPE: int | None

include_in_dashboard

Whether included in dashboard.

TYPE: bool | None

is_default

Whether this is a default bookmark.

TYPE: bool | None

creator_id

ID of the creator.

TYPE: int | None

creator_name

Name of the creator.

TYPE: str | None

creator_email

Email of the creator.

TYPE: str | None

created

Creation timestamp.

TYPE: datetime | None

modified

Last modification timestamp.

TYPE: datetime | None

last_modified_by_id

ID of the last modifier.

TYPE: int | None

last_modified_by_name

Name of the last modifier.

TYPE: str | None

last_modified_by_email

Email of the last modifier.

TYPE: str | None

metadata

Report-specific metadata.

TYPE: BookmarkMetadata | None

is_visibility_restricted

Visibility restriction flag.

TYPE: bool | None

is_modification_restricted

Modification restriction flag.

TYPE: bool | None

can_update_basic

Permission flag.

TYPE: bool | None

can_view

Permission flag.

TYPE: bool | None

can_share

Permission flag.

TYPE: bool | None

generation_type

How the bookmark was generated.

TYPE: str | None

original_type

Original report type before conversion.

TYPE: str | None

unique_view_count

Number of unique viewers.

TYPE: int | None

total_view_count

Total view count.

TYPE: int | None

Example
bookmark = Bookmark(
    id=1, name="Signup Funnel", bookmark_type="funnels",
    params={"events": [{"event": "Signup"}]},
)
assert bookmark.bookmark_type == "funnels"

id instance-attribute

id: int

Unique bookmark identifier.

project_id class-attribute instance-attribute

project_id: int | None = None

Parent project identifier.

name instance-attribute

name: str

Bookmark name.

bookmark_type class-attribute instance-attribute

bookmark_type: str = Field(alias='type')

Report type (aliased from "type").

description class-attribute instance-attribute

description: str | None = None

Bookmark description.

icon class-attribute instance-attribute

icon: str | None = None

Bookmark icon.

params class-attribute instance-attribute

params: dict[str, Any] | None = None

Query parameters (JSON value defining the report).

dashboard_id class-attribute instance-attribute

dashboard_id: int | None = None

Associated dashboard ID.

include_in_dashboard class-attribute instance-attribute

include_in_dashboard: bool | None = None

Whether included in dashboard.

is_default class-attribute instance-attribute

is_default: bool | None = None

Whether this is a default bookmark.

creator_id class-attribute instance-attribute

creator_id: int | None = None

ID of the creator.

creator_name class-attribute instance-attribute

creator_name: str | None = None

Name of the creator.

creator_email class-attribute instance-attribute

creator_email: str | None = None

Email of the creator.

created class-attribute instance-attribute

created: datetime | None = None

Creation timestamp.

modified class-attribute instance-attribute

modified: datetime | None = None

Last modification timestamp.

last_modified_by_id class-attribute instance-attribute

last_modified_by_id: int | None = None

ID of the last modifier.

last_modified_by_name class-attribute instance-attribute

last_modified_by_name: str | None = None

Name of the last modifier.

last_modified_by_email class-attribute instance-attribute

last_modified_by_email: str | None = None

Email of the last modifier.

metadata class-attribute instance-attribute

metadata: BookmarkMetadata | None = None

Report-specific metadata.

is_visibility_restricted class-attribute instance-attribute

is_visibility_restricted: bool | None = None

Visibility restriction flag.

is_modification_restricted class-attribute instance-attribute

is_modification_restricted: bool | None = None

Modification restriction flag.

can_update_basic class-attribute instance-attribute

can_update_basic: bool | None = None

Permission: can update basic fields.

can_view class-attribute instance-attribute

can_view: bool | None = None

Permission: can view.

can_share class-attribute instance-attribute

can_share: bool | None = None

Permission: can share.

generation_type class-attribute instance-attribute

generation_type: str | None = None

How the bookmark was generated.

original_type class-attribute instance-attribute

original_type: str | None = None

Original report type before conversion.

unique_view_count class-attribute instance-attribute

unique_view_count: int | None = None

Number of unique viewers.

total_view_count class-attribute instance-attribute

total_view_count: int | None = None

Total view count.

mixpanel_data.BookmarkMetadata

Bases: BaseModel

Metadata associated with a bookmark/report.

Contains optional display and calculation settings that vary by bookmark type (insights, funnels, retention, etc.).

ATTRIBUTE DESCRIPTION
table_display_mode

Table display mode setting.

TYPE: str | None

compare_enabled

Whether comparison is enabled.

TYPE: bool | None

compare_filters

Comparison filter settings.

TYPE: list[Any] | None

retention_calculation_type

Retention calculation method.

TYPE: str | None

event_name

Associated event name.

TYPE: str | None

funnel_conversion_window

Funnel conversion window in days.

TYPE: int | None

funnel_breakdown_limit

Maximum funnel breakdown count.

TYPE: int | None

Example
meta = BookmarkMetadata(
    table_display_mode="linear",
    compare_enabled=True,
)

table_display_mode class-attribute instance-attribute

table_display_mode: str | None = None

Table display mode setting.

compare_enabled class-attribute instance-attribute

compare_enabled: bool | None = None

Whether comparison is enabled.

compare_filters class-attribute instance-attribute

compare_filters: list[Any] | None = None

Comparison filter settings.

retention_calculation_type class-attribute instance-attribute

retention_calculation_type: str | None = None

Retention calculation method.

event_name class-attribute instance-attribute

event_name: str | None = None

Associated event name.

funnel_conversion_window class-attribute instance-attribute

funnel_conversion_window: int | None = None

Funnel conversion window in days.

funnel_breakdown_limit class-attribute instance-attribute

funnel_breakdown_limit: int | None = None

Maximum funnel breakdown count.

mixpanel_data.CreateBookmarkParams

Bases: BaseModel

Parameters for creating a new bookmark/report.

ATTRIBUTE DESCRIPTION
name

Bookmark name (required).

TYPE: str

bookmark_type

Report type (required, serialized as "type").

TYPE: str

params

Query parameters (required).

TYPE: dict[str, Any]

description

Bookmark description.

TYPE: str | None

icon

Bookmark icon.

TYPE: str | None

dashboard_id

Dashboard to associate with. Required by Workspace.create_bookmark() — the Mixpanel v2 API requires every bookmark to belong to a dashboard.

TYPE: int | None

is_visibility_restricted

Visibility restriction flag.

TYPE: bool | None

is_modification_restricted

Modification restriction flag.

TYPE: bool | None

Example
params = CreateBookmarkParams(
    name="Signup Funnel",
    bookmark_type="funnels",
    params={"events": [{"event": "Signup"}]},
    dashboard_id=12345,
)
data = params.model_dump(by_alias=True, exclude_none=True)

name instance-attribute

name: str

Bookmark name (required).

bookmark_type class-attribute instance-attribute

bookmark_type: str = Field(alias='type')

Report type (required, serialized as "type").

params instance-attribute

params: dict[str, Any]

Query parameters (required).

description class-attribute instance-attribute

description: str | None = None

Bookmark description.

icon class-attribute instance-attribute

icon: str | None = None

Bookmark icon.

dashboard_id class-attribute instance-attribute

dashboard_id: int | None = None

Dashboard to associate with.

is_visibility_restricted class-attribute instance-attribute

is_visibility_restricted: bool | None = None

Visibility restriction flag.

is_modification_restricted class-attribute instance-attribute

is_modification_restricted: bool | None = None

Modification restriction flag.

mixpanel_data.UpdateBookmarkParams

Bases: BaseModel

Parameters for updating an existing bookmark/report.

All fields are optional — only provided fields are sent to the API.

ATTRIBUTE DESCRIPTION
name

New bookmark name.

TYPE: str | None

params

New query parameters.

TYPE: dict[str, Any] | None

description

New bookmark description.

TYPE: str | None

icon

New bookmark icon.

TYPE: str | None

dashboard_id

New associated dashboard ID.

TYPE: int | None

is_visibility_restricted

New visibility restriction.

TYPE: bool | None

is_modification_restricted

New modification restriction.

TYPE: bool | None

deleted

Soft-delete flag.

TYPE: bool | None

Example
params = UpdateBookmarkParams(name="Updated Funnel")
data = params.model_dump(exclude_none=True)
# {"name": "Updated Funnel"}

name class-attribute instance-attribute

name: str | None = None

New bookmark name.

params class-attribute instance-attribute

params: dict[str, Any] | None = None

New query parameters.

description class-attribute instance-attribute

description: str | None = None

New bookmark description.

icon class-attribute instance-attribute

icon: str | None = None

New bookmark icon.

dashboard_id class-attribute instance-attribute

dashboard_id: int | None = None

New associated dashboard ID.

is_visibility_restricted class-attribute instance-attribute

is_visibility_restricted: bool | None = None

New visibility restriction.

is_modification_restricted class-attribute instance-attribute

is_modification_restricted: bool | None = None

New modification restriction.

deleted class-attribute instance-attribute

deleted: bool | None = None

Soft-delete flag.

mixpanel_data.BulkUpdateBookmarkEntry

Bases: BaseModel

Entry for bulk-updating bookmarks.

ATTRIBUTE DESCRIPTION
id

Bookmark ID to update (required).

TYPE: int

name

New bookmark name.

TYPE: str | None

params

New query parameters.

TYPE: dict[str, Any] | None

description

New bookmark description.

TYPE: str | None

icon

New bookmark icon.

TYPE: str | None

is_visibility_restricted

New visibility restriction.

TYPE: bool | None

is_modification_restricted

New modification restriction.

TYPE: bool | None

Example
entry = BulkUpdateBookmarkEntry(id=123, name="Renamed")

id instance-attribute

id: int

Bookmark ID to update (required).

name class-attribute instance-attribute

name: str | None = None

New bookmark name.

params class-attribute instance-attribute

params: dict[str, Any] | None = None

New query parameters.

description class-attribute instance-attribute

description: str | None = None

New bookmark description.

icon class-attribute instance-attribute

icon: str | None = None

New bookmark icon.

is_visibility_restricted class-attribute instance-attribute

is_visibility_restricted: bool | None = None

New visibility restriction.

is_modification_restricted class-attribute instance-attribute

is_modification_restricted: bool | None = None

New modification restriction.

mixpanel_data.BookmarkHistoryResponse

Bases: BaseModel

Response from the bookmark history endpoint.

ATTRIBUTE DESCRIPTION
results

List of history entries.

TYPE: list[Any]

pagination

Pagination metadata.

TYPE: BookmarkHistoryPagination | None

Example
response = BookmarkHistoryResponse(results=[{"action": "created"}])

results class-attribute instance-attribute

results: list[Any] = Field(default_factory=list)

List of history entries.

pagination class-attribute instance-attribute

pagination: BookmarkHistoryPagination | None = None

Pagination metadata.

mixpanel_data.BookmarkHistoryPagination

Bases: BaseModel

Pagination metadata for bookmark history responses.

ATTRIBUTE DESCRIPTION
next_cursor

Cursor for next page.

TYPE: str | None

previous_cursor

Cursor for previous page.

TYPE: str | None

page_size

Number of items per page.

TYPE: int

Example
pagination = BookmarkHistoryPagination(page_size=20)

next_cursor class-attribute instance-attribute

next_cursor: str | None = None

Cursor for next page.

previous_cursor class-attribute instance-attribute

previous_cursor: str | None = None

Cursor for previous page.

page_size class-attribute instance-attribute

page_size: int = 0

Number of items per page.

Cohort CRUD Types

mixpanel_data.Cohort

Bases: BaseModel

A Mixpanel cohort as returned by the App API.

Represents the full cohort entity with definition, metadata, and cross-references. Extra fields from API evolution are preserved via extra="allow".

ATTRIBUTE DESCRIPTION
id

Unique cohort identifier.

TYPE: int

name

Cohort name.

TYPE: str

description

Cohort description.

TYPE: str | None

count

Number of users in the cohort.

TYPE: int | None

is_visible

Whether the cohort is visible.

TYPE: bool | None

is_locked

Whether the cohort is locked.

TYPE: bool | None

data_group_id

Data group identifier.

TYPE: str | None

last_edited

Last edited timestamp string.

TYPE: str | None

created_by

Creator information.

TYPE: CohortCreator | None

referenced_by

IDs of entities referencing this cohort.

TYPE: list[int] | None

verified

Whether the cohort is verified.

TYPE: bool

last_queried

Last queried timestamp string.

TYPE: str | None

referenced_directly_by

IDs of entities directly referencing this cohort.

TYPE: list[int]

active_integrations

Active integration IDs.

TYPE: list[int]

Example
cohort = Cohort(id=1, name="Power Users")
assert cohort.name == "Power Users"

id instance-attribute

id: int

Unique cohort identifier.

name instance-attribute

name: str

Cohort name.

description class-attribute instance-attribute

description: str | None = None

Cohort description.

count class-attribute instance-attribute

count: int | None = None

Number of users in the cohort.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

Whether the cohort is visible.

is_locked class-attribute instance-attribute

is_locked: bool | None = None

Whether the cohort is locked.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

last_edited class-attribute instance-attribute

last_edited: str | None = None

Last edited timestamp string.

created_by class-attribute instance-attribute

created_by: CohortCreator | None = None

Creator information.

referenced_by class-attribute instance-attribute

referenced_by: list[int] | None = None

IDs of entities referencing this cohort.

verified class-attribute instance-attribute

verified: bool = False

Whether the cohort is verified.

last_queried class-attribute instance-attribute

last_queried: str | None = None

Last queried timestamp string.

referenced_directly_by class-attribute instance-attribute

referenced_directly_by: list[int] = Field(default_factory=list)

IDs of entities directly referencing this cohort.

active_integrations class-attribute instance-attribute

active_integrations: list[int] = Field(default_factory=list)

Active integration IDs.

mixpanel_data.CohortCreator

Bases: BaseModel

Creator information for a cohort.

ATTRIBUTE DESCRIPTION
id

Creator user ID.

TYPE: int | None

name

Creator name.

TYPE: str | None

email

Creator email.

TYPE: str | None

Example
creator = CohortCreator(id=1, name="Alice", email="alice@example.com")

id class-attribute instance-attribute

id: int | None = None

Creator user ID.

name class-attribute instance-attribute

name: str | None = None

Creator name.

email class-attribute instance-attribute

email: str | None = None

Creator email.

mixpanel_data.CreateCohortParams

Bases: _DefinitionFlatteningModel

Parameters for creating a new cohort.

The definition dict is flattened into the top-level JSON payload at serialization time — its keys become top-level fields in the request body.

ATTRIBUTE DESCRIPTION
name

Cohort name (required).

TYPE: str

description

Cohort description.

TYPE: str | None

data_group_id

Data group identifier.

TYPE: str | None

is_locked

Whether the cohort should be locked.

TYPE: bool | None

is_visible

Whether the cohort should be visible.

TYPE: bool | None

deleted

Soft-delete flag.

TYPE: bool | None

Example
params = CreateCohortParams(name="Power Users")
data = params.model_dump(exclude_none=True)
# {"name": "Power Users"}

name instance-attribute

name: str

Cohort name (required).

description class-attribute instance-attribute

description: str | None = None

Cohort description.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

is_locked class-attribute instance-attribute

is_locked: bool | None = None

Whether the cohort should be locked.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

Whether the cohort should be visible.

deleted class-attribute instance-attribute

deleted: bool | None = None

Soft-delete flag.

mixpanel_data.UpdateCohortParams

Bases: _DefinitionFlatteningModel

Parameters for updating an existing cohort.

All fields are optional — only provided fields are sent to the API. The definition dict is flattened into the payload.

ATTRIBUTE DESCRIPTION
name

New cohort name.

TYPE: str | None

description

New cohort description.

TYPE: str | None

data_group_id

New data group identifier.

TYPE: str | None

is_locked

New lock setting.

TYPE: bool | None

is_visible

New visibility setting.

TYPE: bool | None

deleted

Soft-delete flag.

TYPE: bool | None

Example
params = UpdateCohortParams(name="Updated Cohort")
data = params.model_dump(exclude_none=True)
# {"name": "Updated Cohort"}

name class-attribute instance-attribute

name: str | None = None

New cohort name.

description class-attribute instance-attribute

description: str | None = None

New cohort description.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

New data group identifier.

is_locked class-attribute instance-attribute

is_locked: bool | None = None

New lock setting.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

New visibility setting.

deleted class-attribute instance-attribute

deleted: bool | None = None

Soft-delete flag.

mixpanel_data.BulkUpdateCohortEntry

Bases: _DefinitionFlatteningModel

Entry for bulk-updating cohorts.

ATTRIBUTE DESCRIPTION
id

Cohort ID to update (required).

TYPE: int

name

New cohort name.

TYPE: str | None

description

New cohort description.

TYPE: str | None

Example
entry = BulkUpdateCohortEntry(id=1, name="Renamed")

id instance-attribute

id: int

Cohort ID to update (required).

name class-attribute instance-attribute

name: str | None = None

New cohort name.

description class-attribute instance-attribute

description: str | None = None

New cohort description.

Feature Flag Enums

mixpanel_data.FeatureFlagStatus

Bases: str, Enum

Lifecycle state of a feature flag.

ATTRIBUTE DESCRIPTION
ENABLED

Flag is active and serving variants.

DISABLED

Flag is inactive (default state).

ARCHIVED

Flag is soft-deleted, excluded from default listings.

Example
status = FeatureFlagStatus.ENABLED
assert status.value == "enabled"

mixpanel_data.ServingMethod

Bases: str, Enum

Controls how flag values are delivered to clients.

ATTRIBUTE DESCRIPTION
CLIENT

Client-side evaluation (default).

SERVER

Server-side evaluation only.

REMOTE_OR_LOCAL

Remote preferred, local fallback.

REMOTE_ONLY

Remote evaluation only.

Example
method = ServingMethod.CLIENT
assert method.value == "client"

mixpanel_data.FlagContractStatus

Bases: str, Enum

Account-level flag contract status.

ATTRIBUTE DESCRIPTION
ACTIVE

Active contract.

GRACE_PERIOD

Contract in grace period.

EXPIRED

Contract expired.

Example
status = FlagContractStatus.ACTIVE
assert status.value == "active"

Feature Flag Types

mixpanel_data.FeatureFlag

Bases: BaseModel

A Mixpanel feature flag as returned by the App API.

Represents the full feature flag entity including configuration, metadata, and permissions. Extra fields from API evolution are preserved via extra="allow".

ATTRIBUTE DESCRIPTION
id

Unique identifier (UUID).

TYPE: str

project_id

Project this flag belongs to.

TYPE: int

name

Human-readable name.

TYPE: str

key

Machine-readable key (unique per project).

TYPE: str

description

Optional description.

TYPE: str | None

status

Current lifecycle status.

TYPE: FeatureFlagStatus

tags

Tags for organization.

TYPE: list[str]

experiment_id

Linked experiment ID if flag backs an experiment.

TYPE: str | None

context

Flag context identifier.

TYPE: str

data_group_id

Data group identifier.

TYPE: str | None

serving_method

How flag values are delivered.

TYPE: ServingMethod

ruleset

Variants, rollout rules, and test overrides.

TYPE: dict[str, Any]

hash_salt

Salt for deterministic variant assignment.

TYPE: str | None

workspace_id

Workspace this flag belongs to.

TYPE: int | None

content_type

Content type identifier.

TYPE: str | None

created

ISO 8601 creation timestamp.

TYPE: str

modified

ISO 8601 last-modified timestamp.

TYPE: str

enabled_at

Timestamp when flag was last enabled.

TYPE: str | None

deleted

Timestamp when flag was deleted.

TYPE: str | None

creator_id

Creator's user ID.

TYPE: int | None

creator_name

Creator's display name.

TYPE: str | None

creator_email

Creator's email.

TYPE: str | None

last_modified_by_id

Last modifier's user ID.

TYPE: int | None

last_modified_by_name

Last modifier's display name.

TYPE: str | None

last_modified_by_email

Last modifier's email.

TYPE: str | None

is_favorited

Whether current user has favorited.

TYPE: bool | None

pinned_date

Date flag was pinned.

TYPE: str | None

can_edit

Permission: can current user edit.

TYPE: bool

Example
flag = FeatureFlag(
    id="abc-123",
    project_id=12345,
    name="Dark Mode",
    key="dark_mode",
    status=FeatureFlagStatus.DISABLED,
    context="default",
    serving_method=ServingMethod.CLIENT,
    ruleset={"variants": []},
    created="2026-01-01T00:00:00Z",
    modified="2026-01-01T00:00:00Z",
)
assert flag.key == "dark_mode"

id instance-attribute

id: str

Unique identifier (UUID).

project_id instance-attribute

project_id: int

Project this flag belongs to.

name instance-attribute

name: str

Human-readable name.

key instance-attribute

key: str

Machine-readable key (unique per project).

description class-attribute instance-attribute

description: str | None = None

Optional description.

status class-attribute instance-attribute

status: FeatureFlagStatus = DISABLED

Current lifecycle status.

tags class-attribute instance-attribute

tags: list[str] = Field(default_factory=list)

Tags for organization.

experiment_id class-attribute instance-attribute

experiment_id: str | None = None

Linked experiment ID if flag backs an experiment.

context class-attribute instance-attribute

context: str = ''

Flag context identifier.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

serving_method class-attribute instance-attribute

serving_method: ServingMethod = CLIENT

How flag values are delivered.

ruleset class-attribute instance-attribute

ruleset: dict[str, Any] = Field(default_factory=dict)

Variants, rollout rules, and test overrides.

hash_salt class-attribute instance-attribute

hash_salt: str | None = None

Salt for deterministic variant assignment.

workspace_id class-attribute instance-attribute

workspace_id: int | None = None

Workspace this flag belongs to.

content_type class-attribute instance-attribute

content_type: str | None = None

Content type identifier.

created class-attribute instance-attribute

created: str = ''

ISO 8601 creation timestamp.

modified class-attribute instance-attribute

modified: str = ''

ISO 8601 last-modified timestamp.

enabled_at class-attribute instance-attribute

enabled_at: str | None = None

Timestamp when flag was last enabled.

deleted class-attribute instance-attribute

deleted: str | None = None

Timestamp when flag was deleted.

creator_id class-attribute instance-attribute

creator_id: int | None = None

Creator's user ID.

creator_name class-attribute instance-attribute

creator_name: str | None = None

Creator's display name.

creator_email class-attribute instance-attribute

creator_email: str | None = None

Creator's email.

last_modified_by_id class-attribute instance-attribute

last_modified_by_id: int | None = None

Last modifier's user ID.

last_modified_by_name class-attribute instance-attribute

last_modified_by_name: str | None = None

Last modifier's display name.

last_modified_by_email class-attribute instance-attribute

last_modified_by_email: str | None = None

Last modifier's email.

is_favorited class-attribute instance-attribute

is_favorited: bool | None = None

Whether current user has favorited.

pinned_date class-attribute instance-attribute

pinned_date: str | None = None

Date flag was pinned.

can_edit class-attribute instance-attribute

can_edit: bool = False

Permission: can current user edit.

mixpanel_data.CreateFeatureFlagParams

Bases: BaseModel

Parameters for creating a new feature flag.

The Mixpanel API requires name, key, context, serving_method, tags, and ruleset (with variants and rollout sub-fields). Sensible defaults are provided for the non-obvious required fields so that minimal usage works::

CreateFeatureFlagParams(name="Dark Mode", key="dark_mode")
ATTRIBUTE DESCRIPTION
name

Flag name (required).

TYPE: str

key

Unique machine-readable key (required).

TYPE: str

description

Optional description.

TYPE: str | None

status

Initial status (defaults to disabled).

TYPE: FeatureFlagStatus | None

tags

Tags for organization (required by API, defaults to empty list).

TYPE: list[str]

context

Flag context identifier (required by API, defaults to "distinct_id").

TYPE: str

serving_method

How flag values are delivered (required by API, defaults to ServingMethod.CLIENT).

TYPE: ServingMethod

ruleset

Ruleset with variants and rollout keys (required by API, defaults to a simple On/Off toggle).

TYPE: dict[str, Any]

Example
params = CreateFeatureFlagParams(name="Dark Mode", key="dark_mode")
data = params.model_dump(exclude_none=True)

name instance-attribute

name: str

Flag name (required).

key instance-attribute

key: str

Unique machine-readable key (required).

description class-attribute instance-attribute

description: str | None = None

Optional description.

status class-attribute instance-attribute

status: FeatureFlagStatus | None = None

Initial status (defaults to disabled).

tags class-attribute instance-attribute

tags: list[str] = Field(default_factory=list)

Tags for organization (required by API, defaults to empty list).

context class-attribute instance-attribute

context: str = 'distinct_id'

Flag context identifier (required by API).

serving_method class-attribute instance-attribute

serving_method: ServingMethod = CLIENT

How flag values are delivered (required by API).

ruleset class-attribute instance-attribute

ruleset: dict[str, Any] = Field(
    default_factory=lambda: {
        "variants": [
            {
                "key": "On",
                "value": True,
                "is_control": False,
                "split": 1.0,
                "is_sticky": False,
            },
            {
                "key": "Off",
                "value": False,
                "is_control": True,
                "split": 0.0,
                "is_sticky": False,
            },
        ],
        "rollout": [],
    }
)

Ruleset with variants and rollout (required by API).

mixpanel_data.UpdateFeatureFlagParams

Bases: BaseModel

Parameters for updating an existing feature flag (PUT semantics).

All required fields must always be provided since this performs a full replacement, not a partial update. The API requires tags, context, and serving_method in addition to name, key, status, and ruleset.

ATTRIBUTE DESCRIPTION
name

Flag name (required).

TYPE: str

key

Unique key (required).

TYPE: str

status

Target status (required).

TYPE: FeatureFlagStatus

ruleset

Complete ruleset — replaces existing (required).

TYPE: dict[str, Any]

description

Optional description.

TYPE: str | None

tags

Tags for organization (required by API, defaults to empty list).

TYPE: list[str]

context

Flag context identifier (required by API, defaults to "distinct_id").

TYPE: str

serving_method

How flag values are delivered (required by API, defaults to ServingMethod.CLIENT).

TYPE: ServingMethod

Example
params = UpdateFeatureFlagParams(
    name="Dark Mode",
    key="dark_mode",
    status=FeatureFlagStatus.ENABLED,
    ruleset={"variants": [], "rollout": []},
)

name instance-attribute

name: str

Flag name (required).

key instance-attribute

key: str

Unique key (required).

status instance-attribute

status: FeatureFlagStatus

Target status (required).

ruleset instance-attribute

ruleset: dict[str, Any]

Complete ruleset — replaces existing (required).

description class-attribute instance-attribute

description: str | None = None

Optional description.

tags class-attribute instance-attribute

tags: list[str] = Field(default_factory=list)

Tags for organization (required by API, defaults to empty list).

context class-attribute instance-attribute

context: str = 'distinct_id'

Flag context identifier (required by API).

serving_method class-attribute instance-attribute

serving_method: ServingMethod = CLIENT

How flag values are delivered (required by API).

mixpanel_data.SetTestUsersParams

Bases: BaseModel

Parameters for setting test user variant overrides on a flag.

ATTRIBUTE DESCRIPTION
users

Mapping of variant keys to user distinct IDs.

TYPE: dict[str, str]

Example
params = SetTestUsersParams(users={"on": "user-1", "off": "user-2"})

users instance-attribute

users: dict[str, str]

Mapping of variant keys to user distinct IDs.

mixpanel_data.FlagHistoryParams

Bases: BaseModel

Parameters for querying feature flag change history.

ATTRIBUTE DESCRIPTION
page

Pagination cursor.

TYPE: str | None

page_size

Results per page.

TYPE: int | None

Example
params = FlagHistoryParams(page_size=50)

page class-attribute instance-attribute

page: str | None = None

Pagination cursor.

page_size class-attribute instance-attribute

page_size: int | None = None

Results per page.

mixpanel_data.FlagHistoryResponse

Bases: BaseModel

Paginated change history for a feature flag.

ATTRIBUTE DESCRIPTION
events

Array of event arrays.

TYPE: list[list[Any]]

count

Total number of events.

TYPE: int

Example
response = FlagHistoryResponse(events=[[1, "change"]], count=1)
assert response.count == 1

events instance-attribute

events: list[list[Any]]

Array of event arrays.

count instance-attribute

count: int

Total number of events.

mixpanel_data.FlagLimitsResponse

Bases: BaseModel

Account-level feature flag usage and limits.

ATTRIBUTE DESCRIPTION
limit

Maximum allowed flags.

TYPE: int

is_trial

Whether account is on trial.

TYPE: bool

current_usage

Current number of flags.

TYPE: int

contract_status

Contract status.

TYPE: FlagContractStatus

Example
limits = FlagLimitsResponse(
    limit=100, is_trial=False, current_usage=42,
    contract_status=FlagContractStatus.ACTIVE,
)
assert limits.current_usage == 42

limit instance-attribute

limit: int

Maximum allowed flags.

is_trial instance-attribute

is_trial: bool

Whether account is on trial.

current_usage instance-attribute

current_usage: int

Current number of flags.

contract_status instance-attribute

contract_status: FlagContractStatus

Contract status.

Experiment Enums

mixpanel_data.ExperimentStatus

Bases: str, Enum

Lifecycle state of an experiment.

State transitions: draftactive (launch) → concluded (conclude) → success | fail (decide).

ATTRIBUTE DESCRIPTION
DRAFT

Experiment created but not started.

ACTIVE

Experiment running, collecting data.

CONCLUDED

Experiment stopped, awaiting decision.

SUCCESS

Experiment decided as successful.

FAIL

Experiment decided as failed.

Example
status = ExperimentStatus.DRAFT
assert status.value == "draft"

Experiment Types

mixpanel_data.ExperimentCreator

Bases: BaseModel

Creator metadata for an experiment.

ATTRIBUTE DESCRIPTION
id

Creator's user ID.

TYPE: int | None

first_name

Creator's first name.

TYPE: str | None

last_name

Creator's last name.

TYPE: str | None

Example
creator = ExperimentCreator(id=1, first_name="Alice", last_name="Smith")

id class-attribute instance-attribute

id: int | None = None

Creator's user ID.

first_name class-attribute instance-attribute

first_name: str | None = None

Creator's first name.

last_name class-attribute instance-attribute

last_name: str | None = None

Creator's last name.

mixpanel_data.Experiment

Bases: BaseModel

A Mixpanel A/B experiment as returned by the App API.

Represents the full experiment entity including lifecycle state, variants, metrics, and metadata. Extra fields from API evolution are preserved via extra="allow".

ATTRIBUTE DESCRIPTION
id

Unique identifier (UUID).

TYPE: str

name

Human-readable name.

TYPE: str

description

Optional description.

TYPE: str | None

hypothesis

Experiment hypothesis.

TYPE: str | None

status

Current lifecycle status.

TYPE: ExperimentStatus | None

variants

Variant configuration.

TYPE: list[Any] | dict[str, Any] | None

metrics

Success metrics.

TYPE: list[Any] | dict[str, Any] | None

settings

Experiment settings.

TYPE: dict[str, Any] | None

exposures_cache

Cached exposure data.

TYPE: dict[str, Any] | None

results_cache

Cached result data.

TYPE: dict[str, Any] | None

start_date

ISO 8601 start date.

TYPE: str | None

end_date

ISO 8601 end date.

TYPE: str | None

created

ISO 8601 creation timestamp.

TYPE: str | None

updated

ISO 8601 last-updated timestamp.

TYPE: str | None

creator

Creator metadata.

TYPE: ExperimentCreator | None

feature_flag

Linked feature flag data.

TYPE: dict[str, Any] | None

is_favorited

Whether current user has favorited.

TYPE: bool | None

pinned_date

Date experiment was pinned.

TYPE: str | None

tags

Tags for organization.

TYPE: list[str] | None

can_edit

Permission: can current user edit.

TYPE: bool | None

last_modified_by_id

Last modifier's user ID.

TYPE: int | None

last_modified_by_name

Last modifier's display name.

TYPE: str | None

last_modified_by_email

Last modifier's email.

TYPE: str | None

Example
exp = Experiment(id="xyz-456", name="Checkout Flow Test")
assert exp.name == "Checkout Flow Test"

id instance-attribute

id: str

Unique identifier (UUID).

name instance-attribute

name: str

Human-readable name.

description class-attribute instance-attribute

description: str | None = None

Optional description.

hypothesis class-attribute instance-attribute

hypothesis: str | None = None

Experiment hypothesis.

status class-attribute instance-attribute

status: ExperimentStatus | None = None

Current lifecycle status.

variants class-attribute instance-attribute

variants: list[Any] | dict[str, Any] | None = None

Variant configuration (list from API, may also be dict).

metrics class-attribute instance-attribute

metrics: list[Any] | dict[str, Any] | None = None

Success metrics (list from API, may also be dict).

settings class-attribute instance-attribute

settings: dict[str, Any] | None = None

Experiment settings.

exposures_cache class-attribute instance-attribute

exposures_cache: dict[str, Any] | None = None

Cached exposure data.

results_cache class-attribute instance-attribute

results_cache: dict[str, Any] | None = None

Cached result data.

start_date class-attribute instance-attribute

start_date: str | None = None

ISO 8601 start date.

end_date class-attribute instance-attribute

end_date: str | None = None

ISO 8601 end date.

created class-attribute instance-attribute

created: str | None = None

ISO 8601 creation timestamp.

updated class-attribute instance-attribute

updated: str | None = None

ISO 8601 last-updated timestamp.

creator class-attribute instance-attribute

creator: ExperimentCreator | None = None

Creator metadata.

feature_flag class-attribute instance-attribute

feature_flag: dict[str, Any] | None = None

Linked feature flag data.

is_favorited class-attribute instance-attribute

is_favorited: bool | None = None

Whether current user has favorited.

pinned_date class-attribute instance-attribute

pinned_date: str | None = None

Date experiment was pinned.

tags class-attribute instance-attribute

tags: list[str] | None = None

Tags for organization.

can_edit class-attribute instance-attribute

can_edit: bool | None = None

Permission: can current user edit.

last_modified_by_id class-attribute instance-attribute

last_modified_by_id: int | None = None

Last modifier's user ID.

last_modified_by_name class-attribute instance-attribute

last_modified_by_name: str | None = None

Last modifier's display name.

last_modified_by_email class-attribute instance-attribute

last_modified_by_email: str | None = None

Last modifier's email.

mixpanel_data.CreateExperimentParams

Bases: BaseModel

Parameters for creating a new experiment.

ATTRIBUTE DESCRIPTION
name

Experiment name (required).

TYPE: str

description

Optional description.

TYPE: str | None

hypothesis

Experiment hypothesis.

TYPE: str | None

settings

Experiment settings.

TYPE: dict[str, Any] | None

access_type

Access control type.

TYPE: str | None

can_edit

Edit permission.

TYPE: bool | None

Example
params = CreateExperimentParams(name="Checkout Flow Test")
data = params.model_dump(exclude_none=True)
# {"name": "Checkout Flow Test"}

name instance-attribute

name: str

Experiment name (required).

description class-attribute instance-attribute

description: str | None = None

Optional description.

hypothesis class-attribute instance-attribute

hypothesis: str | None = None

Experiment hypothesis.

settings class-attribute instance-attribute

settings: dict[str, Any] | None = None

Experiment settings.

access_type class-attribute instance-attribute

access_type: str | None = None

Access control type.

can_edit class-attribute instance-attribute

can_edit: bool | None = None

Edit permission.

mixpanel_data.UpdateExperimentParams

Bases: BaseModel

Parameters for updating an existing experiment (PATCH semantics).

All fields optional — only provided fields are updated.

ATTRIBUTE DESCRIPTION
name

Updated name.

TYPE: str | None

description

Updated description.

TYPE: str | None

hypothesis

Updated hypothesis.

TYPE: str | None

variants

Updated variant config.

TYPE: list[Any] | dict[str, Any] | None

metrics

Updated metrics.

TYPE: list[Any] | dict[str, Any] | None

settings

Updated settings.

TYPE: dict[str, Any] | None

start_date

Updated start date.

TYPE: str | None

end_date

Updated end date.

TYPE: str | None

tags

Updated tags.

TYPE: list[str] | None

exposures_cache

Updated exposures cache.

TYPE: dict[str, Any] | None

results_cache

Updated results cache.

TYPE: dict[str, Any] | None

status

Updated status.

TYPE: ExperimentStatus | None

global_access_type

Updated access type.

TYPE: str | None

Example
params = UpdateExperimentParams(description="Updated")
data = params.model_dump(exclude_none=True)
# {"description": "Updated"}

name class-attribute instance-attribute

name: str | None = None

Updated name.

description class-attribute instance-attribute

description: str | None = None

Updated description.

hypothesis class-attribute instance-attribute

hypothesis: str | None = None

Updated hypothesis.

variants class-attribute instance-attribute

variants: list[Any] | dict[str, Any] | None = None

Updated variant config (list or dict).

metrics class-attribute instance-attribute

metrics: list[Any] | dict[str, Any] | None = None

Updated metrics (list or dict).

settings class-attribute instance-attribute

settings: dict[str, Any] | None = None

Updated settings.

start_date class-attribute instance-attribute

start_date: str | None = None

Updated start date.

end_date class-attribute instance-attribute

end_date: str | None = None

Updated end date.

tags class-attribute instance-attribute

tags: list[str] | None = None

Updated tags.

exposures_cache class-attribute instance-attribute

exposures_cache: dict[str, Any] | None = None

Updated exposures cache.

results_cache class-attribute instance-attribute

results_cache: dict[str, Any] | None = None

Updated results cache.

status class-attribute instance-attribute

status: ExperimentStatus | None = None

Updated status.

global_access_type class-attribute instance-attribute

global_access_type: str | None = None

Updated access type.

mixpanel_data.ExperimentConcludeParams

Bases: BaseModel

Parameters for concluding an experiment.

ATTRIBUTE DESCRIPTION
end_date

Override end date (ISO 8601).

TYPE: str | None

Example
params = ExperimentConcludeParams(end_date="2026-04-01")

end_date class-attribute instance-attribute

end_date: str | None = None

Override end date (ISO 8601).

mixpanel_data.ExperimentDecideParams

Bases: BaseModel

Parameters for recording an experiment decision.

ATTRIBUTE DESCRIPTION
success

Whether the experiment succeeded (required).

TYPE: bool

variant

Winning variant key.

TYPE: str | None

message

Decision summary message.

TYPE: str | None

Example
params = ExperimentDecideParams(success=True, variant="simplified")

success instance-attribute

success: bool

Whether the experiment succeeded (required).

variant class-attribute instance-attribute

variant: str | None = None

Winning variant key.

message class-attribute instance-attribute

message: str | None = None

Decision summary message.

mixpanel_data.DuplicateExperimentParams

Bases: BaseModel

Parameters for duplicating an experiment.

ATTRIBUTE DESCRIPTION
name

Name for the duplicated experiment (required).

TYPE: str

Example
params = DuplicateExperimentParams(name="Checkout Flow Test v2")

name instance-attribute

name: str

Name for the duplicated experiment (required).

Annotation Types

mixpanel_data.Annotation

Bases: BaseModel

Response model for a timeline annotation.

ATTRIBUTE DESCRIPTION
id

Annotation ID.

TYPE: int

project_id

Project ID.

TYPE: int

date

Annotation date (ISO format).

TYPE: str

description

Annotation text.

TYPE: str

user

Creator user info.

TYPE: AnnotationUser | None

tags

Associated tags.

TYPE: list[AnnotationTag]

Example
annotation = Annotation.model_validate(api_response)

id instance-attribute

id: int

Annotation ID.

project_id instance-attribute

project_id: int

Project ID.

date instance-attribute

date: str

Annotation date (%Y-%m-%d %H:%M:%S format).

description instance-attribute

description: str

Annotation text.

user class-attribute instance-attribute

user: AnnotationUser | None = None

Creator user info.

tags class-attribute instance-attribute

tags: list[AnnotationTag] = Field(default_factory=list)

Associated tags.

mixpanel_data.AnnotationUser

Bases: BaseModel

Nested user info for annotation creator.

ATTRIBUTE DESCRIPTION
id

User ID.

TYPE: int

first_name

First name.

TYPE: str

last_name

Last name.

TYPE: str

Example
user = AnnotationUser(id=1, first_name="Alice", last_name="Smith")

id instance-attribute

id: int

User ID.

first_name instance-attribute

first_name: str

First name.

last_name instance-attribute

last_name: str

Last name.

mixpanel_data.AnnotationTag

Bases: BaseModel

Annotation tag for categorization.

ATTRIBUTE DESCRIPTION
id

Tag ID.

TYPE: int

name

Tag name.

TYPE: str

project_id

Project ID.

TYPE: int | None

has_annotations

Whether tag has annotations.

TYPE: bool | None

Example
tag = AnnotationTag(id=1, name="releases")

id instance-attribute

id: int

Tag ID.

name instance-attribute

name: str

Tag name.

project_id class-attribute instance-attribute

project_id: int | None = None

Project ID.

has_annotations class-attribute instance-attribute

has_annotations: bool | None = None

Whether tag has annotations.

mixpanel_data.CreateAnnotationParams

Bases: BaseModel

Parameters for creating a new annotation.

ATTRIBUTE DESCRIPTION
date

Date string in %Y-%m-%d %H:%M:%S format (required).

TYPE: str

description

Annotation text (max 512 characters, required).

TYPE: str

tags

Tag IDs to associate.

TYPE: list[int] | None

user_id

Creator user ID.

TYPE: int | None

Example
params = CreateAnnotationParams(
    date="2026-03-31 00:00:00", description="v2.5 release"
)

date instance-attribute

date: str

Date string in %Y-%m-%d %H:%M:%S format.

description class-attribute instance-attribute

description: str = Field(max_length=512)

Annotation text (max 512 characters).

tags class-attribute instance-attribute

tags: list[int] | None = None

Tag IDs to associate.

user_id class-attribute instance-attribute

user_id: int | None = None

Creator user ID.

mixpanel_data.UpdateAnnotationParams

Bases: BaseModel

Parameters for updating an annotation (PATCH semantics).

Only description and tags can be changed after creation; the annotation date is immutable.

ATTRIBUTE DESCRIPTION
description

New description (max 512 characters).

TYPE: str | None

tags

New tag IDs.

TYPE: list[int] | None

Example
params = UpdateAnnotationParams(description="Updated text")

description class-attribute instance-attribute

description: str | None = Field(default=None, max_length=512)

New description (max 512 characters).

tags class-attribute instance-attribute

tags: list[int] | None = None

New tag IDs.

mixpanel_data.CreateAnnotationTagParams

Bases: BaseModel

Parameters for creating an annotation tag.

ATTRIBUTE DESCRIPTION
name

Tag name (required).

TYPE: str

Example
params = CreateAnnotationTagParams(name="releases")

name instance-attribute

name: str

Tag name.

Webhook Enums

mixpanel_data.WebhookAuthType

Bases: str, Enum

Authentication type for webhooks.

Values

BASIC: HTTP Basic authentication.

Webhook Types

mixpanel_data.ProjectWebhook

Bases: BaseModel

Response model for a project webhook.

ATTRIBUTE DESCRIPTION
id

Webhook ID (UUID string).

TYPE: str

name

Webhook name.

TYPE: str

url

Webhook URL.

TYPE: str

is_enabled

Whether enabled.

TYPE: bool

auth_type

Authentication type.

TYPE: WebhookAuthType | None

created

Creation timestamp.

TYPE: str | None

modified

Last modified timestamp.

TYPE: str | None

creator_id

Creator user ID.

TYPE: int | None

creator_name

Creator name.

TYPE: str | None

Example
webhook = ProjectWebhook.model_validate(api_response)

id instance-attribute

id: str

Webhook ID (UUID string).

name instance-attribute

name: str

Webhook name.

url instance-attribute

url: str

Webhook URL.

is_enabled instance-attribute

is_enabled: bool

Whether enabled.

auth_type class-attribute instance-attribute

auth_type: WebhookAuthType | None = None

Authentication type.

created class-attribute instance-attribute

created: str | None = None

Creation timestamp.

modified class-attribute instance-attribute

modified: str | None = None

Last modified timestamp.

creator_id class-attribute instance-attribute

creator_id: int | None = None

Creator user ID.

creator_name class-attribute instance-attribute

creator_name: str | None = None

Creator name.

mixpanel_data.CreateWebhookParams

Bases: BaseModel

Parameters for creating a webhook.

ATTRIBUTE DESCRIPTION
name

Webhook name (required).

TYPE: str

url

Webhook URL (required).

TYPE: str

auth_type

Auth type ("basic" or None).

TYPE: WebhookAuthType | None

username

Basic auth username.

TYPE: str | None

password

Basic auth password.

TYPE: str | None

Example
params = CreateWebhookParams(
    name="Pipeline webhook",
    url="https://example.com/webhook",
)

name instance-attribute

name: str

Webhook name.

url instance-attribute

url: str

Webhook URL.

auth_type class-attribute instance-attribute

auth_type: WebhookAuthType | None = None

Auth type (e.g. WebhookAuthType.BASIC).

username class-attribute instance-attribute

username: str | None = None

Basic auth username.

password class-attribute instance-attribute

password: str | None = None

Basic auth password.

mixpanel_data.UpdateWebhookParams

Bases: BaseModel

Parameters for updating a webhook (PATCH semantics).

ATTRIBUTE DESCRIPTION
name

New name.

TYPE: str | None

url

New URL.

TYPE: str | None

auth_type

New auth type.

TYPE: WebhookAuthType | None

username

New username.

TYPE: str | None

password

New password.

TYPE: str | None

is_enabled

New enabled state.

TYPE: bool | None

Example
params = UpdateWebhookParams(name="Updated name")

name class-attribute instance-attribute

name: str | None = None

New name.

url class-attribute instance-attribute

url: str | None = None

New URL.

auth_type class-attribute instance-attribute

auth_type: WebhookAuthType | None = None

New auth type.

username class-attribute instance-attribute

username: str | None = None

New username.

password class-attribute instance-attribute

password: str | None = None

New password.

is_enabled class-attribute instance-attribute

is_enabled: bool | None = None

New enabled state.

mixpanel_data.WebhookTestParams

Bases: BaseModel

Parameters for testing webhook connectivity.

ATTRIBUTE DESCRIPTION
url

URL to test (required).

TYPE: str

name

Webhook name.

TYPE: str | None

auth_type

Auth type.

TYPE: WebhookAuthType | None

username

Username for auth.

TYPE: str | None

password

Password for auth.

TYPE: str | None

Example
params = WebhookTestParams(url="https://example.com/webhook")

url instance-attribute

url: str

URL to test.

name class-attribute instance-attribute

name: str | None = None

Webhook name.

auth_type class-attribute instance-attribute

auth_type: WebhookAuthType | None = None

Auth type.

username class-attribute instance-attribute

username: str | None = None

Username for auth.

password class-attribute instance-attribute

password: str | None = None

Password for auth.

mixpanel_data.WebhookTestResult

Bases: BaseModel

Response model for webhook connectivity test.

ATTRIBUTE DESCRIPTION
success

Whether test succeeded.

TYPE: bool

status_code

HTTP status code.

TYPE: int

message

Descriptive message.

TYPE: str

Example
result = WebhookTestResult.model_validate(api_response)
if result.success:
    print("Webhook is reachable")

success instance-attribute

success: bool

Whether test succeeded.

status_code instance-attribute

status_code: int

HTTP status code.

message instance-attribute

message: str

Descriptive message.

mixpanel_data.WebhookMutationResult

Bases: BaseModel

Response model for webhook create/update (returns id + name only).

ATTRIBUTE DESCRIPTION
id

Webhook ID.

TYPE: str

name

Webhook name.

TYPE: str

Example
result = WebhookMutationResult.model_validate(api_response)

id instance-attribute

id: str

Webhook ID.

name instance-attribute

name: str

Webhook name.

Alert Enums

mixpanel_data.AlertFrequencyPreset

Bases: int, Enum

Preset frequency values for alert check intervals.

Values

HOURLY: Check every hour (3600 seconds). DAILY: Check every day (86400 seconds). WEEKLY: Check every week (604800 seconds).

Alert Types

mixpanel_data.CustomAlert

Bases: BaseModel

Response model for a custom alert.

ATTRIBUTE DESCRIPTION
id

Alert ID.

TYPE: int

name

Alert name.

TYPE: str

bookmark

Linked saved report.

TYPE: AlertBookmark | None

condition

Trigger condition (opaque JSON).

TYPE: dict[str, Any]

frequency

Check frequency in seconds.

TYPE: int

paused

Whether alert is paused.

TYPE: bool

subscriptions

Notification targets.

TYPE: list[dict[str, Any]]

notification_windows

Notification window config.

TYPE: dict[str, Any] | None

creator

Creator user info.

TYPE: AlertCreator | None

workspace

Workspace metadata.

TYPE: AlertWorkspace | None

project

Project metadata.

TYPE: AlertProject | None

created

Creation timestamp.

TYPE: str

modified

Last modified timestamp.

TYPE: str

last_checked

Last check timestamp.

TYPE: str | None

last_fired

Last trigger timestamp.

TYPE: str | None

valid

Whether alert is valid.

TYPE: bool

results

Latest evaluation results.

TYPE: dict[str, Any] | None

Example
alert = CustomAlert.model_validate(api_response)

id instance-attribute

id: int

Alert ID.

name instance-attribute

name: str

Alert name.

bookmark class-attribute instance-attribute

bookmark: AlertBookmark | None = None

Linked saved report.

condition class-attribute instance-attribute

condition: dict[str, Any] = Field(default_factory=dict)

Trigger condition (opaque JSON).

frequency class-attribute instance-attribute

frequency: int = 0

Check frequency in seconds.

paused class-attribute instance-attribute

paused: bool = False

Whether alert is paused.

subscriptions class-attribute instance-attribute

subscriptions: list[dict[str, Any]] = Field(default_factory=list)

Notification targets.

notification_windows class-attribute instance-attribute

notification_windows: dict[str, Any] | None = None

Notification window config.

creator class-attribute instance-attribute

creator: AlertCreator | None = None

Creator user info.

workspace class-attribute instance-attribute

workspace: AlertWorkspace | None = None

Workspace metadata.

project class-attribute instance-attribute

project: AlertProject | None = None

Project metadata.

created class-attribute instance-attribute

created: str = ''

Creation timestamp.

modified class-attribute instance-attribute

modified: str = ''

Last modified timestamp.

last_checked class-attribute instance-attribute

last_checked: str | None = None

Last check timestamp.

last_fired class-attribute instance-attribute

last_fired: str | None = None

Last trigger timestamp.

valid class-attribute instance-attribute

valid: bool = True

Whether alert is valid.

results class-attribute instance-attribute

results: dict[str, Any] | None = None

Latest evaluation results.

mixpanel_data.AlertBookmark

Bases: BaseModel

Nested bookmark info for an alert.

ATTRIBUTE DESCRIPTION
id

Bookmark ID.

TYPE: int

name

Bookmark name.

TYPE: str | None

type

Bookmark type.

TYPE: str | None

Example
bookmark = AlertBookmark(id=1, name="Daily Signups")

id instance-attribute

id: int

Bookmark ID.

name class-attribute instance-attribute

name: str | None = None

Bookmark name.

type class-attribute instance-attribute

type: str | None = None

Bookmark type.

mixpanel_data.AlertCreator

Bases: BaseModel

Nested creator info for an alert.

ATTRIBUTE DESCRIPTION
id

User ID.

TYPE: int

first_name

First name.

TYPE: str | None

last_name

Last name.

TYPE: str | None

email

Email.

TYPE: str | None

Example
creator = AlertCreator(id=1, email="alice@example.com")

id instance-attribute

id: int

User ID.

first_name class-attribute instance-attribute

first_name: str | None = None

First name.

last_name class-attribute instance-attribute

last_name: str | None = None

Last name.

email class-attribute instance-attribute

email: str | None = None

Email.

mixpanel_data.AlertWorkspace

Bases: BaseModel

Nested workspace info for an alert.

ATTRIBUTE DESCRIPTION
id

Workspace ID.

TYPE: int

name

Workspace name.

TYPE: str | None

Example
ws = AlertWorkspace(id=100, name="Production")

id instance-attribute

id: int

Workspace ID.

name class-attribute instance-attribute

name: str | None = None

Workspace name.

mixpanel_data.AlertProject

Bases: BaseModel

Nested project info for an alert.

ATTRIBUTE DESCRIPTION
id

Project ID.

TYPE: int

name

Project name.

TYPE: str | None

Example
proj = AlertProject(id=12345, name="My App")

id instance-attribute

id: int

Project ID.

name class-attribute instance-attribute

name: str | None = None

Project name.

mixpanel_data.CreateAlertParams

Bases: BaseModel

Parameters for creating a new alert.

ATTRIBUTE DESCRIPTION
bookmark_id

ID of linked bookmark (required).

TYPE: int

name

Alert name (required).

TYPE: str

condition

Trigger condition JSON (required).

TYPE: dict[str, Any]

frequency

Check frequency in seconds (required).

TYPE: int

paused

Start paused or active (required).

TYPE: bool

subscriptions

Notification targets (required).

TYPE: list[dict[str, Any]]

notification_windows

Notification window config.

TYPE: dict[str, Any] | None

Example
params = CreateAlertParams(
    bookmark_id=12345,
    name="Daily signups drop",
    condition={
        "keys": [{"header": "Signup", "value": "Signup"}],
        "type": "absolute",
        "op": "<",
        "value": 100,
    },
    frequency=AlertFrequencyPreset.DAILY,
    paused=False,
    subscriptions=[{"type": "email", "value": "team@example.com"}],
)

bookmark_id instance-attribute

bookmark_id: int

ID of linked bookmark.

name class-attribute instance-attribute

name: str = Field(max_length=50)

Alert name (max 50 characters).

condition instance-attribute

condition: dict[str, Any]

Trigger condition JSON.

frequency instance-attribute

frequency: int

Check frequency in seconds. See AlertFrequencyPreset for common values.

paused instance-attribute

paused: bool

Start paused or active.

subscriptions instance-attribute

subscriptions: list[dict[str, Any]]

Notification targets.

notification_windows class-attribute instance-attribute

notification_windows: dict[str, Any] | None = None

Notification window config.

mixpanel_data.UpdateAlertParams

Bases: BaseModel

Parameters for updating an alert (PATCH semantics).

ATTRIBUTE DESCRIPTION
name

New name.

TYPE: str | None

bookmark_id

New bookmark ID.

TYPE: int | None

condition

New condition.

TYPE: dict[str, Any] | None

frequency

New frequency.

TYPE: int | None

paused

New pause state.

TYPE: bool | None

subscriptions

New subscriptions.

TYPE: list[dict[str, Any]] | None

notification_windows

New notification windows.

TYPE: dict[str, Any] | None

Example
params = UpdateAlertParams(name="Updated alert", paused=True)

name class-attribute instance-attribute

name: str | None = None

New name.

bookmark_id class-attribute instance-attribute

bookmark_id: int | None = None

New bookmark ID.

condition class-attribute instance-attribute

condition: dict[str, Any] | None = None

New condition.

frequency class-attribute instance-attribute

frequency: int | None = None

New frequency.

paused class-attribute instance-attribute

paused: bool | None = None

New pause state.

subscriptions class-attribute instance-attribute

subscriptions: list[dict[str, Any]] | None = None

New subscriptions.

notification_windows class-attribute instance-attribute

notification_windows: dict[str, Any] | None = None

New notification windows.

mixpanel_data.AlertCount

Bases: BaseModel

Response model for alert count and limits.

ATTRIBUTE DESCRIPTION
anomaly_alerts_count

Current alert count.

TYPE: int

alert_limit

Account limit.

TYPE: int

is_below_limit

Whether below limit.

TYPE: bool

Example
count = AlertCount.model_validate(api_response)
if count.is_below_limit:
    print(f"{count.anomaly_alerts_count}/{count.alert_limit}")

anomaly_alerts_count instance-attribute

anomaly_alerts_count: int

Current alert count.

alert_limit instance-attribute

alert_limit: int

Account limit.

is_below_limit instance-attribute

is_below_limit: bool

Whether below limit.

mixpanel_data.AlertHistoryPagination

Bases: BaseModel

Pagination metadata for alert history.

ATTRIBUTE DESCRIPTION
next_cursor

Next page cursor.

TYPE: str | None

previous_cursor

Previous page cursor.

TYPE: str | None

page_size

Page size.

TYPE: int

Example
pagination = AlertHistoryPagination(page_size=20)

next_cursor class-attribute instance-attribute

next_cursor: str | None = None

Next page cursor.

previous_cursor class-attribute instance-attribute

previous_cursor: str | None = None

Previous page cursor.

page_size class-attribute instance-attribute

page_size: int = 20

Page size.

mixpanel_data.AlertHistoryResponse

Bases: BaseModel

Response model for alert history (paginated).

ATTRIBUTE DESCRIPTION
results

History entries.

TYPE: list[dict[str, Any]]

pagination

Pagination metadata.

TYPE: AlertHistoryPagination | None

Example
history = AlertHistoryResponse.model_validate(api_response)
for entry in history.results:
    print(entry)

results class-attribute instance-attribute

results: list[dict[str, Any]] = Field(default_factory=list)

History entries.

pagination class-attribute instance-attribute

pagination: AlertHistoryPagination | None = None

Pagination metadata.

mixpanel_data.AlertScreenshotResponse

Bases: BaseModel

Response model for alert screenshot URL.

ATTRIBUTE DESCRIPTION
signed_url

Signed GCS URL for screenshot.

TYPE: str

Example
resp = AlertScreenshotResponse.model_validate(api_response)
print(resp.signed_url)

signed_url instance-attribute

signed_url: str

Signed GCS URL for screenshot.

mixpanel_data.AlertValidation

Bases: BaseModel

Per-alert validation result.

ATTRIBUTE DESCRIPTION
alert_id

Alert ID.

TYPE: int

alert_name

Alert name.

TYPE: str

valid

Whether valid.

TYPE: bool

reason

Reason if invalid.

TYPE: str | None

Example
v = AlertValidation(alert_id=1, alert_name="Test", valid=True)

alert_id instance-attribute

alert_id: int

Alert ID.

alert_name instance-attribute

alert_name: str

Alert name.

valid instance-attribute

valid: bool

Whether valid.

reason class-attribute instance-attribute

reason: str | None = None

Reason if invalid.

mixpanel_data.ValidateAlertsForBookmarkParams

Bases: BaseModel

Parameters for validating alerts against a bookmark.

ATTRIBUTE DESCRIPTION
alert_ids

Alert IDs to validate (required).

TYPE: list[int]

bookmark_type

Bookmark type to validate against (required).

TYPE: Literal['insights', 'funnels']

bookmark_params

Bookmark params JSON (required).

TYPE: dict[str, Any]

Example
params = ValidateAlertsForBookmarkParams(
    alert_ids=[1, 2],
    bookmark_type="insights",
    bookmark_params={"event": "Signup"},
)

alert_ids class-attribute instance-attribute

alert_ids: list[int] = Field(min_length=1)

Alert IDs to validate (must not be empty).

bookmark_type instance-attribute

bookmark_type: Literal['insights', 'funnels']

Bookmark type to validate against.

bookmark_params instance-attribute

bookmark_params: dict[str, Any]

Bookmark params JSON.

mixpanel_data.ValidateAlertsForBookmarkResponse

Bases: BaseModel

Response model for alert-bookmark validation.

ATTRIBUTE DESCRIPTION
alert_validations

Per-alert validation results.

TYPE: list[AlertValidation]

invalid_count

Count of invalid alerts.

TYPE: int

Example
resp = ValidateAlertsForBookmarkResponse.model_validate(api_response)
if resp.invalid_count > 0:
    for v in resp.alert_validations:
        if not v.valid:
            print(f"{v.alert_name}: {v.reason}")

alert_validations class-attribute instance-attribute

alert_validations: list[AlertValidation] = Field(default_factory=list)

Per-alert validation results.

invalid_count class-attribute instance-attribute

invalid_count: int = 0

Count of invalid alerts.

Data Governance Enums

mixpanel_data.PropertyResourceType

Bases: str, Enum

Resource type for property definitions.

Values

EVENT: Event property. USER: User profile property. GROUPPROFILE: Group profile property (wire format: groupprofile).

mixpanel_data.CustomPropertyResourceType

Bases: str, Enum

Resource type for custom properties.

Values

EVENTS: Event-level custom property. PEOPLE: User profile custom property. GROUP_PROFILES: Group profile custom property.

Event Definition Types

mixpanel_data.EventDefinition

Bases: BaseModel

A Mixpanel event definition from the Lexicon.

ATTRIBUTE DESCRIPTION
id

Server-assigned event ID.

TYPE: int

name

Event name (unique identifier).

TYPE: str

display_name

Human-readable name.

TYPE: str | None

description

Event description.

TYPE: str | None

hidden

Whether hidden from UI.

TYPE: bool | None

dropped

Whether data is dropped at ingestion.

TYPE: bool | None

merged

Whether merged into another event.

TYPE: bool | None

verified

Whether verified by governance team.

TYPE: bool | None

tags

Assigned tag names.

TYPE: list[str] | None

custom_event_id

Links to custom event.

TYPE: int | None

last_modified

ISO 8601 timestamp.

TYPE: str | None

status

Event status.

TYPE: str | None

platforms

Tracking platforms.

TYPE: list[str] | None

created_utc

ISO 8601 creation timestamp.

TYPE: str | None

modified_utc

ISO 8601 modification timestamp.

TYPE: str | None

Example
ev = EventDefinition(id=1, name="Purchase")

id instance-attribute

id: int

Server-assigned event ID.

name instance-attribute

name: str

Event name (unique identifier).

display_name class-attribute instance-attribute

display_name: str | None = None

Human-readable name.

description class-attribute instance-attribute

description: str | None = None

Event description.

hidden class-attribute instance-attribute

hidden: bool | None = None

Whether hidden from UI.

dropped class-attribute instance-attribute

dropped: bool | None = None

Whether data is dropped at ingestion.

merged class-attribute instance-attribute

merged: bool | None = None

Whether merged into another event.

verified class-attribute instance-attribute

verified: bool | None = None

Whether verified by governance team.

tags class-attribute instance-attribute

tags: list[str] | None = None

Assigned tag names.

custom_event_id class-attribute instance-attribute

custom_event_id: int | None = None

Links to custom event.

last_modified class-attribute instance-attribute

last_modified: str | None = None

ISO 8601 timestamp.

status class-attribute instance-attribute

status: str | None = None

Event status.

platforms class-attribute instance-attribute

platforms: list[str] | None = None

Tracking platforms.

created_utc class-attribute instance-attribute

created_utc: str | None = None

ISO 8601 creation timestamp.

modified_utc class-attribute instance-attribute

modified_utc: str | None = None

ISO 8601 modification timestamp.

mixpanel_data.UpdateEventDefinitionParams

Bases: BaseModel

Parameters for updating an event definition (PATCH semantics).

All fields are optional; only set fields are sent.

ATTRIBUTE DESCRIPTION
hidden

Whether hidden from UI.

TYPE: bool | None

dropped

Whether data is dropped.

TYPE: bool | None

merged

Whether merged.

TYPE: bool | None

verified

Whether verified.

TYPE: bool | None

tags

Tag names to assign.

TYPE: list[str] | None

description

Event description.

TYPE: str | None

Example
params = UpdateEventDefinitionParams(
    description="User completed a purchase", verified=True
)

hidden class-attribute instance-attribute

hidden: bool | None = None

Whether hidden from UI.

dropped class-attribute instance-attribute

dropped: bool | None = None

Whether data is dropped.

merged class-attribute instance-attribute

merged: bool | None = None

Whether merged.

verified class-attribute instance-attribute

verified: bool | None = None

Whether verified.

tags class-attribute instance-attribute

tags: list[str] | None = None

Tag names to assign.

description class-attribute instance-attribute

description: str | None = None

Event description.

mixpanel_data.BulkEventUpdate

Bases: BaseModel

A single event update entry for bulk operations.

ATTRIBUTE DESCRIPTION
name

Event name (identifier).

TYPE: str | None

id

Alternative identifier.

TYPE: int | None

hidden

Whether hidden from UI.

TYPE: bool | None

dropped

Whether data is dropped.

TYPE: bool | None

merged

Whether merged.

TYPE: bool | None

verified

Whether verified.

TYPE: bool | None

tags

Tag names.

TYPE: list[str] | None

contacts

Contact emails.

TYPE: list[str] | None

team_contacts

Team contact emails.

TYPE: list[str] | None

Example
entry = BulkEventUpdate(name="OldEvent", hidden=True)

name class-attribute instance-attribute

name: str | None = None

Event name (identifier).

id class-attribute instance-attribute

id: int | None = None

Alternative identifier.

hidden class-attribute instance-attribute

hidden: bool | None = None

Whether hidden from UI.

dropped class-attribute instance-attribute

dropped: bool | None = None

Whether data is dropped.

merged class-attribute instance-attribute

merged: bool | None = None

Whether merged.

verified class-attribute instance-attribute

verified: bool | None = None

Whether verified.

tags class-attribute instance-attribute

tags: list[str] | None = None

Tag names.

contacts class-attribute instance-attribute

contacts: list[str] | None = None

Contact emails.

team_contacts class-attribute instance-attribute

team_contacts: list[str] | None = None

Team contact emails.

mixpanel_data.BulkUpdateEventsParams

Bases: BaseModel

Parameters for bulk-updating event definitions.

ATTRIBUTE DESCRIPTION
events

List of event update entries (required).

TYPE: list[BulkEventUpdate]

Example
params = BulkUpdateEventsParams(
    events=[BulkEventUpdate(name="E1", hidden=True)]
)

events instance-attribute

events: list[BulkEventUpdate]

List of event update entries.

Property Definition Types

mixpanel_data.PropertyDefinition

Bases: BaseModel

A Mixpanel property definition from the Lexicon.

ATTRIBUTE DESCRIPTION
id

Server-assigned property ID.

TYPE: int | None

name

Property name.

TYPE: str

resource_type

Property resource type (event, user, groupprofile).

TYPE: str | None

description

Property description.

TYPE: str | None

hidden

Whether hidden from UI.

TYPE: bool | None

dropped

Whether data is dropped.

TYPE: bool | None

merged

Whether merged into another property.

TYPE: bool | None

sensitive

PII flag.

TYPE: bool | None

data_group_id

Data group identifier.

TYPE: str | None

Example
prop = PropertyDefinition(id=1, name="$browser")

id class-attribute instance-attribute

id: int | None = None

Server-assigned property ID (may be absent for custom properties).

name instance-attribute

name: str

Property name.

resource_type class-attribute instance-attribute

resource_type: str | None = None

Property resource type (event, user, groupprofile).

description class-attribute instance-attribute

description: str | None = None

Property description.

hidden class-attribute instance-attribute

hidden: bool | None = None

Whether hidden from UI.

dropped class-attribute instance-attribute

dropped: bool | None = None

Whether data is dropped.

merged class-attribute instance-attribute

merged: bool | None = None

Whether merged into another property.

sensitive class-attribute instance-attribute

sensitive: bool | None = None

PII flag.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

mixpanel_data.UpdatePropertyDefinitionParams

Bases: BaseModel

Parameters for updating a property definition (PATCH semantics).

All fields are optional; only set fields are sent.

ATTRIBUTE DESCRIPTION
hidden

Whether hidden from UI.

TYPE: bool | None

dropped

Whether data is dropped.

TYPE: bool | None

merged

Whether merged.

TYPE: bool | None

sensitive

PII flag.

TYPE: bool | None

description

Property description.

TYPE: str | None

Example
params = UpdatePropertyDefinitionParams(sensitive=True)

hidden class-attribute instance-attribute

hidden: bool | None = None

Whether hidden from UI.

dropped class-attribute instance-attribute

dropped: bool | None = None

Whether data is dropped.

merged class-attribute instance-attribute

merged: bool | None = None

Whether merged.

sensitive class-attribute instance-attribute

sensitive: bool | None = None

PII flag.

description class-attribute instance-attribute

description: str | None = None

Property description.

mixpanel_data.BulkPropertyUpdate

Bases: BaseModel

A single property update entry for bulk operations.

Uses camelCase serialization to match the Django API contract.

ATTRIBUTE DESCRIPTION
name

Property name (required).

TYPE: str

resource_type

Resource type (required).

TYPE: str

id

Property ID.

TYPE: int | None

hidden

Whether hidden from UI.

TYPE: bool | None

dropped

Whether data is dropped.

TYPE: bool | None

sensitive

PII flag.

TYPE: bool | None

data_group_id

Data group identifier.

TYPE: str | None

Example
entry = BulkPropertyUpdate(name="$browser", resource_type="event")

name instance-attribute

name: str

Property name.

resource_type instance-attribute

resource_type: str

Resource type (event, user, groupprofile).

id class-attribute instance-attribute

id: int | None = None

Property ID.

hidden class-attribute instance-attribute

hidden: bool | None = None

Whether hidden from UI.

dropped class-attribute instance-attribute

dropped: bool | None = None

Whether data is dropped.

sensitive class-attribute instance-attribute

sensitive: bool | None = None

PII flag.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

mixpanel_data.BulkUpdatePropertiesParams

Bases: BaseModel

Parameters for bulk-updating property definitions.

ATTRIBUTE DESCRIPTION
properties

List of property update entries (required).

TYPE: list[BulkPropertyUpdate]

Example
params = BulkUpdatePropertiesParams(
    properties=[BulkPropertyUpdate(name="$browser", resource_type="event")]
)

properties instance-attribute

properties: list[BulkPropertyUpdate]

List of property update entries.

Lexicon Tag Types

mixpanel_data.LexiconTag

Bases: BaseModel

A Lexicon tag for categorizing event/property definitions.

ATTRIBUTE DESCRIPTION
id

Server-assigned tag ID.

TYPE: int

name

Tag name.

TYPE: str

Example
tag = LexiconTag(id=1, name="core-metrics")

id instance-attribute

id: int

Server-assigned tag ID.

name instance-attribute

name: str

Tag name.

mixpanel_data.CreateTagParams

Bases: BaseModel

Parameters for creating a Lexicon tag.

ATTRIBUTE DESCRIPTION
name

Tag name (required, non-empty).

TYPE: str

Example
params = CreateTagParams(name="core-metrics")

name instance-attribute

name: str

Tag name.

mixpanel_data.UpdateTagParams

Bases: BaseModel

Parameters for updating a Lexicon tag.

ATTRIBUTE DESCRIPTION
name

New tag name.

TYPE: str | None

Example
params = UpdateTagParams(name="key-metrics")

name class-attribute instance-attribute

name: str | None = None

New tag name.

Drop Filter Types

mixpanel_data.DropFilter

Bases: BaseModel

A drop filter for discarding events at ingestion.

ATTRIBUTE DESCRIPTION
id

Server-assigned filter ID.

TYPE: int

event_name

Event name to filter.

TYPE: str

filters

Filter condition JSON.

TYPE: list[Any] | None

active

Whether the filter is active.

TYPE: bool | None

display_name

Human-readable name.

TYPE: str | None

created

ISO 8601 creation timestamp.

TYPE: str | None

Example
df = DropFilter(id=1, event_name="debug_log")

id instance-attribute

id: int

Server-assigned filter ID.

event_name instance-attribute

event_name: str

Event name to filter.

filters class-attribute instance-attribute

filters: list[Any] | None = None

Filter condition JSON.

active class-attribute instance-attribute

active: bool | None = None

Whether the filter is active.

display_name class-attribute instance-attribute

display_name: str | None = None

Human-readable name.

created class-attribute instance-attribute

created: str | None = None

ISO 8601 creation timestamp.

mixpanel_data.CreateDropFilterParams

Bases: BaseModel

Parameters for creating a drop filter.

ATTRIBUTE DESCRIPTION
event_name

Event name to filter (required).

TYPE: str

filters

Filter condition JSON (required).

TYPE: Any

Example
params = CreateDropFilterParams(
    event_name="debug_log",
    filters={"property": "env", "operator": "equals", "value": "test"},
)

event_name instance-attribute

event_name: str

Event name to filter.

filters instance-attribute

filters: Any

Filter condition JSON.

mixpanel_data.UpdateDropFilterParams

Bases: BaseModel

Parameters for updating a drop filter.

ATTRIBUTE DESCRIPTION
id

Drop filter ID (required).

TYPE: int

event_name

New event name.

TYPE: str | None

filters

New filter condition JSON.

TYPE: Any | None

active

Whether the filter is active.

TYPE: bool | None

Example
params = UpdateDropFilterParams(id=123, active=False)

id instance-attribute

id: int

Drop filter ID.

event_name class-attribute instance-attribute

event_name: str | None = None

New event name.

filters class-attribute instance-attribute

filters: Any | None = None

New filter condition JSON.

active class-attribute instance-attribute

active: bool | None = None

Whether the filter is active.

mixpanel_data.DropFilterLimitsResponse

Bases: BaseModel

Response model for drop filter limits.

ATTRIBUTE DESCRIPTION
filter_limit

Maximum allowed filters.

TYPE: int

Example
limits = DropFilterLimitsResponse(filter_limit=10)

filter_limit instance-attribute

filter_limit: int

Maximum allowed filters.

Custom Property Types

mixpanel_data.ComposedPropertyValue

Bases: BaseModel

A composed property reference within a custom property formula.

ATTRIBUTE DESCRIPTION
type

Property type.

TYPE: str | None

type_cast

Type cast instruction.

TYPE: str | None

resource_type

Resource type (required).

TYPE: str

behavior

Behavior specification.

TYPE: Any | None

join_property_type

Join property type.

TYPE: str | None

Example
cpv = ComposedPropertyValue(resource_type="event")

type class-attribute instance-attribute

type: str | None = None

Property type.

type_cast class-attribute instance-attribute

type_cast: str | None = None

Type cast instruction.

resource_type instance-attribute

resource_type: str

Resource type. Uses singular form (event, user, groupprofile) from the Mixpanel API composed property schema — distinct from CustomPropertyResourceType which uses plural form.

value class-attribute instance-attribute

value: str | None = None

Property name in the project (e.g. "deal_name").

label class-attribute instance-attribute

label: str | None = None

Human-readable label for the property (e.g. "Deal Name").

property_default_type class-attribute instance-attribute

property_default_type: CustomPropertyType | None = None

Default property type hint (e.g. "string", "number").

behavior class-attribute instance-attribute

behavior: Any | None = None

Behavior specification.

join_property_type class-attribute instance-attribute

join_property_type: str | None = None

Join property type.

mixpanel_data.CustomProperty

Bases: BaseModel

A Mixpanel custom property (computed/formula property).

ATTRIBUTE DESCRIPTION
custom_property_id

Server-assigned property ID.

TYPE: int

name

Property name.

TYPE: str

description

Property description.

TYPE: str | None

resource_type

Resource type (events, people, group_profiles).

TYPE: CustomPropertyResourceType

property_type

Property type.

TYPE: str | None

display_formula

Formula expression.

TYPE: str | None

composed_properties

Referenced properties in formula.

TYPE: dict[str, ComposedPropertyValue] | None

is_locked

Whether the property is locked.

TYPE: bool | None

is_visible

Whether the property is visible.

TYPE: bool | None

data_group_id

Data group identifier.

TYPE: str | None

created

ISO 8601 creation timestamp.

TYPE: str | None

modified

ISO 8601 modification timestamp.

TYPE: str | None

example_value

Example value.

TYPE: str | None

Example
cp = CustomProperty(
    custom_property_id=1, name="Revenue", resource_type="events"
)

custom_property_id instance-attribute

custom_property_id: int

Server-assigned property ID.

name instance-attribute

name: str

Property name.

description class-attribute instance-attribute

description: str | None = None

Property description.

resource_type instance-attribute

resource_type: CustomPropertyResourceType

Resource type (events, people, group_profiles).

property_type class-attribute instance-attribute

property_type: str | None = None

Property type.

display_formula class-attribute instance-attribute

display_formula: str | None = None

Formula expression.

composed_properties class-attribute instance-attribute

composed_properties: dict[str, ComposedPropertyValue] | None = None

Referenced properties in formula.

is_locked class-attribute instance-attribute

is_locked: bool | None = None

Whether the property is locked.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

Whether the property is visible.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

created class-attribute instance-attribute

created: str | None = None

ISO 8601 creation timestamp.

modified class-attribute instance-attribute

modified: str | None = None

ISO 8601 modification timestamp.

example_value class-attribute instance-attribute

example_value: str | None = None

Example value.

mixpanel_data.CreateCustomPropertyParams

Bases: BaseModel

Parameters for creating a custom property.

Validation rules: - display_formula and behavior are mutually exclusive. - behavior and composed_properties are mutually exclusive. - display_formula requires composed_properties. - One of display_formula or behavior must be set.

ATTRIBUTE DESCRIPTION
name

Property name (required).

TYPE: str

resource_type

Resource type (required).

TYPE: CustomPropertyResourceType

description

Property description.

TYPE: str | None

display_formula

Formula expression (mutually exclusive with behavior).

TYPE: str | None

composed_properties

Referenced properties (required if display_formula set).

TYPE: dict[str, ComposedPropertyValue] | None

is_locked

Whether the property is locked.

TYPE: bool | None

is_visible

Whether the property is visible.

TYPE: bool | None

data_group_id

Data group identifier.

TYPE: str | None

behavior

Behavior specification (mutually exclusive with display_formula).

TYPE: Any | None

Example
params = CreateCustomPropertyParams(
    name="Revenue Per User",
    resource_type="events",
    display_formula='number(properties["amount"])',
    composed_properties={"amount": ComposedPropertyValue(resource_type="event")},
)

name instance-attribute

name: str

Property name.

resource_type instance-attribute

resource_type: CustomPropertyResourceType

Resource type (events, people, group_profiles).

description class-attribute instance-attribute

description: str | None = None

Property description.

display_formula class-attribute instance-attribute

display_formula: str | None = None

Formula expression (mutually exclusive with behavior).

composed_properties class-attribute instance-attribute

composed_properties: dict[str, ComposedPropertyValue] | None = None

Referenced properties (required if display_formula set).

is_locked class-attribute instance-attribute

is_locked: bool | None = None

Whether the property is locked.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

Whether the property is visible.

property_type class-attribute instance-attribute

property_type: CustomPropertyType | None = None

Output type of the custom property (string, number, boolean, datetime). Auto-inferred by the API from the formula if not set.

example_value class-attribute instance-attribute

example_value: str | None = None

Example output value for documentation purposes.

data_group_id class-attribute instance-attribute

data_group_id: str | None = None

Data group identifier.

behavior class-attribute instance-attribute

behavior: Any | None = None

Behavior specification (mutually exclusive with display_formula).

mixpanel_data.UpdateCustomPropertyParams

Bases: BaseModel

Parameters for updating a custom property (PUT — full replacement).

Note: resource_type and data_group_id are immutable.

ATTRIBUTE DESCRIPTION
name

Property name.

TYPE: str | None

description

Property description.

TYPE: str | None

display_formula

Formula expression.

TYPE: str | None

composed_properties

Referenced properties.

TYPE: dict[str, ComposedPropertyValue] | None

is_locked

Whether the property is locked.

TYPE: bool | None

is_visible

Whether the property is visible.

TYPE: bool | None

Example
params = UpdateCustomPropertyParams(name="Updated Name")

name class-attribute instance-attribute

name: str | None = None

Property name.

description class-attribute instance-attribute

description: str | None = None

Property description.

display_formula class-attribute instance-attribute

display_formula: str | None = None

Formula expression.

composed_properties class-attribute instance-attribute

composed_properties: dict[str, ComposedPropertyValue] | None = None

Referenced properties.

is_locked class-attribute instance-attribute

is_locked: bool | None = None

Whether the property is locked.

is_visible class-attribute instance-attribute

is_visible: bool | None = None

Whether the property is visible.

Lookup Table Types

mixpanel_data.LookupTable

Bases: BaseModel

A Mixpanel lookup table.

ATTRIBUTE DESCRIPTION
id

Server-assigned table ID.

TYPE: int

name

Table name.

TYPE: str

token

Table token.

TYPE: str | None

created_at

ISO 8601 creation timestamp.

TYPE: str | None

last_modified_at

ISO 8601 modification timestamp.

TYPE: str | None

has_mapped_properties

Whether the table has mapped properties.

TYPE: bool | None

Example
lt = LookupTable(id=1, name="Product Catalog")

id instance-attribute

id: int

Server-assigned table ID.

name instance-attribute

name: str

Table name.

token class-attribute instance-attribute

token: str | None = None

Table token.

created_at class-attribute instance-attribute

created_at: str | None = None

ISO 8601 creation timestamp.

last_modified_at class-attribute instance-attribute

last_modified_at: str | None = None

ISO 8601 modification timestamp.

has_mapped_properties class-attribute instance-attribute

has_mapped_properties: bool | None = None

Whether the table has mapped properties.

mixpanel_data.UploadLookupTableParams

Bases: BaseModel

Parameters for uploading a lookup table CSV.

The upload is a 3-step process handled by the workspace method: 1. Get a signed upload URL 2. Upload CSV to signed URL 3. Register the table

ATTRIBUTE DESCRIPTION
name

Table name (1-255 characters, required).

TYPE: str

file_path

Path to local CSV file (required).

TYPE: str

data_group_id

For replacing an existing table.

TYPE: int | None

Example
params = UploadLookupTableParams(
    name="Product Catalog", file_path="/path/to/products.csv"
)

name class-attribute instance-attribute

name: str = Field(min_length=1, max_length=255)

Table name (1-255 characters).

file_path instance-attribute

file_path: str

Path to local CSV file.

data_group_id class-attribute instance-attribute

data_group_id: int | None = None

For replacing an existing table.

mixpanel_data.MarkLookupTableReadyParams

Bases: BaseModel

Parameters for marking a lookup table as ready.

ATTRIBUTE DESCRIPTION
name

Table name (required).

TYPE: str

key

Primary key column name (required).

TYPE: str

data_group_id

For replacing an existing table.

TYPE: int | None

Example
params = MarkLookupTableReadyParams(name="Products", key="product_id")

name instance-attribute

name: str

Table name.

key instance-attribute

key: str

Primary key column name.

data_group_id class-attribute instance-attribute

data_group_id: int | None = None

For replacing an existing table.

mixpanel_data.LookupTableUploadUrl

Bases: BaseModel

Response model for lookup table upload URL request.

ATTRIBUTE DESCRIPTION
url

Signed GCS upload URL.

TYPE: str

path

GCS path for registration.

TYPE: str

key

Primary key column name.

TYPE: str

Example
upload = LookupTableUploadUrl(
    url="https://storage.googleapis.com/...",
    path="gs://bucket/path",
    key="id",
)

url instance-attribute

url: str

Signed GCS upload URL.

path instance-attribute

path: str

GCS path for registration.

key instance-attribute

key: str

Primary key column name.

mixpanel_data.UpdateLookupTableParams

Bases: BaseModel

Parameters for updating a lookup table.

ATTRIBUTE DESCRIPTION
name

New table name.

TYPE: str | None

Example
params = UpdateLookupTableParams(name="Updated Catalog")

name class-attribute instance-attribute

name: str | None = None

New table name.

Schema Registry Types

Types for managing JSON Schema Draft 7 definitions in the schema registry.

mixpanel_data.SchemaEntry

Bases: BaseModel

A schema registry entry for an event, custom event, or profile.

Represents a JSON Schema Draft 7 definition registered in the Mixpanel schema registry. Used for both API responses and as entries in bulk create/update operations.

ATTRIBUTE DESCRIPTION
entity_type

Entity type ("event", "custom_event", "profile").

TYPE: str

name

Entity name (event name or "$user" for profile).

TYPE: str

version

Schema version in YYYY-MM-DD format.

TYPE: str | None

schema_definition

JSON Schema Draft 7 definition (API field: schemaJson).

TYPE: dict[str, Any]

Example
entry = SchemaEntry(
    entity_type="event",
    name="Purchase",
    schema_definition={"properties": {"amount": {"type": "number"}}},
)
# Or using the API alias:
entry = SchemaEntry(
    entityType="event", name="Purchase",
    schemaJson={"properties": {"amount": {"type": "number"}}},
)

entity_type instance-attribute

entity_type: str

Entity type: "event", "custom_event", or "profile".

name instance-attribute

name: str

Entity name (event name or "$user" for profile).

version class-attribute instance-attribute

version: str | None = None

Schema version in YYYY-MM-DD format.

schema_definition class-attribute instance-attribute

schema_definition: dict[str, Any] = Field(alias='schemaJson')

JSON Schema Draft 7 definition (API field: schemaJson).

mixpanel_data.BulkCreateSchemasParams

Bases: BaseModel

Parameters for bulk-creating schemas in the registry.

ATTRIBUTE DESCRIPTION
entries

Schema entries to create.

TYPE: list[SchemaEntry]

truncate

If true, delete all existing schemas of entity_type before inserting.

TYPE: bool | None

entity_type

Entity type for all entries (only "event" supported for batch operations).

TYPE: str | None

Example
params = BulkCreateSchemasParams(
    entries=[
        SchemaEntry(name="Login", entity_type="event", schema_definition={...}),
    ],
    truncate=True,
    entity_type="event",
)

entries instance-attribute

entries: list[SchemaEntry]

Schema entries to create.

truncate class-attribute instance-attribute

truncate: bool | None = None

If true, delete all existing schemas of entity_type before inserting.

entity_type class-attribute instance-attribute

entity_type: str | None = None

Entity type for all entries (only "event" supported for batch).

mixpanel_data.BulkCreateSchemasResponse

Bases: BaseModel

Response from a bulk schema creation operation.

ATTRIBUTE DESCRIPTION
added

Number of schemas added.

TYPE: int

deleted

Number of schemas deleted (from truncate).

TYPE: int

Example
resp = BulkCreateSchemasResponse(added=5, deleted=3)

added instance-attribute

added: int

Number of schemas added.

deleted instance-attribute

deleted: int

Number of schemas deleted (from truncate).

mixpanel_data.BulkPatchResult

Bases: BaseModel

Per-entry result from a bulk schema update operation.

ATTRIBUTE DESCRIPTION
entity_type

Entity type processed.

TYPE: str

name

Entity name processed.

TYPE: str

status

Result status ("ok" or "error").

TYPE: str

error

Error message if status is "error".

TYPE: str | None

Example
result = BulkPatchResult(
    entity_type="event", name="Login", status="ok"
)

entity_type instance-attribute

entity_type: str

Entity type processed.

name instance-attribute

name: str

Entity name processed.

status instance-attribute

status: str

Result status ("ok" or "error").

error class-attribute instance-attribute

error: str | None = None

Error message if status is "error".

mixpanel_data.DeleteSchemasResponse

Bases: BaseModel

Response from a schema deletion operation.

ATTRIBUTE DESCRIPTION
delete_count

Number of schemas deleted.

TYPE: int

Example
resp = DeleteSchemasResponse(delete_count=3)

delete_count instance-attribute

delete_count: int

Number of schemas deleted.

Schema Enforcement Types

Types for configuring schema enforcement policies.

mixpanel_data.SchemaEnforcementConfig

Bases: BaseModel

Schema enforcement configuration for a project.

Controls how Mixpanel handles events that don't match defined schemas.

ATTRIBUTE DESCRIPTION
id

Config ID.

TYPE: int | None

last_modified

Last modification timestamp.

TYPE: str | None

last_modified_by

User who last modified.

TYPE: dict[str, Any] | None

rule_event

Enforcement action ("Warn and Accept", "Warn and Hide", "Warn and Drop").

TYPE: str | None

notification_emails

Notification recipients.

TYPE: list[str] | None

events

Event enforcement rules.

TYPE: list[dict[str, Any]] | None

common_properties

Common property rules.

TYPE: list[dict[str, Any]] | None

user_properties

User property rules.

TYPE: list[dict[str, Any]] | None

initialized_by

User who initialized.

TYPE: dict[str, Any] | None

initialized_from

Initialization start date.

TYPE: str | None

initialized_to

Initialization end date.

TYPE: str | None

state

Enforcement state ("planned" or "ingested").

TYPE: str | None

Example
config = SchemaEnforcementConfig(
    id=1, rule_event="Warn and Accept", state="ingested"
)

id class-attribute instance-attribute

id: int | None = None

Config ID.

last_modified class-attribute instance-attribute

last_modified: str | None = None

Last modification timestamp.

last_modified_by class-attribute instance-attribute

last_modified_by: dict[str, Any] | None = None

User who last modified.

rule_event class-attribute instance-attribute

rule_event: str | None = None

Enforcement action: "Warn and Accept", "Warn and Hide", "Warn and Drop".

notification_emails class-attribute instance-attribute

notification_emails: list[str] | None = None

Notification recipients.

events class-attribute instance-attribute

events: list[dict[str, Any]] | None = None

Event enforcement rules.

common_properties class-attribute instance-attribute

common_properties: list[dict[str, Any]] | None = None

Common property rules.

user_properties class-attribute instance-attribute

user_properties: list[dict[str, Any]] | None = None

User property rules.

initialized_by class-attribute instance-attribute

initialized_by: dict[str, Any] | None = None

User who initialized.

initialized_from class-attribute instance-attribute

initialized_from: str | None = None

Initialization start date.

initialized_to class-attribute instance-attribute

initialized_to: str | None = None

Initialization end date.

state class-attribute instance-attribute

state: str | None = None

Enforcement state ("planned" or "ingested").

mixpanel_data.InitSchemaEnforcementParams

Bases: BaseModel

Parameters for initializing schema enforcement.

ATTRIBUTE DESCRIPTION
rule_event

Enforcement action ("Warn and Accept", "Warn and Hide", "Warn and Drop").

TYPE: str

Example
params = InitSchemaEnforcementParams(rule_event="Warn and Accept")

rule_event instance-attribute

rule_event: str

Enforcement action.

mixpanel_data.UpdateSchemaEnforcementParams

Bases: BaseModel

Parameters for partially updating schema enforcement.

ATTRIBUTE DESCRIPTION
notification_emails

Updated notification recipients.

TYPE: list[str] | None

rule_event

Updated enforcement action.

TYPE: str | None

events

Updated event list.

TYPE: list[str] | None

properties

Updated property map.

TYPE: dict[str, list[str]] | None

Example
params = UpdateSchemaEnforcementParams(
    rule_event="Warn and Drop",
    notification_emails=["data-team@example.com"],
)

notification_emails class-attribute instance-attribute

notification_emails: list[str] | None = None

Updated notification recipients.

rule_event class-attribute instance-attribute

rule_event: str | None = None

Updated enforcement action.

events class-attribute instance-attribute

events: list[str] | None = None

Updated event list.

properties class-attribute instance-attribute

properties: dict[str, list[str]] | None = None

Updated property map.

mixpanel_data.ReplaceSchemaEnforcementParams

Bases: BaseModel

Parameters for fully replacing schema enforcement configuration.

All fields are required since this is a full replacement.

ATTRIBUTE DESCRIPTION
common_properties

Full common property rules.

TYPE: list[dict[str, Any]]

user_properties

Full user property rules.

TYPE: list[dict[str, Any]]

events

Full event rules.

TYPE: list[dict[str, Any]]

rule_event

Enforcement action.

TYPE: str

notification_emails

Notification recipients.

TYPE: list[str]

schema_id

Schema definition ID.

TYPE: int | None

Example
params = ReplaceSchemaEnforcementParams(
    events=[...],
    common_properties=[...],
    user_properties=[...],
    rule_event="Warn and Hide",
    notification_emails=["admin@example.com"],
)

common_properties instance-attribute

common_properties: list[dict[str, Any]]

Full common property rules.

user_properties instance-attribute

user_properties: list[dict[str, Any]]

Full user property rules.

events instance-attribute

events: list[dict[str, Any]]

Full event rules.

rule_event instance-attribute

rule_event: str

Enforcement action.

notification_emails instance-attribute

notification_emails: list[str]

Notification recipients.

schema_id class-attribute instance-attribute

schema_id: int | None = None

Schema definition ID.

Data Audit Types

Types for schema audit operations and violation reporting.

mixpanel_data.AuditViolation

Bases: BaseModel

A single violation found during a data audit.

ATTRIBUTE DESCRIPTION
violation

Violation type (e.g., "Unexpected Event", "Missing Property", "Unexpected Type for Property").

TYPE: str

name

Property or event name.

TYPE: str

platform

Platform ("iOS", "Android", "Web").

TYPE: str | None

version

Version string.

TYPE: str | None

count

Number of occurrences.

TYPE: int

event

Event name (for property violations).

TYPE: str | None

sensitive

Whether property is marked sensitive.

TYPE: bool | None

property_type_error

Type mismatch description.

TYPE: str | None

Example
v = AuditViolation(
    violation="Unexpected Event", name="DebugLog", count=42
)

violation instance-attribute

violation: str

Violation type.

name instance-attribute

name: str

Property or event name.

platform class-attribute instance-attribute

platform: str | None = None

Platform: "iOS", "Android", "Web".

version class-attribute instance-attribute

version: str | None = None

Version string.

count instance-attribute

count: int

Number of occurrences.

event class-attribute instance-attribute

event: str | None = None

Event name (for property violations).

sensitive class-attribute instance-attribute

sensitive: bool | None = None

Whether property is marked sensitive.

property_type_error class-attribute instance-attribute

property_type_error: str | None = None

Type mismatch description.

mixpanel_data.AuditResponse

Bases: BaseModel

Response from a data audit operation.

Contains a list of schema violations and the timestamp when the audit was computed.

ATTRIBUTE DESCRIPTION
violations

List of audit violations.

TYPE: list[AuditViolation]

computed_at

Timestamp of audit computation.

TYPE: str

Example
resp = AuditResponse(
    violations=[
        AuditViolation(violation="Unexpected Event", name="Debug", count=1)
    ],
    computed_at="2026-04-01T12:00:00Z",
)

violations instance-attribute

violations: list[AuditViolation]

List of audit violations.

computed_at instance-attribute

computed_at: str

Timestamp of audit computation.

Data Volume Anomaly Types

Types for monitoring and managing data volume anomalies.

mixpanel_data.DataVolumeAnomaly

Bases: BaseModel

A detected data volume anomaly.

ATTRIBUTE DESCRIPTION
id

Anomaly ID.

TYPE: int

timestamp

Detection timestamp.

TYPE: str | None

actual_count

Actual observed count.

TYPE: int

predicted_upper

Upper bound of prediction.

TYPE: int

predicted_lower

Lower bound of prediction.

TYPE: int

percent_variance

Variance percentage.

TYPE: str

status

Anomaly status ("open" or "dismissed").

TYPE: str

project

Project ID.

TYPE: int

event

Event ID.

TYPE: int | None

event_name

Event name.

TYPE: str | None

property

Property ID.

TYPE: int | None

property_name

Property name.

TYPE: str | None

metric

Metric ID.

TYPE: int | None

metric_name

Metric name.

TYPE: str | None

metric_type

Metric type.

TYPE: str | None

primary_type

Primary anomaly type.

TYPE: str | None

drift_types

Drift type details.

TYPE: dict[str, Any] | None

anomaly_class

Anomaly class ("Event", "Property", "PropertyTypeDrift", "Metric").

TYPE: str

Example
anomaly = DataVolumeAnomaly(
    id=1, actual_count=1000, predicted_upper=500,
    predicted_lower=100, percent_variance="100%",
    status="open", project=12345, anomaly_class="Event",
)

id instance-attribute

id: int

Anomaly ID.

timestamp class-attribute instance-attribute

timestamp: str | None = None

Detection timestamp.

actual_count instance-attribute

actual_count: int

Actual observed count.

predicted_upper instance-attribute

predicted_upper: int

Upper bound of prediction.

predicted_lower instance-attribute

predicted_lower: int

Lower bound of prediction.

percent_variance instance-attribute

percent_variance: str

Variance percentage.

status instance-attribute

status: str

Anomaly status ("open" or "dismissed").

project instance-attribute

project: int

Project ID.

event class-attribute instance-attribute

event: int | None = None

Event ID.

event_name class-attribute instance-attribute

event_name: str | None = None

Event name.

property class-attribute instance-attribute

property: int | None = None

Property ID.

property_name class-attribute instance-attribute

property_name: str | None = None

Property name.

metric class-attribute instance-attribute

metric: int | None = None

Metric ID.

metric_name class-attribute instance-attribute

metric_name: str | None = None

Metric name.

metric_type class-attribute instance-attribute

metric_type: str | None = None

Metric type.

primary_type class-attribute instance-attribute

primary_type: str | None = None

Primary anomaly type.

drift_types class-attribute instance-attribute

drift_types: dict[str, Any] | None = None

Drift type details.

anomaly_class instance-attribute

anomaly_class: str

Anomaly class: "Event", "Property", "PropertyTypeDrift", "Metric".

mixpanel_data.UpdateAnomalyParams

Bases: BaseModel

Parameters for updating a single anomaly status.

ATTRIBUTE DESCRIPTION
id

Anomaly ID.

TYPE: int

status

New status ("open" or "dismissed").

TYPE: str

anomaly_class

Anomaly class.

TYPE: str

Example
params = UpdateAnomalyParams(
    id=123, status="dismissed", anomaly_class="Event"
)

id instance-attribute

id: int

Anomaly ID.

status instance-attribute

status: str

New status: "open" or "dismissed".

anomaly_class instance-attribute

anomaly_class: str

Anomaly class.

mixpanel_data.BulkAnomalyEntry

Bases: BaseModel

A single entry in a bulk anomaly update.

ATTRIBUTE DESCRIPTION
id

Anomaly ID.

TYPE: int

anomaly_class

Anomaly class.

TYPE: str

Example
entry = BulkAnomalyEntry(id=123, anomaly_class="Event")

id instance-attribute

id: int

Anomaly ID.

anomaly_class instance-attribute

anomaly_class: str

Anomaly class.

mixpanel_data.BulkUpdateAnomalyParams

Bases: BaseModel

Parameters for bulk-updating anomaly statuses.

ATTRIBUTE DESCRIPTION
anomalies

Anomalies to update.

TYPE: list[BulkAnomalyEntry]

status

New status for all ("open" or "dismissed").

TYPE: str

Example
params = BulkUpdateAnomalyParams(
    anomalies=[BulkAnomalyEntry(id=1, anomaly_class="Event")],
    status="dismissed",
)

anomalies instance-attribute

anomalies: list[BulkAnomalyEntry]

Anomalies to update.

status instance-attribute

status: str

New status for all.

Event Deletion Request Types

Types for managing event deletion requests.

mixpanel_data.EventDeletionRequest

Bases: BaseModel

An event deletion request with lifecycle status.

ATTRIBUTE DESCRIPTION
id

Request ID.

TYPE: int

display_name

Display name.

TYPE: str | None

event_name

Event to delete.

TYPE: str

from_date

Start date.

TYPE: str

to_date

End date.

TYPE: str

filters

Deletion filters.

TYPE: dict[str, Any] | None

status

Request status ("Submitted", "Processing", "Completed", "Failed").

TYPE: str

deleted_events_count

Count of deleted events.

TYPE: int

created

Creation timestamp.

TYPE: str

requesting_user

User who requested.

TYPE: dict[str, Any]

Example
req = EventDeletionRequest(
    id=1, event_name="Test", from_date="2026-01-01",
    to_date="2026-01-31", status="Submitted",
    deleted_events_count=0, created="2026-04-01",
    requesting_user={"id": 1},
)

id instance-attribute

id: int

Request ID.

display_name class-attribute instance-attribute

display_name: str | None = None

Display name.

event_name instance-attribute

event_name: str

Event to delete.

from_date instance-attribute

from_date: str

Start date.

to_date instance-attribute

to_date: str

End date.

filters class-attribute instance-attribute

filters: dict[str, Any] | None = None

Deletion filters (dict when populated, None when absent).

status instance-attribute

status: str

Request status: "Submitted", "Processing", "Completed", "Failed".

deleted_events_count instance-attribute

deleted_events_count: int

Count of deleted events.

created instance-attribute

created: str

Creation timestamp.

requesting_user instance-attribute

requesting_user: dict[str, Any]

User who requested.

mixpanel_data.CreateDeletionRequestParams

Bases: BaseModel

Parameters for creating an event deletion request.

ATTRIBUTE DESCRIPTION
from_date

Start date (YYYY-MM-DD or datetime).

TYPE: str

to_date

End date.

TYPE: str

event_name

Event name to delete.

TYPE: str

filters

Optional deletion filters.

TYPE: dict[str, Any] | None

Example
params = CreateDeletionRequestParams(
    event_name="Test Event",
    from_date="2026-01-01",
    to_date="2026-01-31",
)

from_date instance-attribute

from_date: str

Start date (YYYY-MM-DD or datetime).

to_date instance-attribute

to_date: str

End date.

event_name instance-attribute

event_name: str

Event name to delete.

filters class-attribute instance-attribute

filters: dict[str, Any] | None = None

Optional deletion filters.

mixpanel_data.PreviewDeletionFiltersParams

Bases: BaseModel

Parameters for previewing event deletion filters.

This is a read-only operation that shows what events would match.

ATTRIBUTE DESCRIPTION
event_name

Event name.

TYPE: str

from_date

Start date.

TYPE: str

to_date

End date.

TYPE: str

filters

Optional filters.

TYPE: dict[str, Any] | None

Example
params = PreviewDeletionFiltersParams(
    event_name="Test Event",
    from_date="2026-01-01",
    to_date="2026-01-31",
)

event_name instance-attribute

event_name: str

Event name.

from_date instance-attribute

from_date: str

Start date.

to_date instance-attribute

to_date: str

End date.

filters class-attribute instance-attribute

filters: dict[str, Any] | None = None

Optional filters.