Skip to content

Metric Operations (v2)

GraphQL operations for managing metrics (KPIs) and their scores. See the v2 guide for how client.v2 relates to client.v1/client.scorecard, and for metric score/week semantics.

API Reference

MetricOperations

MetricOperations(client: Any, graphql_url: str, user_id_cache: UserIdCache | None = None)

Bases: GraphQLOperations, MetricOperationsMixin

Class to handle v2 (GraphQL) operations related to metrics (KPIs).

Note

Archiving a metric cannot be undone through the GraphQL API (EditMetric(archived: false) does not restore it -- it re-archives it). There is no restore().

Methods:

  • details –

    Get details for a metric.

  • list –

    List metrics for a meeting or a user.

  • create –

    Create a new metric (KPI).

  • update –

    Update an existing metric.

  • archive –

    Archive a metric.

  • scores –

    List the scores of a metric.

  • set_score –

    Set a metric's score for a given time.

  • update_score –

    Update an existing metric score's value and/or note.

  • clear_score –

    Clear a metric score's value, leaving an empty placeholder.

Methods:

details
details(metric_id: int) -> Metric

Get details for a metric.

Parameters:

  • metric_id (int) –

    The ID of the metric (its measurableId).

Returns:

  • Metric –

    A Metric model instance.

Example
client.v2.metric.details(2036155)
# Returns: Metric(id=2036155, title='New Customers', ...)
list
list(meeting_id: int | None = None, user_id: int | None = None, *, frequency: MetricFrequency | str | None = None) -> list[Metric]

List metrics for a meeting or a user.

Parameters:

  • meeting_id (int | None, default: None ) –

    The ID of the meeting. Mutually exclusive with user_id.

  • user_id (int | None, default: None ) –

    The ID of the metric owner. Mutually exclusive with meeting_id. If neither is given, defaults to the current user.

  • frequency (MetricFrequency | str | None, default: None ) –

    If given, only list metrics with this scoring frequency.

Returns:

  • list[Metric] –

    A list of Metric model instances. Archived metrics and

  • list[Metric] –

    scorecard dividers are excluded.

Raises:

  • ValueError –

    If both meeting_id and user_id are provided.

Example
client.v2.metric.list(meeting_id=349524)
# Returns: [Metric(id=2036155, title='New Customers', ...), ...]
create
create(meeting_id: int, title: str, user_id: int | None = None, goal: float | str | None = None, units: MetricUnit | str = NONE, rule: MetricRule | str = GREATER_THAN, frequency: MetricFrequency | str = WEEKLY, min_goal: float | str | None = None, max_goal: float | str | None = None, notes: str | None = None) -> Metric

Create a new metric (KPI).

Parameters:

  • meeting_id (int) –

    The ID of the meeting to attach the metric to.

  • title (str) –

    The title of the metric.

  • user_id (int | None, default: None ) –

    The ID of the metric owner (defaults to the current user).

  • goal (float | str | None, default: None ) –

    The single goal value. Use for every rule except MetricRule.BETWEEN; mutually exclusive with min_goal/ max_goal.

  • units (MetricUnit | str, default: NONE ) –

    The display unit for scores.

  • rule (MetricRule | str, default: GREATER_THAN ) –

    The comparison rule between a score and its goal.

  • frequency (MetricFrequency | str, default: WEEKLY ) –

    The scoring cadence.

  • min_goal (float | str | None, default: None ) –

    The lower goal bound. Only valid with rule=MetricRule.BETWEEN.

  • max_goal (float | str | None, default: None ) –

    The upper goal bound. Only valid with rule=MetricRule.BETWEEN.

  • notes (str | None, default: None ) –

    Description text for the metric.

Returns:

  • Metric –

    The newly created Metric.

Raises:

  • ValueError –

    If goal is combined with rule=MetricRule.BETWEEN, or if min_goal/max_goal is combined with any other rule.

Example
client.v2.metric.create(349524, "New Customers", goal=10)
# Returns: Metric(id=2036155, title='New Customers', ...)
update
update(metric_id: int, *, title: str | None = None, user_id: int | None = None, goal: float | str | None = None, min_goal: float | str | None = None, max_goal: float | str | None = None, units: MetricUnit | str | None = None, rule: MetricRule | str | None = None, notes: str | None = None) -> Metric

