Shot Data Model
A Shot is the record Element produces for a single struck ball.
DRAFT
Field names, units, and which metrics are measured vs. derived are all placeholders.
Ball data
| Field | Type | Unit | Notes |
|---|---|---|---|
ballSpeed | number | mph | TODO |
launchAngle | number | degrees | TODO |
launchDirection | number | degrees | Negative left, positive right — TODO confirm |
backSpin | number | rpm | TODO |
sideSpin | number | rpm | TODO |
spinAxis | number | degrees | TODO |
Club data
| Field | Type | Unit | Notes |
|---|---|---|---|
clubSpeed | number | mph | TODO |
clubPath | number | degrees | TODO |
faceAngle | number | degrees | TODO |
attackAngle | number | degrees | TODO |
smashFactor | number | ratio | Derived: ballSpeed / clubSpeed |
Calculated flight
| Field | Type | Unit | Notes |
|---|---|---|---|
carryDistance | number | yards | TODO — state the atmospheric model |
totalDistance | number | yards | TODO |
apex | number | feet | TODO |
offline | number | yards | TODO |
Metadata
| Field | Type | Notes |
|---|---|---|
id | string | Unique shot ID |
sessionId | string | Session this shot belongs to |
timestamp | string | ISO 8601, UTC |
club | string | null | Club selected in the app, if any |
confidence | TODO | TODO: how a low-confidence reading is signalled |
Example
json
{
"id": "shot_TODO",
"sessionId": "sess_TODO",
"timestamp": "2026-01-01T00:00:00Z",
"club": "7i",
"ball": {
"ballSpeed": 0,
"launchAngle": 0,
"backSpin": 0
},
"club_data": {
"clubSpeed": 0,
"clubPath": 0,
"faceAngle": 0
}
}Missing values
TODO: Explain what happens when a metric can't be measured — is the field null, omitted, or estimated?