The precision model
Calculation responses carry aprecision object on every tier:
profile_complete: true→ the response carries exact numbers (carb_g_per_hretc.).profile_complete: false→ the response carries honest bands (carb_range_g_per_hretc.) — never wider than free-tier teaser ranges, never falsely exact. Band width is measured from our engine’s real sensitivity to each missing field, somissing_fieldsis sorted most-impactful-first: it is literally your collection roadmap.- The 30-day trial clock starts at the athlete’s first narrower-than-full-wide calculation — any real profile data starts it; zero-data calls never do. Collect the profile first and your athletes get 30 days of genuinely exact numbers.
The required (safety-core) fields are:
sex, year_of_birth/age, weight_kg, sweat_level, saltiness, carb_experience, usual_carb_consumption, plus per-call duration_min, intensity_level, and thermal_stress_level. Recommended fields (satiety_level, fitness_level, concerns, meal_before_min, is_race) narrow bands further — exactness requires everything.Four ways to collect the profile
1. Hosted onboarding page (recommended start)
Every incomplete-profile response includesprecision.onboarding.url — a durable, athlete-scoped link to Saturday’s hosted onboarding page, co-branded with your platform. Send the athlete there (button, email, push — your call):
- Asks only the missing questions, one per screen, ~2 minutes, mobile-first.
- Each answer commits immediately — a half-finished session still narrows bands.
- The finish screen asks the athlete’s consent to show fuel for their most recent activity, then deep-links into your activity screen if you’ve registered an
activity_link_templateon your partner account (e.g.yourapp://activity/{external_id}) — otherwise it renders the numbers and returns via yourreturn_url. - The link stays valid: athletes can revisit to edit answers.
2. Your UI, our questions (headless)
PATCH /v1/athletes/{id}/settings or athlete create/update. Attribution is required when rendering our questions in your UI (the schema response carries the attribution object, same contract as calculations).
Schema evolution promise: new questions always arrive as recommended, and athletes complete under a schema version keep exact numbers until they next edit their profile or 12 months pass — a schema change will never mass-downgrade your athletes.
3. Saturday app (once, forever)
If the athlete uses the Saturday app with the same email address they have on your platform, their full app onboarding silently powers their numbers on your platform too — live at calculation time, no sync. Their answers are used compute-only and are never exposed through the API; athletes can separately choose to share profile values with you from app settings.4. Pass fields inline
Every calculate call accepts the full profile inline (sweat_level, saltiness, etc. — see Nutrition Calculation). Inline values always win over stored ones. Good for stateless integrations; you carry the data.
Finding athletes to nudge
athlete.profile_completed webhook — it fires exactly once when an athlete crosses into completeness, so you can celebrate in your UI the moment their numbers go exact.