Update an existing metric.

Parameters:

  • metric_id (int) –

    The ID of the metric to update.

  • title (str | None, default: None ) –

    New title for the metric.

  • user_id (int | None, default: None ) –

    New owner for the metric.

  • goal (float | str | None, default: None ) –

    New single goal value. Use for every rule except MetricRule.BETWEEN; mutually exclusive with min_goal/ max_goal.

  • min_goal (float | str | None, default: None ) –

    New lower goal bound. Only valid with rule=MetricRule.BETWEEN.

  • max_goal (float | str | None, default: None ) –

    New upper goal bound. Only valid with rule=MetricRule.BETWEEN.

  • units (MetricUnit | str | None, default: None ) –

    New display unit for scores.

  • rule (MetricRule | str | None, default: None ) –

    New comparison rule between a score and its goal.

  • notes (str | None, default: None ) –

    New description text for the metric.

Returns:

  • Metric –

    The updated Metric.

Raises:

  • ValueError –

    If no update fields are provided, if goal is combined with rule=MetricRule.BETWEEN, or if min_goal/ max_goal is combined with a non-BETWEEN rule.

Example
client.v2.metric.update(2036155, title="New Title")
# Returns: Metric(id=2036155, title='New Title', ...)
archive
archive(metric_id: int) -> Metric

Archive a metric.

Note

This cannot be undone through the GraphQL API -- there is no restore() (see the class Note).

Parameters:

  • metric_id (int) –

    The ID of the metric to archive.

Returns:

  • Metric –

    The updated Metric.

scores
scores(metric_id: int, *, start: TimeInput | None = None, end: TimeInput | None = None, include_empty: bool = False) -> list[MetricScore]

List the scores of a metric.

Parameters:

  • metric_id (int) –

    The ID of the metric.

  • start (TimeInput | None, default: None ) –

    Only include scores at or after this time.

  • end (TimeInput | None, default: None ) –

    Only include scores at or before this time.

  • include_empty (bool, default: False ) –

    If True, also include placeholder rows with no value set.

Returns:

  • list[MetricScore] –

    A list of MetricScore model instances, most recent first.

Example
client.v2.metric.scores(2036155)
# Returns: [MetricScore(id=1, value=120.0, ...), ...]
set_score
set_score(metric_id: int, value: float | str, timestamp: TimeInput) -> MetricScore

Set a metric's score for a given time.

For weekly/monthly/quarterly metrics this upserts the score for whichever period timestamp falls in. For DAILY metrics, a score already exists for every day (as an empty placeholder), so this looks the existing score up and edits it instead.

Parameters:

  • metric_id (int) –

    The ID of the metric.

  • value (float | str) –

    The score value (a decimal number).

  • timestamp (TimeInput) –

    The time the score belongs to, as a datetime, date, or unix timestamp (seconds).

Returns:

  • MetricScore –

    The written MetricScore, re-read after the write.

Raises:

  • GraphQLError –

    If value cannot be parsed as a decimal number.

Example
client.v2.metric.set_score(2036155, 120, date(2026, 9, 21))
# Returns: MetricScore(id=1, value=120.0, ...)
update_score
update_score(metric_id: int, score_id: int, *, value: float | str | None = None, notes: str | None = None) -> MetricScore

Update an existing metric score's value and/or note.

Parameters:

  • metric_id (int) –

    The ID of the score's parent metric, needed to re-read it afterwards (there is no root score(id) query).

  • score_id (int) –

    The ID of the score to update.

  • value (float | str | None, default: None ) –

    New score value.

  • notes (str | None, default: None ) –

    New note text for the score.

Returns:

Raises:

  • ValueError –

    If neither value nor notes is provided.

Example
client.v2.metric.update_score(2036155, 499964609, value=125)
# Returns: MetricScore(id=499964609, value=125.0, ...)
clear_score
clear_score(metric_id: int, score_id: int) -> MetricScore

Clear a metric score's value, leaving an empty placeholder.

