Skip to content
Your data

It's yours.
No asterisks.

Most fitness apps gate export behind a Pro tier, a CSV with three columns, or a JSON dump you can't actually read. flexRep is built on the opposite stance: data portability is a product pillar, not a checkbox feature. Export is free now and forever.

The CSV

11 columns. Every set.

One row per set. ISO timestamps. Weight in kilograms — the canonical unit. RPE half-steps. The notes field carries whatever you typed in the app.

Column
Example
Notes
Date
2026-05-19
ISO 8601
Time
06:14:03
HH:MM:SS, local
Exercise
Bench Press
ExerciseDefinition.name
Group
Chest
MuscleGroup raw value
Equipment
Barbell
Equipment raw value
Set Type
working
warmup, working, drop, etc.
Weight
102.05
kg (canonical), 4dp precision
Reps
5
integer
RPE
7.5
6.0–10.0, half-step
RIR
2.5
computed from RPE
Notes
"top set; bar speed clean"
arbitrary string, CSV-escaped
The JSON

Full schema. Plain shape.

Workouts → ExercisePerformances → SetEntries. UUIDs everywhere. Soft deletes filtered out. Checksum at the top so you can verify nothing changed in transit.

The same schema docs/SCHEMA.md publishes for developers. No mystery fields. Nothing renamed for "branding". If you import a flexRep export into a spreadsheet six years from now, every field will still make sense.

{
  "schemaVersion": "1.0",
  "exportedAt": "2026-05-19T06:48:12Z",
  "checksum": "sha256:8f4e2a…",
  "workouts": [
    {
      "id": "F7C2E9B4-…",
      "startedAt": "2026-05-19T06:00:00Z",
      "endedAt":   "2026-05-19T07:08:23Z",
      "pausedSeconds": 0,
      "wasExplicitlyEnded": true,
      "rating": 5,
      "tags": ["heavy", "bench"],
      "performances": [
        {
          "id": "…",
          "exerciseDefinitionId": "BENCH-PRESS-BARBELL",
          "ordinal": 0,
          "sets": [
            {
              "id": "…",
              "weightKg": 102.0586,
              "reps": 5,
              "rpe": 7.5,
              "rir": 2.5,
              "setType": "working",
              "createdAt": "2026-05-19T06:14:03Z"
            }
          ]
        }
      ]
    }
  ]
}
Six promises

What 'data ownership' actually means here.

Free, forever.

CSV and JSON export are in the free tier. No subscription. No "Pro export" upsell. If you can log a set, you can pull every set.

Every column, every set.

No "summary mode". No "Pro adds RPE column". Every row carries weight, reps, RPE, RIR, set type, equipment, group, notes, timestamp.

No vendor lock-in.

Generic CSV format. Plain JSON schema. .flexrep bundles are zipped JSON with a SHA-256 checksum file. Any other tool can read your data.

Reversible imports.

Every import tags entities with a UUID batch ID. Revert wipes the batch and leaves your native data untouched. No "I shouldn't have imported that" panic.

Two-way HealthKit.

flexRep writes per-set metadata to Apple Health. Body weight syncs both ways. If you delete the app, your data already lives in Health.

On-device by default.

No analytics SDKs, no ad networks, no telemetry. Foundation Models runs locally. iCloud sync is opt-in.

Migration

Coming from Strong or Hevy?

Native importers for both. Map the columns. Preview the rows. Commit the batch. Revert any time.

STRONG → flexRep CSV
  • Strong → Settings → Export CSV
  • flexRep → Settings → Import → Strong
  • Map exercise names (auto-suggested via fuzzy match against 873 bundled definitions)
  • Preview 5 rows · Commit with batch UUID
  • Revertable from Your Training Data screen any time
HEVY → flexRep CSV
  • Hevy → Settings → Account → Export CSV
  • flexRep → Settings → Import → Hevy
  • Map routines + exercise aliases
  • RPE preserved · superset/dropset metadata preserved
  • HealthKit sync re-enabled after import
GENERIC CSV ANY APP
  • Any CSV with the 11 columns documented above
  • flexRep → Settings → Import → Generic
  • Manual column mapping if headers differ
  • UUID-tagged batch, revertable in one tap
  • Useful for restoring from a spreadsheet

Pull your data. Anytime.

If we ever paywall export, it stops being our product.