Quickstart: Tier 2 (writer)
Tier 2 is everything Tier 1 reads, plus writing training sessions and check-ins your team originates. This assumes the Tier 1 quickstart's token and capability check are already done.
1. Get a Tier 2 token
Your team operator mints one at /team/tokens, same as Tier 1, choosing "Tier 2"
from the tier picker.
2. Create a training session
A create is always observable as 201, distinct from the 200 an
update to the same row would return later (WR-04). person_id names an athlete
your team already has a write-access grant for:
curl -X POST https://xcathletes.org/v1/training-sessions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"person_id": "1a2b3c4d5e6f70819203a4b5c6d7e8f9",
"date": "2026-08-20",
"modality": [{ "system": "xca", "code": "skiing", "display": "Skiing" }],
"technique": "classic",
"duration_seconds": 3600,
"blocks": [{ "reps": 1, "duration_seconds": 3600, "zone": "L2" }]
}' HTTP/1.1 201 Created
Location: /v1/training-sessions/aabbccdd11223344556677889900aabb
ETag: W/"1"
{
"id": "aabbccdd11223344556677889900aabb",
"person_id": "1a2b3c4d5e6f70819203a4b5c6d7e8f9",
"date": "2026-08-20",
"technique": "classic",
"duration_seconds": 3600,
"modality": [{ "system": "xca", "code": "skiing", "display": "Skiing" }],
"blocks": [{ "position": 0, "reps": 1, "duration_seconds": 3600, "zone": "L2" }],
"computed": { "block_seconds": 3600, "seconds_by_zone": { "L2": 3600 } },
"duplicates": [],
"origin_team_id": "01020304050607080910111213141516",
"origin_person_id": "1a2b3c4d5e6f70819203a4b5c6d7e8f9",
"version": 1
} That 201, carrying version: 1 and an ETag, is the
verified outcome: your team originated a row. The Idempotency-Key makes a retried
request safe to resend (WR-01); a later change to this same row needs its current ETag back as If-Match (MW-02), or it answers precondition_required.