| title | Quickstart |
|---|---|
| description | Your first prescription, start to finish |
| sidebarTitle | Quickstart |
Self-serve: sign up at saturday.fit/api for $5.39/month, no contract. Your key is revealed once after checkout and emailed to you. An AI agent can do this for you: POST /v1/signup (no auth) returns a hosted checkout link. Not sure self-serve is your lane? See Getting Access.
Platform partners: keys come with your agreement. Contact api@saturday.fit.
Keys carry an environment prefix. Production keys start with sk_live_, sandbox keys with sk_test_, and the two are not interchangeable: a sandbox key does not authenticate against production. See Authentication for what each environment does and which base URL it uses.
The examples below read the key from a SATURDAY_API_KEY environment variable, so the same code runs against either environment:
export SATURDAY_API_KEY="sk_live_..."The prescription endpoint takes activity parameters and returns fuel, hydration, and sodium targets. Only activity_type and duration_min are required; everything else sharpens the result.
curl -X POST https://api.saturday.fit/v1/nutrition/calculate \
-H "Authorization: Bearer $SATURDAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"activity_type": "run",
"duration_min": 90,
"intensity_level": 5,
"athlete_weight_kg": 70,
"thermal_stress_level": 6
}'import os
import requests
response = requests.post(
"https://api.saturday.fit/v1/nutrition/calculate",
headers={
"Authorization": f"Bearer {os.environ['SATURDAY_API_KEY']}",
"Content-Type": "application/json",
},
json={
"activity_type": "run",
"duration_min": 90,
"intensity_level": 5,
"athlete_weight_kg": 70,
"thermal_stress_level": 6,
},
)
data = response.json()
print(data)const response = await fetch(
"https://api.saturday.fit/v1/nutrition/calculate",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SATURDAY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
activity_type: "run",
duration_min: 90,
intensity_level: 5,
athlete_weight_kg: 70,
thermal_stress_level: 6,
}),
}
);
const data = await response.json();
console.log(data);Saturday publishes SDKs for Python and TypeScript:
pip install saturdaynpm install @saturdayinc/sdkimport os
from saturday import Saturday
client = Saturday(api_key=os.environ["SATURDAY_API_KEY"])
result = client.nutrition.calculate(
activity_type="run",
duration_min=90,
intensity_level=5,
athlete_weight_kg=70,
thermal_stress_level=6,
)
print(result)import Saturday from "@saturdayinc/sdk";
const client = new Saturday({ apiKey: process.env.SATURDAY_API_KEY });
const result = await client.nutrition.calculate({
activity_type: "run",
duration_min: 90,
intensity_level: 5,
athlete_weight_kg: 70,
thermal_stress_level: 6,
});
console.log(result);Both SDKs default to https://api.saturday.fit and accept a base URL override (base_url in Python, baseUrl in TypeScript) for sandbox work.
A successful response returns a prescription with safety metadata:
{
"tier": "full",
"carb_g_per_hr": 60.0,
"sodium_mg_per_hr": 600.0,
"fluid_ml_per_hr": 620.0,
"total_carb_g": 90,
"total_sodium_mg": 900,
"total_fluid_ml": 930,
"safety": {
"max_safe_fluid_ml_per_hr": 1500,
"max_safe_sodium_mg_per_hr": 3000,
"confidence_score": 0.72,
"requires_human_review": false,
"warnings": [],
"not_instructions": true
},
"attribution": {
"text": "Powered by Saturday",
"logo_url": "https://saturday.fit/logo.png",
"link": "https://saturday.fit",
"required": false
}
}| Field | What it means |
|---|---|
tier |
"full" for exact numbers, "teaser" for ranges |
carb_g_per_hr |
Carbohydrate target in grams per hour |
sodium_mg_per_hr |
Sodium target in milligrams per hour |
fluid_ml_per_hr |
Fluid target in milliliters per hour |
total_* |
Totals across the whole activity duration |
safety.max_safe_*_per_hr |
Hard ceilings the prescription is held under |
safety.confidence_score |
Confidence in this prescription, 0.0 to 1.0 |
safety.requires_human_review |
Set when the case warrants a dietitian's eyes |
safety.warnings |
Safety warnings for this prescription |
safety.not_instructions |
Marks the prescription as guidance, not commands |
A response may also carry a precision object describing which profile fields are still missing and how much they widen the answer. See Onboarding for how to collect them.
tier reflects the athlete's subscription and trial status, not your key's environment. A request with no athlete attached returns full precision.
| Athlete status | What they get | Example |
|---|---|---|
| Subscribed or in trial | Exact numbers | "carb_g_per_hr": 60.0 |
| Free | Ranges | "carb_range_g_per_hr": "60-90" |
Teaser responses carry a subscription_cta field, and their attribution.required is true:
{
"tier": "teaser",
"carb_range_g_per_hr": "60-90",
"sodium_range_mg_per_hr": "500-1000",
"fluid_range_ml_per_hr": "500-1000",
"attribution": {
"text": "Powered by Saturday",
"logo_url": "https://saturday.fit/logo.png",
"link": "https://saturday.fit",
"required": true
},
"subscription_cta": {
"message": "Get your exact carb, sodium, and fluid targets, not ranges",
"subscribe_url": "https://saturday.fit/subscribe?ref=YOUR_PARTNER_ID",
"features": [
"Exact gram/mg/mL targets per hour",
"Personalized product picks inside the app",
"Personalized fueling plan",
"15+ tuning factors"
]
}
}See Freemium Model for how the tiers are decided and how the subscribe loop pays you.
[Athletes](/guides/athletes) stores athlete settings (weight, sweat level, preferences) so calculations stop relying on defaults. [Safety](/guides/safety) covers the safety model and the ceilings above. [Activities](/guides/activities) creates activities, attaches prescriptions, and collects post-session feedback. [Authentication](/authentication) covers swapping a `sk_test_` key and its sandbox base URL for a `sk_live_` key against `api.saturday.fit`.