Nutrition Calculation
This endpoint takes an activity description and returns a fuel prescription: carbohydrate, sodium, and fluid targets, with safety guardrails applied.Progressive enrichment
Saturday works with whatever data you have. More data narrows the prescription; minimal inputs still return a usable result.Minimal inputs
The bare minimum for a calculation:confidence_score. The numbers are based on population-level defaults for the given activity type and body weight.
Standard inputs
Add intensity and environmental conditions:Comprehensive inputs
For the highest accuracy, include an athlete reference:athlete_id, Saturday reads that athlete’s stored profile: sex, year of birth, body weight, sweat level, saltiness, carb experience, usual carb consumption, satiety level, fitness level, and fueling concerns. Inline fields in the request body override the stored values for that one call.
Understanding the response
Confidence score
Thesafety.confidence_score (0.0-1.0) reports how much of the athlete’s fueling profile was answered: a complete fueling profile scores 1.0, and every unanswered field lowers the score. precision.missing_fields tells you which answers would raise it.
Comparing across conditions
To compare fueling across different conditions (a cool morning against a hot afternoon, say), callPOST /v1/nutrition/calculate once per scenario and diff the results yourself, or use POST /v1/nutrition/calculate/batch to submit up to 50 scenarios in a single request. Each scenario in a batch debits your quota individually.
Two prescription shapes. The
calculate endpoints return a flat response (carb_g_per_hr, sodium_mg_per_hr, … with a nested safety block). The stored-prescription read (GET /v1/athletes/{id}/activities/{id}/prescription) returns a wrapped response: { "prescription": { … }, "safety": { … } }. Read the fields accordingly depending on which endpoint you called.Calculation timing
Every engine run carries a deliberate computation window, the same one athletes see in the Saturday app. Size your loading state around it:- Single calculation (
POST /v1/nutrition/calculate,POST .../activities/{id}/calculate): roughly 1 to 3 seconds, scaling with activity duration and rising with intensity. Recalculating an activity that already has a prescription takes about half as long. - Batch (
POST /v1/nutrition/calculate/batch): each scenario adds about half a single calculation’s time. The response headers arrive immediately withX-Batch-Estimated-Ms, the expected total processing time, so you can size a progress indicator before the body lands. The completed body includesestimated_msandelapsed_ms. - Estimate without calculating: send the same batch payload with
"estimate_only": trueto getestimated_msback immediately, with no calculations run and no quota debited. Useful when your HTTP client can’t read streamed headers early. - Reads are instant. Fetching a stored prescription (
GET .../prescription) carries no computation window.
Teaser vs. full responses
Responses depend on the athlete’s Saturday subscription status:- Subscribed athletes get exact numbers:
"carb_g_per_hr": 72 - Free/teaser athletes get ranges:
"carb_range_g_per_hr": "60-90"
Safety
Every calculation response includes asafety block, on every tier. See Safety for the fields, the guardrails behind them, and what you are required to display.
Supported activity types
These seven keys are the complete set.
GET /v1/activity-types returns the same list with descriptions, and accepts an optional ?activity_type= filter to validate a single key.
Every calculation response carries a
precision object: profile_complete, impact-sorted missing_fields, and an onboarding invite. Exact numbers require a complete fueling profile; an incomplete one gets a band instead. See Athlete Onboarding.