Skip to content

Traces

client.traces: /api/v1/traces/...

Bases: Resource

Traces: point measurements such as lactate, RPE or heart rate, optionally linked to a test.

app_metadata cached property

This app's metadata on traces: set(trace_id, data=...) and delete.

create(*, timestamp, lactate=None, rpe=None, notes=None, power=None, speed=None, heart_rate=None, vo2=None, tags=None, sport=None, test_id=None)

Creates a trace.

Endpoint: POST /api/v1/traces/

Parameters:

  • timestamp (datetime) –

    When the measurement was taken. Must be timezone-aware; the offset is stored alongside the instant.

  • lactate (float | None, default: None ) –

    Blood lactate, mmol/L.

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

    Rating of perceived exertion.

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

    Free text.

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

    Power, W.

  • speed (float | None, default: None ) –

    Speed, m/s.

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

    Heart rate, bpm.

  • vo2 (float | None, default: None ) –

    Oxygen uptake (VO2).

  • tags (list[str] | None, default: None ) –

    Tags.

  • sport (Sport | str | None, default: None ) –

    The sport.

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

    Link the trace to this test. A linked trace belongs to the test whatever its timestamp.

Returns:

Raises:

Examples:

from datetime import datetime, timezone

from sweatstack import Client

client = Client()
trace = client.traces.create(
    timestamp=datetime.now(timezone.utc), lactate=2.1, heart_rate=152, tags=["lactate"]
)

delete(trace_id)

Deletes a trace.

Endpoint: DELETE /api/v1/traces/{trace_id}

Parameters:

  • trace_id (str) –

    The trace's ID.

Raises:

Examples:

from sweatstack import Client

client = Client()
client.traces.delete("trace_123")

list(*, start=None, end=None, sport=None, tags=None, limit=100, offset=0, output=None)

list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, limit: int = 100, offset: int = 0, output: Literal['models'] | None = None) -> builtins.list[TraceDetails]
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, limit: int = 100, offset: int = 0, output: Literal['pandas']) -> pd.DataFrame
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, limit: int = 100, offset: int = 0, output: Literal['polars']) -> pl.DataFrame
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, limit: int = 100, offset: int = 0, output: Literal['arrow']) -> pa.Table

Lists traces, newest first.

Endpoint: GET /api/v1/traces/

Parameters:

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

    Only traces on or after this date.

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

    Only traces on or before this date.

  • sport (SportParam | None, default: None ) –

    One sport or a list; a trace matches any of them.

  • tags (TagParam | None, default: None ) –

    One tag or a list; a trace must have all of them.

  • limit (int, default: 100 ) –

    How many traces to return. The client pages through the endpoint until it has this many or there are no more.

  • offset (int, default: 0 ) –

    How many of the newest matching traces to skip.

  • output (ListOutput | None, default: None ) –

    "models" (default), "pandas", "polars" or "arrow".

Returns:

  • list[TraceDetails] | DataFrame | DataFrame | Table –

    TraceDetails objects, or a frame with one row per trace.

Raises:

Examples:

from sweatstack import Client

client = Client()
traces = client.traces.list(tags="lactate", limit=50)

replace(trace_id, *, timestamp, lactate=None, rpe=None, notes=None, power=None, speed=None, heart_rate=None, vo2=None, tags=None, sport=None, test_id=None)

Replaces every field of a trace.

Endpoint: PUT /api/v1/traces/{trace_id}

Every field you leave out is cleared, including test_id: a trace linked to a test is unlinked unless you pass its test_id again. To change one field, retrieve the trace first and pass all its fields back.

Parameters:

  • trace_id (str) –

    The trace's ID.

  • timestamp (datetime) –

    When the measurement was taken. Must be timezone-aware.

  • lactate (float | None, default: None ) –

    Blood lactate, mmol/L.

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

    Rating of perceived exertion.

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

    Free text.

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

    Power, W.

  • speed (float | None, default: None ) –

    Speed, m/s.

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

    Heart rate, bpm.

  • vo2 (float | None, default: None ) –

    Oxygen uptake (VO2).

  • tags (list[str] | None, default: None ) –

    Tags.

  • sport (Sport | str | None, default: None ) –

    The sport.

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

    The test this trace is linked to; None unlinks it.

Raises:

Examples:

from datetime import datetime, timezone

from sweatstack import Client

client = Client()
client.traces.replace(
    "trace_123", timestamp=datetime(2026, 5, 1, 9, 30, tzinfo=timezone.utc), lactate=2.4
)

Bases: _RecordAppMetadata

This app's metadata on traces. Requires an app token.

delete(trace_id)

Deletes this app's metadata from a trace.

Endpoint: DELETE /api/v1/traces/{trace_id}/app-metadata

Parameters:

  • trace_id (str) –

    The trace's ID.

Raises:

Examples:

from sweatstack import Client

client = Client(api_key="app-user-token")
client.traces.app_metadata.delete("trace_123")

set(trace_id, *, data)

Replaces this app's metadata on a trace.

Endpoint: PUT /api/v1/traces/{trace_id}/app-metadata

The whole dict is replaced; there is no merge. Each app sees only its own metadata, and it appears as app_metadata on the trace when read with an app token.

Parameters:

  • trace_id (str) –

    The trace's ID.

  • data (dict[str, Any]) –

    Any JSON-serialisable dict, at most 1 KB and 32 levels deep.

Raises:

Examples:

from sweatstack import Client

client = Client(api_key="app-user-token")  # e.g. user.client in FastAPI
client.traces.app_metadata.set("trace_123", data={"reviewed": True})