Other
Overview
ApexLog is a track day logbook for drivers. Connect it to ChatGPT and ask about your own driving history in plain language: compare two laps sector by sector, see where you lost time, pull the setup and tyre state you ran at an event, check how many laps are on a set of pads or tyres, or read the GPS trace of your best lap — including OBD channels such as fuel and temperatures when they were logged. It holds the full context around your laps — vehicle, tyre model and age, per-session setup, component wear, weather and track — so the assistant answers with your real data. The connector is read-only and scoped to your own account; it never changes or deletes anything. You bring your own ChatGPT plan, so there are no question limits.
Tools
Compares two laps (possibly from different sessions) with a per-sector time delta table computed server-side from GPS telemetry — the cheap way to answer 'where am I losing time'. Sectors are equal-distance splits of each lap's GPS distance, not official timing sectors. Lap numbers default to each session's best lap. Positive sector delta means lap B was slower there.
compare_laps
ChatGPTCompares two laps (possibly from different sessions) server-side from GPS telemetry. It answers both 'where am I losing time' (sectors) and 'why' (corners). sectors: per-sector time delta table. When the track has sector gates (harvested from the RaceChrono track definition), sectors are timed at real gate-line crossings and sectorCount is ignored; otherwise sectors are equal-distance splits of each lap's GPS distance, not official timing sectors. The response's sectorSource/note say which applied. corners: one row per corner (C1..Cn in lap order) detected from lap A's GPS path geometry and matched on lap B by position, with per-lap brakeStartM (where speed starts falling into the corner; null = no braking zone of its own), entryKph, minKph, apexM (where the minimum speed occurred), gearAtBrake/gearAtApex, throttleOnM (first sustained throttle application after the apex — 20% of the lap's pedal range), exitKph (at one place on both laps, 100 m after lap A's apex) and peakLatG, plus timeDeltaMs through the corner. Grip per corner and lap: peakCombinedG, utilization (peakCombinedG divided by the session's grip envelope at that speed; gripEnvelope is the 98th percentile of combined G per 20 km/h bin, i.e. what was reached that day, not a theoretical limit — about 1 is normal, clearly lower means less combined G was reached there than elsewhere in the session at that speed, which is also true for a flat-out kink), overlapMs (trail braking: time braking and cornering both exceed 0.3 g before the slowest point) and combinedGDip (how far combined G fell below the envelope between the hardest braking and the hardest cornering; a large dip with a short overlap means the brake was released before turn-in). cornerLatGSource is the same for both laps: imu (calibrated accelerometer), source (the recorder's own channel) or gps (derived from the GPS path, coarser: its overlapMs reads about 0.3 s longer than imu, and differences under 0.5 s are noise). Grip fields are absent when the GPS is slower than 4 Hz (phone GPS) and across data gaps. All corner distances are on lap A's distance axis, so 'B braked 18 m later' reads directly; gear/throttle are null when the session has no such channel. Lap numbers default to each session's best lap. Positive deltas mean lap B was slower.
get_lap_telemetry
ChatGPTGPS telemetry trace for one lap of a session. Default response is downsampled to roughly one point per 10 m of travelled distance with [timeMs, distanceM, speedKph, lat, lon] per point — compact enough to analyze in-context. Set raw=true only when you genuinely need full resolution and every channel (altitude, g-forces, rpm); it is much larger. Omit lapNumber to get the session's best lap.
get_lap_telemetry
ChatGPTGPS telemetry trace for one lap of a session. Default response is downsampled to roughly one point per 10 m of travelled distance with [timeMs, distanceM, speedKph, lat, lon] per point — compact enough to analyze in-context. To see driver inputs, pass channels (e.g. ["gear", "throttle_position", "rpm"]): each requested channel becomes an extra column with the sample nearest in time to every downsampled point — this is the preferred way to get gear, throttle, brake-related or OBD data. Without channels the response lists availableChannels (names + units) for this session. Set raw=true only when you genuinely need full resolution and every channel (altitude, g-forces, rpm, and all stored side channels as sparse extra columns at their own rate); it is much larger. Omit lapNumber to get the session's best lap.
get_photos
ChatGPTReturns the user's photos for one entity as viewable images (downscaled JPEGs), so wear and condition can be assessed visually — e.g. brake disc lips/scoring or tire surface on a component installation, paddock/car photos on a session, detail shots on a setup. Returns the newest photos first (default 4, max 10 per call) with a metadata block per photo. Entities with photos are flagged via photoCount in list_vehicles and get_session.
get_photos
ChatGPTReturns the user's photos for one entity as viewable images (downscaled JPEGs), so wear and condition can be assessed visually — e.g. brake disc lips/scoring or tire surface on a component installation, paddock/car photos on a session, detail shots on a setup, day-level shots like official timing boards on a track day. Returns the newest photos first (default 4, max 10 per call) with a metadata block per photo. Entities with photos are flagged via photoCount in list_vehicles and get_session.
get_session
ChatGPTFull context for one session: all laps with times and validity, the complete setup snapshot (tires, pressures, brakes, suspension, alignment, fuel), weather/track conditions, wear state of the tire and brake sets that were installed, session notes, linked onboard video links (YouTube), and a telemetry availability summary. Use list_sessions first to find the session id. Session, setup, and installed components each carry a photoCount; when > 0, get_photos returns the actual photos as viewable images.
get_session
ChatGPTFull context for one session: all laps with times and validity, the complete setup snapshot (tires, pressures, brakes, suspension, alignment, fuel), weather/track conditions, wear state of the tire and brake sets that were installed, session notes, the driver's own point annotations anchored to telemetry moments (e.g. 'blocked by traffic' with the lap it happened on; source 'videoAudio' marks a verbatim transcript of the driver's spoken comment from the onboard video, 'manual' a typed note), linked onboard video links (YouTube), and a telemetry availability summary. Use list_sessions first to find the session id. Session, setup, installed components, and the track day each carry a photo count; when > 0, get_photos returns the actual photos as viewable images (day-level photos: scope 'trackday' with trackDayId).
get_session_events
ChatGPTMachine-detected events for a session, three kinds, ordered by anchorMs (ms from the start of the session's telemetry, the time base of annotations; timeMs is ms from the lap's first sample). rotation_deviation: places where a lap's yaw rate differed clearly from the session's other laps at the same position, from the calibrated gyro against the GPS path. The deviation has a sign: positive extraYawDps = the lap rotated more in the turn direction than the other laps (the rear stepping out can look like this), negative = it rotated less (a yaw collapse, e.g. after a catch or countersteer, can look like this). Each gives the lap, timeMs, distanceM, lat/lon, speedKph, durationMs, extraYawDps (peak deviation, in the direction of the turn), bodyYawDps and baselineYawDps. referenceM is the position on a common reference line, so events from different laps at the same corner share it. mountUncertain=true means the recorder's mount was different from the session's dominant mount at that moment, so the event may come from the device moving. rpm_near_max: rpm held at or above 98 % of the session's highest rpm for at least 600 ms at speed (rpm = peak in the run, sessionMaxRpm); only for sessions reaching 4000 rpm. It is relative to the session, not a rev limiter reading. temperature_peak: one per temperature channel (channel, peak, first reading) at the first moment it held its session maximum, only when it rose; no threshold, not a 'too hot' judgement. These are facts, not a diagnosis: a kerb, a bump or a correction can look like a rotation event, and understeer cannot be detected. An event is a detector output, not a note by the driver, so check a rotation event against what the driver remembers or the onboard video before presenting it as a slide. Rotation needs a recording with a gyro, calibrated IMU data on the lap and GPS of at least 10 Hz, and at least four analysable laps; lapsSkipped says which laps could not be analysed for rotation and why.
get_track_day
ChatGPTWhole track day in one call: date, track, vehicle, organizer, day-level weather and notes (e.g. official results the driver wrote down), day photo count (get_photos scope 'trackday' returns the images — often timing-board or results screenshots), onboard video links, and a summary of every session that day (lap count, best lap, telemetry availability, photo count). Use the trackDayId from list_sessions or get_session. Drill into one session with get_session for setup, laps and wear context.
get_track_day
ChatGPTWhole track day in one call: date, track, vehicle, organizer, day-level weather and notes (e.g. official results the driver wrote down), day photo count (get_photos scope 'trackday' returns the images — often timing-board or results screenshots), onboard video links, and a summary of every session that day (lap count, best lap, telemetry availability, photo count). Use the trackDayId from list_sessions or get_session. Drill into one session with get_session for setup, laps and wear context.
list_sessions
ChatGPTLists the user's track sessions, newest first. Filter by track name (substring match), vehicle id, and/or date range. Each entry has the session id (use with get_session, get_lap_telemetry, compare_laps), date, track, vehicle, lap count, best lap time, weather, whether GPS telemetry is available and whether onboard video links exist.
list_sessions
ChatGPTLists the user's track sessions, newest first. Filter by track name (substring match), vehicle id, and/or date range. Each entry has the session id (use with get_session, get_lap_telemetry, compare_laps), the track day id (use with get_track_day and get_photos scope 'trackday'), date, track, vehicle, lap count, best lap time, weather, whether GPS telemetry is available and whether onboard video links exist. The response includes totalMatching and truncated — when truncated is true, re-query with a higher limit (max 100) to see the remaining sessions. When onboarding.state is 'empty_account', explain that the connection is ready and surface both the importUrl and demoUrl actions instead of replying only that no sessions were found.
list_vehicles
ChatGPTLists the user's vehicles with total track mileage, the most recent setup snapshot (tires, pressures, alignment, brakes), and currently installed wear-tracked components (tire sets, brake pads, brake discs) including km/laps accrued and latest tread depth measurements. Each component has a photoCount; when > 0, get_photos(scope='component', id) returns viewable wear photos of that set.
list_vehicles
ChatGPTLists the user's vehicles with total track mileage, the most recent setup snapshot (tires, pressures, alignment, brakes), and currently installed wear-tracked components (tire sets, brake pads, brake discs) including km/laps accrued and latest tread depth measurements. Each component has a photoCount; when > 0, get_photos(scope='component', id) returns viewable wear photos of that set. When onboarding.state is 'empty_account', explain that the connection is ready and surface both the importUrl and demoUrl actions instead of replying only that no vehicles were found.






