Developer API & webhooks
Every institution gets its own API keys (Administration → API keys). Keys are shown once and stored hashed. All requests use HTTPS and JSON.
Authentication
Authorization: Bearer nsk_your_institution_key
Content-Type: application/jsonInvalid, revoked or malformed keys return 401 and are logged for the platform security team. Suspended institutions receive 403.
Endpoints
GEThttps://nutrientsport-sa.com/api/public/v1/athletes
List the institution's athletes.
{ "athletes": [ { "id": "ext-12", "external_id": "12", "name_en": "Sara Mansour", "name_ar": "سارة منصور", "sport": "Athletics", "discipline": "800 m" } ] }POSThttps://nutrientsport-sa.com/api/public/v1/athletes
Create or update up to 500 athletes, keyed by your own external_id. Only fields you send are changed. Response 202: records are queued and merged into the workspace within seconds while staff are online.
{
"athletes": [
{ "external_id": "12", "name_en": "Sara Mansour", "name_ar": "سارة منصور",
"sex": "female", "age": 21, "height_cm": 168, "weight_kg": 58,
"sport": "Athletics", "discipline": "800 m", "level": "National" }
]
}
→ 202 { "queued": 1, "rejected": [] }POSThttps://nutrientsport-sa.com/api/public/v1/logs
Push training sessions and daily wellness from wearables or club systems (up to 500 per request). Send a source_id to make retries safe — the same source_id is never duplicated.
{
"logs": [
{ "athlete_external_id": "12", "date": "2026-10-24", "source_id": "garmin-883421",
"sessions": [ { "label": "Tempo run", "duration_minutes": 55, "session_rpe": 7, "type": "run" } ],
"body_mass_kg": 57.8, "sleep_hours": 7.5, "wellness": 8,
"watch": { "active_kcal": 620, "steps": 11200, "duration_minutes": 75, "avg_hr": 148, "source": "garmin" } }
]
}
→ 202 { "queued": 1 }POSThttps://nutrientsport-sa.com/api/public/v1/events
Generic event for anything else; recorded in the institution's integration log.
{ "provider": "club", "event": "session.created", "payload": { "id": "abc" } }Outgoing webhooks
Register HTTPS endpoints in Administration → Webhooks. Events: plan.published, log.submitted, athlete.added, training.program.published, training.session.completed, training.pr.achieved. Each delivery carries X-Nutrient-Event and X-Nutrient-Signature = hex HMAC-SHA256(secret, raw body). Failed deliveries retry up to 3 times.
// Node.js verification
import { createHmac, timingSafeEqual } from "node:crypto";
const expected = createHmac("sha256", process.env.NUTRIENT_WEBHOOK_SECRET).update(rawBody).digest("hex");
const ok = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-nutrient-signature"]));Limits & privacy
- Data is strictly separated per institution; a key can only read and write its own institution.
- Max 500 records per request; numeric fields are range-checked and invalid rows are returned in rejected.
- Wearable vendor connectors (Garmin, WHOOP, Polar) and SSO are enabled per contract.