VOLTRA Workout Data
Use when the user asks about VOLTRA or Concept2 Rowing/Ski workout history, recent workouts, sets, reps, training volume, force, velocity, power, fatigue, progress trends, movement performance, or data completeness. Fetch and analyze training data through Cortex. When "rowing" or "skiing" is ambiguous, distinguish VOLTRA cardio records from the matching Concept2 records and combine clearly labeled results when the user wants an overall summary.
Use the local voltra command as the single data entry point. Do not bypass Cortex to call the Beyond backend API directly. Do not expose the full VOLTRA API Key in commands, logs, or responses. Concept2 Rowing and Ski queries are read-only; C2 record deletion is temporarily unsupported.
Prerequisites
Unless already confirmed in the current session, run:
where.exe voltra
voltra --version
voltra -v
voltra workout auth-check --jsonIf authentication fails, tell the user to set VOLTRA_API_KEY or run:
voltra config set-api-key "<VOLTRA API Key>"Do not ask for the web URL to generate keys. The VOLTRA API key is obtained from the Beyond+ mobile app (Cortex beta section), not a web dashboard.
After auth, detect the user's unit preference: read the unit field from voltra workout list --page-size 1 --json. If no workout data exists, ask "lbs or kg?". Standard workout weight/force/volume fields are already unified to LBS regardless of unit — unit only signals the user's display preference. Isometric isometricResult force fields are an explicit exception and use N/N·s. If unit is "KG", convert standard *Lbs fields ÷ 2.205 → kg for user-facing display, but do not convert the N-based Isometric fields. If unit is "LBS", report values as-is. Always allow the user to override. For details, see references/field-units.md.
After auth, use local-time output for user-facing timestamps. Cortex timestamps are UTC by default. Add --local-time to display timestamps in local timezone with ISO 8601 offset (for example, 2026-06-10T20:45:32+08:00). --start / --end parameters always use UTC regardless of --local-time.
For Concept2 Rowing and Ski, workoutDate is already the record's local time and timezone contains its IANA timezone. Do not reinterpret C2 workoutDate with --local-time.
Source and Sport Resolution
The source and sport are independent dimensions. Do not use a Concept2 command just because the sport is rowing or skiing.
- VOLTRA Cardio Rowing — a workout performed on VOLTRA. It appears in standard VOLTRA workout history as workout type
8; useworkout list,sets,aggregate-sets, oraggregate-repswith--workout-type 8where supported. - Concept2 Rowing — a Concept2 Logbook rowing record. Use the read-only
workout c2-rowing ...commands. - VOLTRA Cardio Skiing — a workout performed on VOLTRA. It appears in standard VOLTRA workout history as workout type
9; use the same standard commands with--workout-type 9where supported. - Concept2 Ski — a Concept2 Logbook skiing record. Use the read-only
workout c2-ski ...commands.
When the user names only "rowing" or only "skiing" and asks for historical data or analysis, do not silently choose one source. For rowing, query VOLTRA workout type 8 and Concept2 Rowing when both are requested; for skiing, query VOLTRA workout type 9 and Concept2 Ski when both are requested. Label every result with both its source and sport. If the user names only Concept2 or C2, ask whether they mean Rowing or Ski. If the user names a source and sport explicitly, use only the matching source and sport. If the request would control a device, clarify the source first; this skill cannot control Concept2, and both C2 record types are read-only with deletion temporarily unsupported.
For an integrated rowing or skiing summary:
- Use the standard VOLTRA commands for workout type
8or9, and use the matching C2 command (c2-rowingorc2-ski) for Concept2. - Align the time zone and date range before comparing results.
- Keep source-specific units and metrics explicit: VOLTRA cardio uses the standard workout contract; C2
distanceMis already meters, C2 pace fields require their own conversion, and C2workoutDateis already local. - Never merge or reuse IDs across sources or sports.
Quick Decision Guide
- Recent training / training history:
voltra workout list --page-size 10 --json - Single workout details:
voltra workout sets <workout-id> --json - Per-rep breakdown of a set:
voltra workout reps <workout-id> <set-id> --json - Isometric test results:
voltra workout list --workout-type 5 --json, thenvoltra workout sets <workout-id> --json - Unqualified rowing history or comparison: resolve VOLTRA workout type 8 versus Concept2 Rowing; see Source and Sport Resolution
- VOLTRA Cardio Rowing records:
voltra workout list --workout-type 8 --page-size 10 --json - Concept2 Rowing records:
voltra workout c2-rowing list --page-size 10 --json - One Concept2 Rowing workout with stroke data:
voltra workout c2-rowing detail <workout-id> --json - Concept2 Rowing monthly totals:
voltra workout c2-rowing monthly --timezone <IANA> --json - Unqualified skiing history or comparison: resolve VOLTRA workout type 9 versus Concept2 Ski; see Source and Sport Resolution
- VOLTRA Cardio Skiing records:
voltra workout list --workout-type 9 --page-size 10 --json - Concept2 Ski records:
voltra workout c2-ski list --page-size 10 --json - One Concept2 Ski workout with stroke data:
voltra workout c2-ski detail <workout-id> --json - Concept2 Ski monthly totals:
voltra workout c2-ski monthly --timezone <IANA> --json - Set/rep counts, volume, duration, movement distribution, weekly trends:
voltra workout aggregate-sets --json - Force, velocity, power, work, rep quality, fatigue:
voltra workout aggregate-reps --json - Delete confirmed Beyond app records:
voltra workout records delete <workout-id>... --yes --json - Key or config issues:
voltra workout auth-check --json, thenvoltra config show --jsonif needed - Clear local key:
voltra config clear-api-key --json
Command Index
These are the stable commands available to this skill:
| Command | Purpose |
|---|---|
voltra workout auth-check --json | Verify the current VOLTRA API Key |
voltra workout list ... --json | List workouts, locate training records |
voltra workout sets <workout-id> --json | View sets for a single workout |
voltra workout reps <workout-id> <set-id> --json | View per-rep data for a set |
voltra workout c2-rowing list ... --json | List the current user's Concept2 Rowing records (read-only) |
voltra workout c2-rowing detail <workout-id> --json | View one Concept2 Rowing record and cumulative stroke data (read-only) |
voltra workout c2-rowing monthly --timezone <IANA> ... --json | Summarize Concept2 Rowing records by month (read-only) |
voltra workout c2-ski list ... --json | List the current user's Concept2 Ski records (read-only) |
voltra workout c2-ski detail <workout-id> --json | View one Concept2 Ski record and cumulative stroke data (read-only) |
voltra workout c2-ski monthly --timezone <IANA> ... --json | Summarize Concept2 Ski records by month (read-only) |
voltra workout aggregate-sets ... --json | Cross-workout set-level aggregates |
voltra workout aggregate-reps ... --json | Cross-workout rep-level aggregates |
voltra workout records delete <workout-id>... --yes --json | Permanently delete confirmed current-user Beyond app workout records and sets after confirmation |
voltra config show --json | Check if a local key is configured (returns masked key only) |
voltra config clear-api-key --json | Delete the local stored key (does not revoke the remote token) |
The public C2 commands are sport-specific: use c2-rowing for Concept2 Rowing and c2-ski for Concept2 Ski. Both commands are read-only; there is no unfiltered public C2 command that mixes the two sports.
Command References
For non-trivial analysis tasks, read the matching reference first:
| Need | Reference |
|---|---|
| Key setup, auth failures, config boundaries | references/auth-and-config.md |
| Workout lists, single workouts, set/rep drill-down | references/drill-down.md |
| Aggregate commands, time ranges, filters | references/aggregates.md |
| Analysis workflows, output structure, common pitfalls | references/analysis-recipes.md |
| Field naming, unit suffixes, conversion rules | references/field-units.md |
Isometric Test Results (workoutType 5)
Historical Isometric results are available through the standard workout APIs. Use
workout list --workout-type 5 to locate a test, then workout sets <workout-id> to
read its set-level isometricResult. The workout list contract is unchanged and its
maxPullForceLbs is the test's peak force summary in pounds.
When present, isometricResult contains:
peakForceN: peak force in N.rfdNPerSec: rate of force development in N/s.timeToPeakForceMs: time to peak from the run-segment start, in ms.impulseNSec: impulse in N·s.testTimeMs: run-segment duration in ms; it excludes pre and post segments.forceDataRateHz: force-curve sample rate, normally 100 or 500 Hz.
The nested Isometric force fields use N/N·s even though standard *Lbs fields use
pounds. Convert explicitly when comparing them: 1 lbf = 4.4482216152605 N.
timeToPeakForceMs and testTimeMs are elapsed durations, not timestamps, so
--local-time must not change them. Missing isometricResult or subfields are
omitted; do not replace them with zero. The reps endpoint does not return the raw
force curve, and realtime Isometric result streaming is outside this history API.
The force trace has pre/run/post segments: testTimeMs is the run segment,
timeToPeakForceMs starts at the run segment, and RFD uses the first 10 run samples.
Treat impulseNSec as the returned device/service metric; its exact integration
window cannot be independently reproduced from the Agent response.
Rules
- Default to
--jsonand parse structured output. Do not scrape plain text. - If the user says only "rowing" or "skiing", follow Source and Sport Resolution; never assume that it means Concept2 or VOLTRA without checking the request type.
- Before running commands, convert relative times ("today", "last week", "last 30 days") to explicit
yyyy-MM-ddTHH:mm:ssin UTC. - In responses, state the exact time range used in the user's local timezone.
- For user-facing timestamp display, add
--local-timeto standard workout commands so JSON timestamps include local timezone offsets. C2 Rowing and SkiworkoutDatevalues are already local and must be left as returned. - Isometric
isometricResult.*values are already normalized by the backend. Do not apply the user's lbs/kg preference conversion topeakForceN,rfdNPerSec, orimpulseNSec; only convert them to another unit when explicitly requested. - Always convert distance fields (
*Mm) from millimeters to meters (÷1000) before display. Never show raw mm values to the user. C2 fields ending inM(for example,distanceM) are already meters and must not be divided again. Seereferences/field-units.md. - Always convert duration fields (
*Sec) to human-readable format (Xm Xs) for user-facing summaries. Preserve the raw decimal seconds when exact C2 data is requested. - Follow all unit conversion rules in
references/field-units.md— weight (lbs/kg per user preference), distance (mm→m), duration (sec→human). - Do not expose internal IDs by default. This includes workout
id, setid,actionIds, anddeviceIdentity. Use descriptive labels instead (type name, time, position, movement name). If the user explicitly asks to delete records, IDs may be used internally to build the deletion command; first identify the target records from query results and obtain a second confirmation before executing it. - To resolve
actionId→ exercise name, usevoltra actions get <id>orvoltra actions list --json. The action catalog is cached locally. Common defaults:actionId=33→ "Free Exercises". - To capture account preferences, run
voltra whoami --json; this refreshes~/.voltra/user-preferences.jsonwith preferred units and body measurements. - Do not infer long-term trends from a single page of
workout list. Use aggregate commands for trends and totals. - Do not paginate indefinitely by default. Only fetch additional pages when the user asks for full history or the question genuinely requires more data.
workout list --page-sizeis capped at 50 by the backend, not Cortex. Do not request larger pages. For broader history, paginate manually or useaggregate-sets/aggregate-reps.workout list/aggregate-*--start/--endspan is capped at 365 days by the backend, not Cortex. Split longer queries into chunks.--startand--endare always UTC.- Cortex fetches data; interpretation, comparison, conclusions, and caveats are the AI layer's responsibility.
Out of Scope
- Creating, listing, or revoking remote VOLTRA API Keys. Cortex can only store, view masked status, and clear local keys.
- Modifying Concept2 Rowing or Ski records. The C2 command is read-only; deletion is temporarily unsupported.
- Any training-history mutation other than the explicit, confirmed
voltra workout records delete ... --yescommand for the current user's Beyond app records. This deletion is physical and also removes set data. The backend returnsdata: nullwithout per-ID results; missing, already-deleted, re-submitted, or foreign IDs may be silently ignored. - BLE device control.
- Prescribing deterministic training plans based on insufficient data.
- Managing custom curves. Custom Curve (workout type 6) records are queryable via
workout list/sets/reps/aggregate-*, but curve CRUD lives involtra custom-curve *— seevoltra-device-trainingfor those commands. - Session template CRUD. Workout history may reference
actionId/workoutModevalues that also appear in session templates, but creating/updating/deleting session templates is owned byvoltra-device-training(thevoltra session *commands). Use that skill for template authoring.
Guardrails
- If authentication or config issues persist and the cause is unclear, suggest loading
voltra-getting-startedfor first-time setup orvoltra-cli-troubleshootingfor diagnostics. - Before deleting Beyond app records, show the user which workouts will be targeted and ask for explicit confirmation. Never add
--yeswithout that confirmation. The delete API returnsnullwithout confirming each ID, so do not claim that every requested ID was deleted. - If the user also asks about live device state or control, defer to
voltra-device-statusorvoltra-device-trainingrespectively.
VOLTRA Device Training
Safely operate all VOLTRA training modes through Cortex. Use when the user asks to enter a training mode (weight training, resistance band, damper, isokinetic, isometric, rowing, skiing), set load/resistance/velocity, start a rowing/skiing distance preset or Just Row, turn load on, unload, finish training, configure chains/eccentric, enter cable-length mode, switch/change weight units (lbs/kg), pair or unpair Twin devices, manage session templates (create/update/delete/list), manage custom workout actions, or create/apply custom curves. **Operation only** — if the user is asking what a mode is or wants a recommendation, use `voltra-training-modes` instead. For pure device-state inspection (battery, mode, connection), use `voltra-device-status`. This skill controls VOLTRA's built-in Rowing and Skiing modes only; Concept2 Rowing/Ski history and combined reports belong to `voltra-workout-data`.
Cortex Troubleshooting
Diagnose Cortex installation, PATH, storage, BLE, scan, connection, and command-control failures. **Diagnosis only** — once the issue is resolved, defer to `voltra-device-status` for routine state inspection and to `voltra-device-training` for ongoing control. Use when `voltra` is missing, the wrong binary is found, PATH contains release artifacts, BLE scan/connect fails, doctor reports issues, known devices are stale, or an AI agent needs a systematic Cortex troubleshooting workflow.