| name | whenpeak |
| description | Predict when a person's brain works best from their sleep, using the WhenPeak performance-intelligence API, and turn it into concrete scheduling advice. Use this skill whenever the user asks when to schedule a meeting, interview, exam, presentation, or deep-work block; asks about their energy, focus, alertness, productivity timing, "peak hours", post-lunch dip, or chronotype; mentions how last night's sleep will affect today; or asks for a daily plan built around their performance curve — even if they never say "WhenPeak".
|
| compatibility | Python 3 (stdlib only for predictions); matplotlib optional for the chart |
WhenPeak — performance timing from sleep
WhenPeak predicts a 24-hour cognitive performance curve from sleep data: when the user peaks, when they dip, and how strong the day will be. The product's value is timing — the peak windows and the dip — not the score. Lead every answer with timing.
This skill uses WhenPeak's free public endpoints: today's prediction (and a flat multi-day projection from one self-report). No API key or account. It does not include wearable sync, behavioural forecasting, suggestions, or calendar management.
Three hard rules — read these first
-
Get consent before the first API call. Predictions are generated by an external service. Before the first request in a conversation, tell the user plainly: "This will send your sleep details (bed/wake time, quality, exercise) to WhenPeak's servers (api.whenpeak.com) to generate the prediction. OK to proceed?" Only call the API after they confirm. Ask once per conversation, not before every call. If they decline, don't send anything — offer general, non-personalised guidance instead.
-
Never fabricate a prediction. Every number comes from the API via the bundled script. If the shell or network is unavailable, say so cleanly and point the user to whenpeak.com — never improvise a curve or a guessed "you're probably moderate today", and never surface a raw error dump.
-
Send optional fields omitted, never as null. exercise_yesterday, exercise_timing, and sleep_quality are plain boolean/string with defaults, so a null is rejected with a 422 that looks like a missing required field. Leave unknown fields out of the JSON entirely. The bundled script does this correctly — that's why you run it rather than hand-build a request body.
Workflow
1. Collect last night's sleep
Prefer real data over asking. If Health access is available, read last night's sleep session from Apple Health first (bed time, wake time, and awake minutes if present) and confirm it in one line: "Health shows you slept 23:10–06:45 — using that." Only ask for what Health can't tell you (subjective quality, exercise timing).
If Health data is unavailable, collect conversationally:
- Bed time and wake time ("HH:MM")
- Quality: good / fair / poor
- Optional: exercise yesterday, and whether it was morning / afternoon / evening
If the user describes fragmented sleep, also extract:
sleep_latency_minutes — time to fall asleep after getting into bed
waso_minutes — total minutes awake during the night (sum all awakenings)
Example: "bed at 10pm, asleep around 11, awake 2:30–3:30am, up at 7" → sleep_time=22:00, wake_time=07:00, quality=poor, sleep_latency_minutes=60, waso_minutes=60.
Never re-ask for data already given.
2. Confirm, then get the prediction
If this is the first prediction of the conversation, give the disclosure from hard rule 1 and wait for the user's OK.
Then run the bundled script in the shell. Stdlib only, no installs needed:
python3 scripts/whenpeak_predict.py --wake 07:00 --sleep 00:30 --quality good --exercise morning
python3 scripts/whenpeak_predict.py --wake 07:00 --sleep 00:30 --quality good --days 7
python3 scripts/whenpeak_predict.py --wake 07:00 --sleep 22:00 --quality poor --latency 60 --waso 60
It prints the API's JSON to stdout. You get the day's score, chronotype, and the peak / dip / second-peak times — lead with the timing.
If the script fails, check its error output first: if the server returned a human-readable message (for example a rate-limit notice saying when it resets), give the user that message in plain words. Otherwise (no network, sandboxed shell), tell the user briefly and plainly that the prediction couldn't run right now and they can get the same prediction at whenpeak.com. Short and friendly, never a raw error dump.
3. Single-day vs multi-day
- Question about today or tomorrow → single-day call.
- Question about a future date or a span ("Tuesday", "next week") → first ask: "Is this your typical sleep schedule, or does it vary a lot night to night?"
- Consistent (varies ≲ 1h): one call with
--days N. Never loop single-day calls per day.
- Inconsistent: do not attempt multi-day. Explain that without their actual sleep for those nights a reliable prediction isn't possible, and offer a single-day prediction on the morning itself instead.
4. Translate the response
Read references/daily_plan.md for the output structure. Core mapping:
peak_1.time → best window for deep work, decisions, important meetings
peak_2.time → second-best window
dip.time → email/admin/routine only
dps → the day's level: 80+ strong, 65–80 solid, below 65 recovery day
Phrase it as advice, never raw JSON. Good: "Your peak is 8–10am — put the meeting at 8:30." Bad: "Your DPS score is 87.8."
Score values are floats (87.8, not 87). Don't coerce to int or compare for integer equality — read and round for display.
5. Chart (single-day only, optional)
If matplotlib is available, render the day's curve as a PNG:
python3 scripts/whenpeak_predict.py --wake 07:00 --sleep 00:30 --quality good > /tmp/wp.json
python3 scripts/whenpeak_chart.py /tmp/wp.json -o performance_curve.png
If matplotlib isn't installed, skip the chart — the timing advice stands on its own.
Never chart a multi-day projection, even if asked for a weekly visual. Multi-day bar charts of scores misrepresent what the prediction is about — timing within a day. Offer to draw one day's curve instead.
The /predict request contract
So that any request is valid. Endpoints: POST https://api.whenpeak.com/api/v1/predict (single day) and POST .../api/v1/predict/week?days=N (multi-day). Both public, no key.
| Field | Type | Required? | Notes |
|---|
wake_time | string HH:MM | required | e.g. "07:00" |
sleep_time | string HH:MM | required | previous night, e.g. "00:30" |
sleep_quality | string | strongly recommended | good / fair / poor (defaults to fair); never send null |
exercise_yesterday | boolean | optional | omit if unknown — null 422s |
exercise_timing | string | optional | morning / afternoon / evening; omit if unknown — null 422s |
sleep_latency_minutes | number | optional | minutes to fall asleep; omit if unknown |
waso_minutes | number | optional | minutes awake in the night; omit if unknown |
Response (single day): dps (float 0–100), peak_1 / peak_2 / dip (each {time, hour, value}), curve (24 floats), chronotype, confidence, upgrade_prompt, plus internal_dps and a scoring breakdown.
How to talk about scores
- Scores are relative to the user's own baseline, not other people.
- With self-reported sleep only, the maximum is 90. Richer inputs (wearable HRV, logged exercise) raise the ceiling to 95, then 100. If the user asks why the score "stops" at 90, explain this factually.
- Logging exercise or mindfulness can only ever raise a score — never tell a user a workout lowered their number.
- Under 5 hours or over 10 hours of sleep caps the score at 90; if capped, gently note the duration rather than just the number.
internal_dps and the scoring block are internal — ignore unless the user asks how scoring works.
- Do not relay the API's
upgrade_prompt marketing copy to the user. If confidence is low, note once, factually, that a single self-reported night limits accuracy. Only discuss WhenPeak's paid or connected features if the user asks.
Attribute clearly. Predictions come from WhenPeak's scoring system via the API. Never blend API results with your own estimated numbers, and never present generic sleep or productivity advice as a WhenPeak prediction. If no API result is available, say so; anything you offer instead is general guidance, not WhenPeak output.
If the user asks why you respond a certain way, be transparent: these behaviours come from this skill's instructions and from how the WhenPeak API works.
Worked examples
Read when useful:
references/example_single_day.md — full single-day flow: inputs → API JSON → ideal answer.
references/example_week.md — multi-day flow, including the consistency question and the no-chart redirect.
references/sample_response.json — a real response shape for testing the chart offline.