Documentation Index
Fetch the complete documentation index at: https://docs.saturday.fit/llms.txt
Use this file to discover all available pages before exploring further.
Batch Operations
Batch endpoints let you perform multiple operations in a single API call. Use these when you need to process a training week, onboard a team, or import historical activities.
Batch calculate
Calculate prescriptions for multiple scenarios at once. Ideal for building “training week” views or “what if” comparisons.
POST /v1/nutrition/calculate/batch
import requests
response = requests.post(
"https://api.saturday.fit/v1/nutrition/calculate/batch",
headers={"Authorization": "Bearer sk_test_abc123def456"},
json={
"athlete_id": "ath_abc123",
"scenarios": [
{
"label": "Monday easy run",
"activity_type": "run",
"duration_min": 45,
"intensity_level": 3,
},
{
"label": "Wednesday intervals",
"activity_type": "run",
"duration_min": 60,
"intensity_level": 7,
},
{
"label": "Saturday long ride",
"activity_type": "bike",
"duration_min": 180,
"intensity_level": 5,
"thermal_stress_level": 7,
},
],
},
)
results = response.json()
for result in results["results"]:
print(f"{result['label']}: {result['carb_g_per_hr']}g carbs/hr")
{
"results": [
{
"index": 0,
"label": "Monday easy run",
"carb_g_per_hr": 30,
"sodium_mg_per_hr": 300,
"fluid_ml_per_hr": 400,
"safety": { "confidence_score": 0.65, "warnings": [], "not_instructions": true }
},
{
"index": 1,
"label": "Wednesday intervals",
"carb_g_per_hr": 55,
"sodium_mg_per_hr": 400,
"fluid_ml_per_hr": 500,
"safety": { "confidence_score": 0.65, "warnings": [], "not_instructions": true }
}
],
"errors": [],
"metadata": {
"total_scenarios": 3,
"successful": 3,
"failed": 0,
"request_id": "req_abc123def456"
}
}
If individual scenarios fail, they appear in errors with the index and error detail. Successful scenarios are still returned — batch operations don’t fail atomically.
Limits
| Constraint | Value |
|---|
| Max scenarios per batch | 50 |
| Rate limiting | Counts as 1 API call per scenario |
Bulk athlete create
Onboard multiple athletes in one call. Useful for team imports or platform migrations.
response = requests.post(
"https://api.saturday.fit/v1/athletes/batch",
headers={"Authorization": "Bearer sk_test_abc123def456"},
json={
"athletes": [
{
"external_id": "user-001",
"name": "Alice Runner",
"weight_kg": 58,
"fitness_level": "advanced",
"primary_sport": "run",
},
{
"external_id": "user-002",
"name": "Bob Cyclist",
"weight_kg": 75,
"fitness_level": "intermediate",
"primary_sport": "bike",
},
{
"external_id": "user-003",
"name": "Carol Triathlete",
"weight_kg": 65,
"fitness_level": "elite",
"primary_sport": "bike",
},
],
},
)
results = response.json()
for athlete in results["created"]:
print(f"Created: {athlete['name']} -> {athlete['id']}")
Limits
| Constraint | Value |
|---|
| Max athletes per batch | 100 |
Duplicate external_id | Error for that item, others continue |
Activity import
Import multiple activities for an athlete at once. Useful for backfilling historical data from other platforms.
POST /v1/athletes/{athlete_id}/activities/import
response = requests.post(
f"https://api.saturday.fit/v1/athletes/ath_abc123/activities/import",
headers={"Authorization": "Bearer sk_test_abc123def456"},
json={
"activities": [
{
"type": "run",
"name": "New Year's Day 10K",
"duration_min": 48,
"intensity_level": 7,
"scheduled_at": "2025-01-01T09:00:00Z",
"thermal_stress_level": 2,
},
{
"type": "bike",
"name": "Weekend group ride",
"duration_min": 150,
"intensity_level": 5,
"scheduled_at": "2025-01-04T08:00:00Z",
},
],
},
)
Imported activities don’t automatically get prescriptions calculated — call the prescription endpoint for each activity that needs one, or let the athlete trigger calculations through your UI.
Error handling in batch operations
Batch operations use partial success semantics. If 3 out of 5 items succeed and 2 fail:
- The 3 successful items are committed
- The 2 failed items are returned in the
errors array with index, error type, and message
- The HTTP status is
200 (not 400) because some items succeeded
{
"created": [
{ "index": 0, "id": "ath_abc123", "name": "Alice Runner" },
{ "index": 2, "id": "ath_def456", "name": "Carol Triathlete" }
],
"errors": [
{
"index": 1,
"error": {
"type": "conflict",
"code": "duplicate_external_id",
"message": "An athlete with external_id 'user-002' already exists"
}
}
]
}
Check both created (or results) and errors arrays to handle the response correctly.