Parameters:

  • metric_id (int) –

    The ID of the score's parent metric, needed to re-read it afterwards (there is no root score(id) query).

  • score_id (int) –

    The ID of the score to clear.

Returns:

  • MetricScore –

    The updated MetricScore, with value=None.

Async Version

The async version AsyncMetricOperations provides the same methods as above, but with async/await support:

AsyncMetricOperations

AsyncMetricOperations(client: Any, graphql_url: str, user_id_cache: UserIdCache | None = None)

Async class to handle v2 (GraphQL) operations related to metrics (KPIs).

Note

See MetricOperations for why there is no restore().

Async Usage

All methods have the same parameters and return types as their sync counterparts. Simply add await before each method call.

Usage Examples

from datetime import date
from bloomy import Client
from bloomy.v2.models import MetricRule, MetricUnit, MetricFrequency

with Client(api_key="your-api-key") as client:
    # Create a metric with a single goal value
    metric = client.v2.metric.create(
        meeting_id=123,
        title="New Customers",
        goal=10,
        units=MetricUnit.NONE,
        rule=MetricRule.GREATER_THAN,
        frequency=MetricFrequency.WEEKLY,
    )

    # Create a BETWEEN-rule metric (min_goal/max_goal instead of goal)
    team_size = client.v2.metric.create(
        meeting_id=123,
        title="Team Size",
        min_goal=5,
        max_goal=10,
        rule=MetricRule.BETWEEN,
    )

    # List metrics for a meeting
    meeting_metrics = client.v2.metric.list(meeting_id=123)

    # Filter by frequency
    weekly_metrics = client.v2.metric.list(meeting_id=123, frequency=MetricFrequency.WEEKLY)

    # Set this week's score
    score = client.v2.metric.set_score(metric.id, 12, date(2026, 9, 21))

    # Update the score's value and/or note
    updated_score = client.v2.metric.update_score(metric.id, score.id, value=14)

    # List scores, most recent first
    scores = client.v2.metric.scores(metric.id)

    # Clear a score back to an empty placeholder
    client.v2.metric.clear_score(metric.id, score.id)

    # Archive (there is no restore for metrics)
    client.v2.metric.archive(metric.id)
import asyncio
from datetime import date
from bloomy import AsyncClient
from bloomy.v2.models import MetricRule

async def main():
    async with AsyncClient(api_key="your-api-key") as client:
        # Create a metric with a single goal value
        metric = await client.v2.metric.create(
            meeting_id=123, title="New Customers", goal=10
        )

        # Set this week's score
        score = await client.v2.metric.set_score(metric.id, 12, date(2026, 9, 21))

        # List scores, most recent first
        scores = await client.v2.metric.scores(metric.id)

        # Archive (there is no restore for metrics)
        await client.v2.metric.archive(metric.id)

asyncio.run(main())

Available Methods

Method Description Parameters Returns
details() Get a metric metric_id Metric
list() List metrics for a meeting or a user meeting_id, user_id, frequency list[Metric]
create() Create a metric meeting_id, title, user_id, goal, units, rule, frequency, min_goal, max_goal, notes Metric
update() Update a metric metric_id, title, user_id, goal, min_goal, max_goal, units, rule, notes Metric
archive() Archive a metric (no restore()) metric_id Metric
scores() List a metric's scores metric_id, start, end, include_empty list[MetricScore]
set_score() Set a score for a given time metric_id, value, timestamp MetricScore
update_score() Update an existing score's value/note metric_id, score_id, value, notes MetricScore
clear_score() Clear a score's value metric_id, score_id MetricScore

No restore()

Archiving a metric is effectively permanent through this SDK — the GraphQL API does not support un-archiving one. See Archive vs. delete semantics in the v2 guide.

goal vs. min_goal/max_goal

goal is for every rule except MetricRule.BETWEEN; min_goal/ max_goal are for BETWEEN only. Combining them across that split raises ValueError locally, before any request is sent.

Filtering and update requirements

list() accepts either meeting_id or user_id, not both — passing both raises ValueError. update() requires at least one field, or it raises ValueError. update_score() requires at least one of value or notes.