Skip to main content

intervals-icu-pause-split

Splits an intervals.icu activity into moving legs and pauses, so a café stop, a lunch break on a hike or a night in a hotel no longer drags down the averages of the leg it sits in. Works for rides, hikes, walks and runs alike.

uvx intervals-icu-pause-split https://intervals.icu/activities/i87942121 --api-key=YOUR_KEY

That is the whole install. uvx fetches it, runs it, and throws it away again. Pass the activity id or just paste its URL.

What it looks like

A gravel ride on Rügen. intervals.icu had detected 97 intervals on its own: power surges of a few seconds, with "recovery" in between, which says nothing about how the ride actually went.

❯ uvx intervals-icu-pause-split --edges 5km https://intervals.icu/activities/i87942121

╭────────────────── intervals.icu · i87942121 ──────────────────╮
│ Sassnitz Gravel/Offroad-Radfahren                             │
│ GravelRide · Sat 10:58, 2025-05-17 · 96.9 km · 5:33 h elapsed │
╰───────────────────────────────────────────────────────────────╯
  Pause: at least 5 min below 3 km/h or not recording; stops less than 1 min apart are merged
  Warmup: first 5 km · Cooldown: last 5 km

Speed     │▄▅▆▇▇▇▇▆▅▃▄▄▅▆▆▄█▇███▅▇▇▁ ▅▇▆▇▇▇▇▇▇▆▇▆▇▆▆▆▄▆▄  ▄▇▇▆▇█▇▆▇▇▇█▇▇█▇▆▇▇▆▅▄▅▆▆▅█▅▅▅▅▇▇▆▅▆██▇██│
Now       │╎░╎╎╎╎█╎█╎╎█░░█████░░█░░░░░░░░░░░░░░░░░░░░░█░░░░░█╎░░░░░░█░░░█░░░░░░╎░█░╎█░░░░░╎█╎░╎╎╎█░│
New       │████████████████████████░░░█████████████████░░░█████████████████████████████████████████│
          └┴───────────────┴──────────────┴───────────────┴───────────────┴───────────────┴────────┘
           11:00           12:00          13:00           14:00           15:00           16:00
           ██ moving   ░ pause   ╎ shorter pause   ▁…█ speed up to 27 km/h   · one column ≈ 3 min

Now  97 intervals, 88 not shown
 #  Type      Label  Start  Duration  Distance  km/h    W
 1  RECOVERY  —      10:58     1 min    0.4 km     —    —
 2  WORK      —      11:00     3 min    0.7 km  11.3  255
 3  RECOVERY  —      11:04     5 min    1.5 km     —    —
 4  WORK      —      11:09       6 s    0.0 km  17.3  510
 5  RECOVERY  —      11:09     1 min    0.6 km     —    —
 6  WORK      —      11:11       5 s    0.0 km  20.8  418
 …  …         …          …         …         …     …    …
95  RECOVERY  —      16:23     1 min    0.7 km     —    —
96  WORK      —      16:25      10 s    0.1 km  27.1  468
97  RECOVERY  —      16:25     6 min    2.8 km     —    —

New
#  Type      Label     Start  Duration  Distance  km/h    W
1  WORK      Warmup    10:58    17 min    5.0 km  17.1  195
2  WORK      Leg 1     11:16    1:13 h   21.0 km  19.6  133
3  RECOVERY  —         12:29    10 min    0.0 km     —    —
4  WORK      Leg 2     12:40    1:06 h   22.0 km  19.8  148
5  RECOVERY  —         13:47    11 min    0.0 km     —    —
6  WORK      Leg 3     13:58    2:20 h   43.9 km  19.4  140
7  WORK      Cooldown  16:19    12 min    5.0 km  23.5   99
  5 legs · 5:11 h · 96.9 km   |   2 pauses · 21 min

  Replace the 97 intervals with these 7? [y/n] (n):

Now is what the activity has, New what it will get: 5 km out of town and 5 km back in as warmup and cooldown, three legs, and the two real stops between them. A long Now list is cut down to its first and last few rows; the timeline above it always shows everything.

The timeline is drawn to scale. A pause shorter than one column still shows up, as a thin ╎, so a short stop stays visible even on a two-day bikepacking trip without looking longer than it was. In the terminal, consecutive legs alternate between green and cyan.

How pauses are found

  • Standing still: slower than --stop-speed: 1 km/h on foot (hike, walk, run), 3 km/h for everything else. A steep climb on foot easily drops below 3 km/h, while GPS drift at a real stop stays under 1 km/h.
  • Not recording: auto-pause leaves no samples, just a jump in the time stream. That counts as standing still too.
  • Merged: stops with less than --merge (60 s) of moving between them are one pause. Wheeling the bike from the café back to the road does not split it in two.
  • Long enough: a pause needs --min-pause (5 min) of actual standstill. The moving between merged stops does not count towards that, so stop-and-go through town stays moving.

