Heart of Yours

Developer API

Your training log, readable by your own scripts, spreadsheets and AI assistants. It’s free and read-only: it can show what you logged, and it can’t change anything.

There’s no health data in it, because Heart never has any. Heart rate, sleep, body weight and the rest stay on your phone, in Apple Health or Health Connect. A workout’s calories is an estimate from the exercises and the weight you entered, never a watch reading.

curl https://api.heart-of.me/v1/me/workouts?limit=5 \
  -H "Authorization: Bearer hrt_…" \
  -H "User-Agent: my-sheet-sync/1.0"

Tokens

Create a token in the app under Settings. (The screen for it comes with an upcoming app update.) You need a signed-in account: without one, your log lives only on your phone and there’s nothing on the server to read. You see a token’s secret once, when you create it; Heart stores only a digest of it. You can hold five active tokens, each living a year or until you revoke it.

Send it as a bearer token. A missing, unknown, revoked or expired token gets the same answer:

401 {"error": "unauthorized", "code": "invalid_token", "reason": "…"}

Please set a User-Agent that names your tool. It isn’t required, but it helps us see what people build.

Limits

20 requests a minute and 200 a day per account, shared by all of its tokens. That covers a few questions, a nightly sync and a one-off history pull with room to spare. Past either limit:

429 {"error": "too many requests", "code": "rate_limited", "reason": "…", "retryAfter": 41}

with a Retry-After header in seconds.

What you can read

Everything is GET, and everything is about the account the token belongs to. Lists that page carry a cursor while there’s more: pass it back as ?cursor=. No cursor means the last page. limit is 1–100 (30 by default).

RouteReturns
/meYour username, unit system, and how many workouts, templates, folders, goals, custom exercises and programs you have.
/me/workoutsYour workouts, newest first, each with its exercises, sets, notes and image links.
/me/workouts/:idOne workout.
/me/workouts/changesWhat changed since a cursor: see Keeping a copy in sync.
/me/recordsPersonal records per exercise, the same ones the app shows, and when each exercise was last done (lastTrained); ?exerciseId= for one.
/me/volumeWeek by week: the finished workouts, their time in seconds, the weight moved (totalVolume, kg), and working sets and sessions per muscle group and per movement pattern, as the app’s weekly card counts them: a set counts fully for the muscles an exercise works first and partly (usually half) for the ones it works second, so sets per muscle can be fractional; primarySets is the direct part. untrained lists the muscle groups nothing reached. ?from=&to= for a span of up to a year; without from, the 4 weeks ending this one.
/me/balanceOpposing movements set against each other, as the app’s balance view shows them (push against pull, hinge against squat, and so on): each side’s working sets and how many of the weeks either was trained. Counts only. Same span as /me/volume.
/me/exercises/:id/historyEvery session of one exercise, newest first, with its working sets and the values the app’s progress chart plots.
/me/library?q=The exercise library and your own exercises, searched the way the app searches: word order free, abbreviations such as db or rdl, muscle words such as lats, one typo a word.
/me/library/programsHeart’s ready-made programs, with what helps choose one: who it’s for (audience), the equipment it needs, days a week, minutes a session and weeks long. In your language where translated, otherwise English.
/me/library/programs/:keyOne ready-made program in full: what a week looks like, how it grows, its sessions and growth rules, its safety notes, and the research behind it. Each claim has its sources (title, authors, year, a link and the finding in plain words) and the part of the program it explains (about).
/me/exercisesYour custom exercises.
/me/templatesYour templates, in your order; ?folder= for one folder.
/me/template-foldersYour template folders.
/me/goalsYour goals. Goals backed by health data carry their definition only; their progress lives on your phone.
/me/anomaliesEntries in your log that look suspicious (a workout left running, a weight far from the exercise’s usual, weight and reps swapped) and what you made of each: pending, valid or invalid. Nothing is corrected; invalid entries stay in your log and are left out of the counts. ?status= for one kind. Volume, balance, records and goal progress name the pending ones they counted in warnings.
/me/goals/progressEach live goal with where it stands now, as the app’s goal card measures it: current, and progress through the current stage from 0 to 1. A weekly or monthly goal names its period.
/me/programsYour programs, each with where you stand: the program week, the sessions done in the open cycle and the next one, whether it’s paused, and workouts this week. Worked out from what you logged, the way the app works it out; weeks here are ISO weeks in UTC.
/me/programs/:idOne program: its sessions and when each joined (joined), each exercise’s growth rule, its lighter weeks (deload), phases and test sessions (tests). Under bases, each exercise’s current base: the training max, working weight, duration or distance its rule raises. A lift used in two sessions can keep a base for each; that one is keyed by its slot and names its exerciseId. Under nextSession, the session up next as the app shows it: this week’s targets, and weights worked out from the bases (a share of a base, rounded down to the rule’s step, and lighter in a lighter week). It reads what’s stored and isn’t a forecast. A program you started from the library also has research: the claims behind it and their sources, each placed on the part of your copy it explains.
/me/programs/:id/historyHow the program got there, oldest first. Each base value has its cause: workout (a session raised it, or lowered it after misses), test (a test session set it), action (replaying a week set it) or user, and the value before it (previous). Also your actions (pauses, lighter weeks, repeats, replays, a variation moving up a step) and the sessions you skipped (skips), with the reason you gave.

