ROWFILE/1
A .rowfile keeps one complete rowing session in one file. Row Smarter exports and imports it today. It carries the lossless session record alongside the CSV and TCX exports meant for spreadsheets and training sites.
Sharing this file directly is available now. A web link that hands off the same archive is built for the coming release but is not in the current TestFlight build.
Container framing
The container is a deterministic concatenation, not a zip file. ASCII framing surrounds each entry's raw bytes:
ROWFILE/1\n
>> <name> <size in bytes, decimal>\n
<size raw bytes>\n
...repeated per entry...manifest.json is written first. Readers must accept entries in any order, skip names they do not know and reject a name that appears twice.
Entry names
Row Smarter writes these fixed names:
manifest.json: archive version and writer details.session.json: the lossless copy the importer trusts.summary.csv: the session summary export.samples.csv: recorded samples.strokes.csv: recorded strokes.rowingdata.csv: the rowingdata-style export.beats.csv: raw beat-to-beat intervals.session.tcx: the TCX export.
The CSV and TCX entries are byte for byte the same as the loose exports. A stitched archive may have no session.json; in that case the importer recovers what it can from those entries.
manifest.json
formatVersion is the only required key. The other values may be absent when a tool stitches an archive from loose files.
formatVersion: integer. The current container format is1.sessionID: optional UUID string.appVersion: optional string.writer: optional string. Row Smarter writesRowSmarter; the recovery tool writesstitch-rowfile.
session.json
The session schema is version 1. Values are not rounded. Required keys are marked below; every other key is optional.
Session
v: required integer, session schema version.id: required UUID string, session identity.start: required number, seconds since the platformDatereference date.dur: required duration object;mov: moving-time duration object.dist: required number, distance in metres.name: workout name;tz: start time-zone identifier;utc: start UTC offset in seconds.mass: athlete body mass in kilograms;age: athlete age in years.maxW: maximum watts;minSplit: minimum seconds per 500 metres;maxSR: maximum stroke rate.plan: the storedWorkoutPlandocument;race: race object.avgPace: average seconds per 500 metres;avgW: average watts;work: total work in joules;kcal: kilocalories.strokeCount: required integer;avgSR: average stroke rate.avgHR: average heart rate in beats per minute;peakHR: peak heart rate in beats per minute.avgLen: average stroke length in centimetres;avgRatio: average drive-to-recovery ratio.samples: required array of sample objects;strokes: required array of stroke objects;beats: required array of beat objects.prov: provenance object;hk: HealthKit workout UUID string.
Duration object
s: required integer, whole seconds.a: required integer, attoseconds.
Sample object
t: required duration object, elapsed time.d: distance in metres;p: pace in seconds per 500 metres;w: watts.sr: stroke rate;sc: stroke count;hr: heart rate in beats per minute.df: drag factor;sl: stroke length in centimetres.ap: average pace in seconds per 500 metres;aw: average watts;wj: work in joules.hr0: raw heart rate in beats per minute.
Stroke object
i: required integer, stroke identity;t: required duration object, start time.dr: drive duration;rc: recovery duration;ds: true when timing was derived rather than reported.d: distance in metres;w: average watts.fc: force-curve object;pf: peak force in newtons;af: average force in newtons.dl: drive length in centimetres;sd: stroke distance in metres.
Force-curve object
f: required array of force samples.dt: required duration object, sample interval.cal: required boolean, whether the samples are calibrated.
Beat object
e: required duration object, elapsed time.r: required number, beat interval in seconds.
Race object
id: required race identity;name: race name;dist: race distance in metres.own: the athlete's participant identity;src: outcome source.field: required array of competitors. Each competitor has required participant identityp, then optional display namen, lanel, rankr, distance in metresd, elapsed millisecondseand finished flagf.
Provenance object
kind: ergometer kind;erg: ergometer name;hrm: heart-rate monitor name.app: app version;build: app build;ver: recording version.si: sample interval in seconds;npc: force newtons per count;hrfix: heart-rate repair count.imf: import format;isrc: import source app;iat: import time in seconds since the platformDatereference date;ifn: imported filename.fid: session fidelity;mtd: whether moving time was derived.