{"openapi":"3.1.0","info":{"title":"Stintsmith API","version":"1.0.0","description":"Public REST API for the Stintsmith. All endpoints require an API key issued by a team admin and are scoped to the issuing team. Rate-limited per key (default 60 req/min). Use the Authorization header: `Bearer lmu_<your-key>`.","contact":{"name":"Stintsmith","url":"https://lmu-portal.example"}},"servers":[{"url":"/api/v1","description":"Default"}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","bearerFormat":"lmu_<base64url>"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"rate_limited"},"message":{"type":"string"},"retryAfterMs":{"type":"integer","nullable":true},"details":{"type":"object","nullable":true,"additionalProperties":true}}}}},"Lap":{"type":"object","required":["id","driverUserId","carId","carClass","trackId","layoutId","lapTimeMs","sectorTimesMs","isValid","recordedAt"],"properties":{"id":{"type":"string","format":"uuid"},"driverUserId":{"type":"string","format":"uuid"},"driverName":{"type":"string","nullable":true},"carId":{"type":"string","format":"uuid"},"carClass":{"type":"string","enum":["Hypercar","LMP2","LMGT3"]},"carMake":{"type":"string"},"carModel":{"type":"string"},"trackId":{"type":"string","format":"uuid"},"layoutId":{"type":"string","format":"uuid"},"lapTimeMs":{"type":"integer"},"sectorTimesMs":{"type":"array","items":{"type":"integer"}},"isValid":{"type":"boolean"},"invalidReason":{"type":"string","nullable":true},"recordedAt":{"type":"string","format":"date-time"}}},"Race":{"type":"object","required":["id","name","trackId","layoutId","scheduledAt","durationMin","format","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"trackId":{"type":"string","format":"uuid"},"layoutId":{"type":"string","format":"uuid"},"scheduledAt":{"type":"string","format":"date-time"},"durationMin":{"type":"integer"},"format":{"type":"string"},"status":{"type":"string"}}},"Driver":{"type":"object","required":["id","name","role"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"countryCode":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"isPublicProfile":{"type":"boolean"},"role":{"type":"string"},"joinedAt":{"type":"string","format":"date-time"}}},"LapPage":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lap"}},"nextCursor":{"type":"string","nullable":true}}},"RacePage":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Race"}},"nextCursor":{"type":"string","nullable":true}}}},"parameters":{"Cursor":{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor returned in `nextCursor` on the previous page."},"Limit":{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}},"responses":{"Unauthorized":{"description":"Missing, malformed, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests. Includes `Retry-After` (seconds) and `X-RateLimit-*` headers.","headers":{"Retry-After":{"schema":{"type":"integer"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"security":[{"ApiKey":[]}],"paths":{"/laps":{"get":{"summary":"List laps shared with the caller's team","operationId":"listLaps","security":[{"ApiKey":["laps:read"]}],"parameters":[{"name":"car_class","in":"query","schema":{"type":"string","enum":["Hypercar","LMP2","LMGT3"]}},{"name":"track_layout_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"valid_only","in":"query","schema":{"type":"string","enum":["true","false"],"default":"true"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Paginated lap list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LapPage"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/laps/{id}":{"get":{"summary":"Get a single lap by ID","operationId":"getLap","security":[{"ApiKey":["laps:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Lap detail.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Lap"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Not found."},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/races":{"get":{"summary":"List races for the caller's team","operationId":"listRaces","security":[{"ApiKey":["races:read"]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Paginated race list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RacePage"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/races/{id}":{"get":{"summary":"Get a single race by ID","operationId":"getRace","security":[{"ApiKey":["races:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Race detail.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Race"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Not found."},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/leaderboards":{"get":{"summary":"Top-N hotlap leaderboard for a track layout","operationId":"getLeaderboard","security":[{"ApiKey":["leaderboard:read"]}],"parameters":[{"name":"layout_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"car_class","in":"query","schema":{"type":"string","enum":["Hypercar","LMP2","LMGT3"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Ordered list of laps, fastest first.","content":{"application/json":{"schema":{"type":"object","required":["data","total"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lap"}},"total":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/drivers":{"get":{"summary":"List members of the caller's team","operationId":"listDrivers","security":[{"ApiKey":["drivers:read"]}],"responses":{"200":{"description":"All drivers on the team.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Driver"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}}}}