This is a submission for the Presage SmartSpectra SDK Challenge
What I Built
I can't afford a smartwatch. Most mornings I ask myself the same thing: should I train hard today, or take it easy? Without a watch telling me how I recovered, I just guess.
But I already have a phone with a camera. So I built Roll Call: prop your phone up, sit still for 75 seconds, and the SmartSpectra SDK reads your pulse, breathing and heart rate variability. Then Roll Call tells you how today compares with your own normal, and helps you decide what to do about it.
It grew into a full daily routine. Here's what one morning looks like, following a fictional athlete called Amara from the demo.
1. Heart: 75 seconds of sitting still
You open your private link and sit still. A sun rises as your progress bar, on a horizon drawn from your pulse waveform, with a glow that follows your breathing. If you start talking, the clock pauses. If the light is poor, Rollo, the rooster coach, tells you to find some.
Then two quick taps for how you slept and how you feel.
Every reading is compared with your own last two weeks. There's no "good" pulse and no league table, only you against you. The first five check-ins just learn what your normal is.
2. Legs: three jumps
Your heart can look fine while your legs are finished, so the next step checks them. Hands on hips, three jumps, tracked on the phone with MediaPipe. The SDK needs you still, so this is the one job I gave to a different tool, and heart always goes first because jumping raises your pulse.
Height comes from how long you're in the air, which means the jump has to be honest. Swing your arms, land in a way that doesn't add up, or leave the picture, and Rollo asks for another. And it never shows you centimetres. At 30 fps, one frame is about 15% of the height, so a raw number would be close to meaningless. You only ever see the change against your own usual.
Sore or injured? Skip it, or do a 20-second balance test on each leg instead.
3. Today's call
This is what it's all for. Two plain lines and a suggestion:
Heart: Ready · Legs: 9% below usual
Your heart looks ready but your legs are clearly down. An easy upper-body day keeps you moving without loading them.
Every option stays open, and you choose. Over time, Rollo also starts noticing patterns between your own days, like how your rep speed holds up on off days, and it always shows how many examples that's based on.
4. Train: reps, form and knowing when to stop
Prop the phone up, pick an exercise, and Rollo counts your reps out loud. It tracks the joint angle with a minimum range, so half-reps don't count, and it gives gentle cues like "a little deeper if it feels good".
It also watches how fast each rep comes up. When your speed falls more than 20% below your fastest rep (you can change that number), Rollo says "That's the set. Good work." It's only a suggestion.
Afterwards, you're back with the SDK for a 60-second settle check, which shows how each kind of session settles.
5. Crews: the fitness competition where resting can win
This is my favourite part. Every fitness leaderboard I can think of rewards whoever trains hardest or has the best numbers. In Crews, you can't score on your pulse, HRV, jumps, reps or speed at all. Everyone starts equal, because the game only scores how you respond to your own readings:
| What you did | Points |
|---|---|
| A real heart check-in | +1 |
| A legs or balance check | +1 |
| Listened to your body: hard on a Ready day, or easier on an off day | +3 |
| Did what you chose | +2 |
| A settle check after training | +1 |
| Went hard when your morning said not to | 0, and no penalty |
Your crew's points spread sunrise light across a shared valley map. A tile on the border goes to whichever crew scored more that day, using the average per member so bigger crews get no edge. Light fades if a crew stops checking in, so turning up beats one big day. Seasons run for a week, with four leagues to climb and a recap card to share at the end. In the demo, Amara's easy day is what wins their crew the contested tile.
You can send a teammate one friendly nudge a day, and you each build up a little farm that grows and never shrinks. Teammates see whether you've checked in, and your points if you allow it. They never see a reading.
6. For coaches: one board
If you have a coach, they get one board with everyone sorted by how far they are from their own usual, with plain reasons instead of a score. "Pulse 10 above usual · HRV 33% below usual."
The coach can change a session, and AI drafts a note from the numbers only. Nothing goes to the athlete until the coach has read it and pressed Send.
Demo
Try it yourself in two minutes. Clone the repo, run pnpm install and pnpm dev, and press Follow Amara's morning. It needs no camera, account or API keys. Everything in that mode is fictional and labelled DEMO DATA.
Code
Roll Call
Should you train hard today, or take it easy? Roll Call answers that with 75 seconds in front of a phone camera. No wearable.
It reads your pulse, breathing and heart rate variability with the Presage SmartSpectra SDK, compares them with your own last two weeks, and helps you make the call. Built for the Presage SmartSpectra SDK Challenge on DEV.
Not a medical device. Readings are wellness estimates to help with training decisions, for adults 18+. You make every decision. Presage states that SDK metrics are for general wellness and informational purposes and have not been cleared by the FDA.
Watch the walkthrough
Watch it on YouTube (under 3 minutes). The check-in in the video is a labelled replay with fictional data, and the voice and exercise footage are AI-generated.
Try it in two minutes
No camera, no account and no API keys needed. You need…
Setup instructions, for both the demo and live check-ins, are in the README.
How It Responds to Human Signals
I use nearly everything the SDK offers for a seated reading. Here's what each signal does in real time:
| SmartSpectra signal | What the app does with it |
|---|---|
| Pulse rate (12-second window) | Compared with your own usual. The heaviest of the heart signals |
| HRV: RMSSD and Baevsky stress index (60-second window) | Compared only with your own usual, which is what Presage's docs advise for the stress index |
| Breathing rate (30-second window) | Part of the same comparison |
| Pulse waveform | Drawn live as the horizon on the check-in screen |
| Breathing trace | Drives the sun's glow |
| Talking | Pauses the check-in, and those readings don't count |
| Validation status | Turns into a friendly hint, like "Lean back so your upper chest is in view" |
| Confidence | Below the SDK's gates (40 for pulse, 45 for breathing, 50 for HRV), a metric says "not read today" and drops out. It's never guessed |
How I integrated it. My app supplies the frames through the SDK's custom input. The browser sends camera frames at 30 fps to my server, and each check-in gets its own worker process running @smartspectra/node-sdk, so a problem in native code can't take down the app. Frames are forwarded and dropped, never written anywhere.
const sdk = new mod.SmartSpectraSDK({
apiKey,
enableTelemetry: false,
requestedMetrics: [...mod.breathingMetrics, ...mod.cardioMetrics, ...mod.faceMetrics],
});
sdk.useCustomInput();
sdk.start();
sdk.sendFrame(buf, w, h, stride, fmt, ts);
Results become one common format that replay and simulation also use, so the check-in logic is the same code whether the signal is live or not. That's also why the demo works with no camera.
How the readings become a decision. After five good check-ins, each reading is compared with your rolling 14-day median using a robust z-score, so one strange morning doesn't throw off your normal. That gives you Ready, Watch or Check in. If a reading is missing, the others share its weight.
How the SDK shaped the product. HRV needs a full 60-second window, which is why a check-in takes 75 seconds and not 20. The docs say to compare the stress index with the person's own baseline, which is where "only ever against yourself" came from. And camera vitals need you still, which is why movement went to a different tool.
A few things that cost me time, in case they save you some:
- With custom input, the session only reaches
kRunningafter it gets frames. I was waiting for "running" before sending any, so it just sat there forever. - If there's a gap of more than 2 seconds between frames, the SDK starts rejecting everything after it. I had to close up the timestamps after a stall.
- It needs a steady connection for the whole session. My sessions kept dying, and for a while I blamed everything except my Wi-Fi.
- My first plan was 15 fps to save bandwidth. The docs say to stay above about 25, so that went too.
Prize Categories
Best Thoughtful Real-World Use.
The need: knowing how recovered you are is mostly sold as a feature of expensive watches. Everyone else guesses, and that's how you end up doing hard intervals on legs that needed a rest.
Who it's for: adults who train and can't justify, or don't want, another device. And online coaches, who can't see their athletes in person and get "feeling 6/10 I guess" instead.
How I designed it for them:
- It fits into a morning. 75 seconds and two taps. Nothing to buy, wear or charge.
- It's fair. You're only ever compared with yourself, and the crew game can't reward anyone for being fitter.
- You stay in charge. The app suggests, and you choose. A coach's message never goes without them pressing Send.
- It admits what it doesn't know. Low confidence says "not read today" rather than showing a number it doesn't trust.
- It doesn't push you. Rest days keep your streak. Going hard on a bad day costs nothing, it just earns nothing. If you feel rough three mornings running, only you see a gentle note, and your crew sees nothing.
- It's accessible. Status is shown by shape and words as well as colour, it respects reduced-motion settings, and the main screens pass automated accessibility scans.
Consent and Data Handling
- Camera consent: a plain-language consent screen with an 18+ confirmation appears before your first check-in, and you start every check-in yourself. Nothing runs in the background.
- Heart check-in video: goes to the Roll Call server, is processed in memory and thrown away. It's never saved.
- Legs and Train video: stays on your phone. Only jump and rep numbers are saved.
- What's stored: the numbers, your answers about sleep and how you feel, your choices and points. They stay until you delete them.
- Deleting: you can download or delete everything from your own page, which also ends your link.
- Who sees what: your coach sees your numbers. Crew teammates only see whether you've checked in, plus points and streaks if you allow it. They never see a reading, and tests check that crew data contains none.
- SDK telemetry: turned off. The SDK still contacts Presage to check its key and usage and to load its models.
- AI: coach notes can be drafted by an AI service, which gets numbers and the chosen action, never names, video or notes. Without one, it uses templates.
- MediaPipe: the browser downloads it from jsDelivr and Google. One thing I only found through testing: it also tries to send Google usage metrics (no images or landmarks), so the app blocks that with a Content-Security-Policy.
- Medical: Roll Call is a training aid, not a medical device. The readings are wellness estimates for adults, and it makes no medical claims.









Top comments (0)