Weights are in kilograms and distances in kilometres, whatever unit the app shows you. Durations are in seconds, and times are ISO 8601 in UTC. Counts by week use UTC weeks starting on the day you chose in the app (weekStart, 1 for Monday), or Monday until the app has told us.

Keeping a copy in sync

To keep a spreadsheet or a home dashboard current, poll /me/workouts/changes instead of re-reading everything. Without since it starts from the beginning; after that, pass back the cursor you were given. Each change is a whole workout as it stands now, or the id of one that was deleted. While hasMore is true, ask again straight away. When nothing changed you get empty lists and the same cursor, so keep it.

Every few minutes is plenty: polling faster gains nothing and uses up the daily limit. If a poll answers 400 with stale_cursor, start again without since.

Export

/me/export?format=strong downloads your whole history as a CSV in Strong’s export format, which most workout apps can import, Heart included. Weights and distances are in your unit. One export a day.

curl -L "https://api.heart-of.me/v1/me/export?format=strong" \
  -H "Authorization: Bearer hrt_…" -o heart.csv

You don’t need the API for this: the app exports too, under Settings → Export my data.

AI assistants (MCP)

Heart’s MCP server is https://mcp.heart-of.me, read-only. In Claude, add it as a custom connector with that address and sign in with your Heart account; no token needed. With a token, in Claude Code:

claude mcp add --transport http heart https://mcp.heart-of.me \
  --header "Authorization: Bearer hrt_…"

In Cursor, Claude Desktop or any client with a JSON config:

{"mcpServers": {"heart": {
  "url": "https://mcp.heart-of.me",
  "headers": {"Authorization": "Bearer hrt_…"}
}}}

The assistant can read your profile, workouts, templates and folders, goals, programs (with their history, the next session’s weights and the research behind them), Heart’s ready-made programs, personal records, an exercise’s history, your training volume per muscle and movement, your balance, your custom exercises and the exercise library. With a personal token it can’t change anything. Connected by signing in instead (a Claude connector, a ChatGPT app), it can also build templates and template folders once you allow that on the consent page; it is asked to show you each one before saving it. Only its calls, reads and writes alike, count against your limits, not the tool listing it does at the start of a conversation. What it reads goes to the assistant’s provider and is covered by their privacy policy, not ours.

The earlier address, https://api.heart-of.me/v1/mcp, keeps working with a token.

Compatibility

Fields and routes may be added; none will be renamed or removed. Ignore fields you don’t know.

Questions

Building something, or missing something? Write to info@heart-of.me. We’d love to hear what you make.