Quickstart: Tier 3 (roster-aware)
Tier 3 adds bringing a new athlete onto your roster: redeeming a join code the athlete already generated, or creating the record yourself when no code exists. Conformance requires trying the join code first (ID-02); create is the fallback, never the default. This assumes the Tier 2 quickstart's token is already in hand, minted at Tier 3.
1. Try a join code
The athlete generates their own join code from the ownership surface. Exercise this step with a code your athlete has shared some other way. The code travels in the request body, never the URL (bearer-material handling, RFC 6750 §2.3):
curl -X POST https://xcathletes.org/v1/join-codes/redeem \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "code": "ATHLETE-JOIN-CODE-1234" }' HTTP/1.1 201 Created
{
"id": "99887766554433221100ffeeddccbbaa",
"person_id": "1a2b3c4d5e6f70819203a4b5c6d7e8f9",
"state": "pending",
"training_access": "read",
"checkins_access": "read"
} state: "pending" and read-only access are the default for every grant that isn't
the person's creating one (GR-07); the athlete accepts it, and may make you the writer, from
their own ownership surface.
2. Fall back to create, only if no code exists
Creating requires the age-floor attestation (FLOOR-01) and hands the birth date over for hashing only; the platform discards the date itself immediately and never returns it (ENT-04):
curl -X POST https://xcathletes.org/v1/people \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"given_name": "Riley",
"family_name": "Sundahl",
"claim_email": "family@example.com",
"birth_date": "2009-04-12",
"attestation": { "floor": "high_school" }
}' HTTP/1.1 201 Created
{
"id": "1a2b3c4d5e6f70819203a4b5c6d7e8f9",
"given_name": "Riley",
"family_name": "Sundahl",
"grant": {
"id": "99887766554433221100ffeeddccbbaa",
"state": "provisional",
"training_access": "write",
"checkins_access": "write"
}
} The creating team's own grant defaults to write, unlike a redeemed one, and starts provisional until the athlete claims the record.
Verified outcome
Either path ends in a 201 carrying a grant. GET /v1/token afterward
shows person_count one higher, confirming the roster now reaches this athlete.