Fitaio

Fitaio / Developers

Your data, your tools.

A REST API and an MCP server over the same records the app uses. Log a workout from a script, chart your weight on a dashboard, or let an assistant read your training history. Everything is metric and everything is yours.

Get a key

  1. Open Fitaio, go to Settings, then Developer, then API keys.
  2. Create a key. Choose Read only unless the tool needs to save records, and an expiry if you like.
  3. Copy the key. It is shown once; Fitaio stores only a hash.

Treat a key like a password. It reads and, with write access, changes your own records. Revoke it in Settings the moment a tool no longer needs it.

Authenticate

Send the key with every request as a bearer token. The api-key header works too, so a Hevy integration can be pointed at Fitaio by changing its base URL.

curl https://fitaio.app/api/v1/me \
  -H "Authorization: Bearer fitaio_..."

Conventions

  • Base URL: https://fitaio.app/api/v1. JSON in and out, snake_case fields.
  • Units: kilograms, centimetres, kilocalories, grams, seconds, percent. Always.
  • Time: RFC 3339 timestamps in UTC such as 2026-09-19T15:04:05.000Z; calendar days as YYYY-MM-DD.
  • Lists: limit (1 to 100, default 25) and cursor. Responses carry next_cursor, null on the last page. since is inclusive, until exclusive, except day ranges which include both ends.
  • Writes: POST creates, PUT replaces a whole resource, PATCH changes the listed fields. Server-managed fields in a body are ignored.
  • Errors: { "error": { "code", "message", "details" } }. Codes include invalid_request, invalid_key, expired_key, insufficient_scope, not_found, rate_limited.
  • Limits: 120 requests a minute per key, 300 a minute per IP address, 256 KB bodies. A 429 carries Retry-After.

Quickstart

Your last five workouts:

curl "https://fitaio.app/api/v1/workouts?limit=5" -H "Authorization: Bearer $FITAIO_KEY"

Log this morning's weight:

curl -X POST https://fitaio.app/api/v1/body/weight \
  -H "Authorization: Bearer $FITAIO_KEY" -H "Content-Type: application/json" \
  -d '{ "weight_kg": 86.4, "body_fat_percent": 19.5 }'

The same from JavaScript, logging a workout. Find exercise ids with GET /exercises?q=bench:

const response = await fetch('https://fitaio.app/api/v1/workouts', {
  method: 'POST',
  headers: { Authorization: 'Bearer ' + process.env.FITAIO_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'Push A',
    started_at: '2026-09-19T15:00:00Z',
    duration_seconds: 3600,
    exercises: [{ exercise_id: 'bench-press', sets: [
      { type: 'warmup', weight_kg: 20, reps: 10 },
      { weight_kg: 60, reps: 8, rpe: 8 },
    ] }],
  }),
});
const workout = await response.json(); // volume_kg is computed for you

What you can reach

ResourceEndpoints
MeProfile
WorkoutsList, count, get, create, replace, delete, and events?since= for sync
RoutinesSaved single-day routines: list, get, create, replace, delete
Training plansWeekly plans: list, get, create, replace, activate, delete
ExercisesSearch the catalogue, get one, and your history with it
BodyWeight logs and measurements: list, create, patch, delete
NutritionDaily totals by day: list, get, set, delete
SupplementsSchedule and daily ticks (send {} to tick today)
GoalsList, current, create
StatsTraining totals, personal records, body trend

Every operation, field and limit is in the interactive reference, generated from the same document that validates requests: /api/v1/openapi.json. Note that PUT /nutrition/{day} answers 201 the first time a day is written and 200 after that.

Coming from Hevy

Workouts, routines, exercises and body measurements map directly. Fitaio adds nutrition, training plans, goals, supplements and stats, uses cursors instead of page numbers, and returns metric units only. There are no deletion events or webhooks yet.

Not in v1

The AI coach is not available through the API, and there are no webhooks. Both are on the list. Questions and requests: .