Getting out of town and back in can be split off as well: --edges 10m turns the first and last ten minutes into Warmup and Cooldown intervals. Give a distance instead with --edges 5km, or two values to set start and end separately: --edges 3km,10m. A distance ignores the time spent at traffic lights, so it tends to match "until I'm out of town" better.

What gets written

Only the moving legs, as labelled WORK intervals. intervals.icu fills the gaps between them with RECOVERY intervals by itself. It does not accept RECOVERY intervals through the API (they come back as WORK), and it drops any label on them, which is why the pauses in the table have none.

Writing replaces all intervals on the activity. Before that, the current ones are saved to ~/.local/state/intervals-icu-pause-split/backups/ (or $XDG_STATE_HOME), and the tool prints the command that puts them back:

uvx intervals-icu-pause-split i87942121 --restore ~/.local/state/intervals-icu-pause-split/backups/i87942121-20261006-044729.json

Usage

uvx intervals-icu-pause-split i87942121                   # preview, then ask before writing
uvx intervals-icu-pause-split i87942121 --dry-run         # preview, never write
uvx intervals-icu-pause-split i87942121 --min-pause 10m   # only the longer stops
uvx intervals-icu-pause-split i87942121 --edges 10m       # warmup and cooldown of 10 minutes
uvx intervals-icu-pause-split i87942121 --edges 3km,10m   # 3 km warmup, 10 minute cooldown
uvx intervals-icu-pause-split i87942121 --label Etappe    # "Etappe 1", "Etappe 2", …
uvx intervals-icu-pause-split i87942121 --yes             # write without asking

Durations are written as 90s, 5m or 1.5h; a bare number means minutes. Distances for --edges are written in km (0.5km, not 500m, because m already means minutes). Nothing is written without a confirmation prompt unless you pass --yes.

Credentials

The API key sits at the bottom of https://intervals.icu/settings. Provide it by flag, by environment variable, or in a .env file next to where you run it:

INTERVALS_ICU_API_KEY=your_key_here

Options

Flag Default Meaning
--api-key $INTERVALS_ICU_API_KEY Your intervals.icu API key
--min-pause 5m Minimum standstill for a pause
--merge 60s Stops with less moving than this in between count as one pause
--stop-speed 1 on foot, 3 otherwise Below this speed (km/h) you count as standing still
--edges Split off the first and last stretch as Warmup and Cooldown, as a duration (10m) or a distance (3km); one value for both ends or two, comma-separated, for start and end
--label Leg Label prefix for the moving intervals
--width terminal width Width of the timeline
--restore Put back the intervals from a backup file
--dry-run Show the preview, never write
--yes Skip the confirmation prompt

Development

just test                      # run the suite with coverage
just coverage                  # the same, as a browsable HTML report
just check i87942121          # dry run against your own account
just run i87942121            # run for real, with the confirmation prompt
just build                     # build the distribution

Releases are cut by tagging:

git tag v0.1.0 && git push --tags

CI runs the tests, refuses a tag that disagrees with the version in pyproject.toml, and publishes to PyPI through Trusted Publishing, so no API token is stored in the repository.

License

MIT

Metadata

Release files for intervals-icu-pause-split 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for intervals-icu-pause-split 0.1.0
File Size Uploaded Provenance Actions
intervals_icu_pause_split-0.1.0.tar.gz 43.1 kB With provenance Details for intervals_icu_pause_split-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for intervals-icu-pause-split 0.1.0
File Interpreter ABI Platform Actions
intervals_icu_pause_split-0.1.0-py3-none-any.whl Python 3 none any Details for intervals_icu_pause_split-0.1.0-py3-none-any.whl

Total release size: 58.7 kB

Release files / intervals_icu_pause_split-0.1.0.tar.gz

Download URL intervals_icu_pause_split-0.1.0.tar.gz
Size 43.1 kB
Tags Source
SHA-256 checksum
How to use checksums
dbc944c0be9ff7112a885a994a9c806b987543453b0b01e9744a3eac1b7991bd
BLAKE2b-256 checksum
How to use checksums
753fb4d1f22b21668da4f5667a8bcd40d6bce61d3300151158cd62aaaf312630
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / intervals_icu_pause_split-0.1.0-py3-none-any.whl

Download URL intervals_icu_pause_split-0.1.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1622456a8ab197ba89d5fc26b2f31680605e1a4f19004758639b1c5df593e24b
BLAKE2b-256 checksum
How to use checksums
d139579df9824d395431f27150a71bd504af79d7141aa90f1be6b57d67594ca1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Security for intervals-icu-pause-split 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for intervals_icu_pause_split-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page