A reference for the Results import wizard. Covers the column list (required vs optional), the validation errors you can hit, and how to fix the rows that fail.
The Racey results importer accepts CSV files in a fixed shape. The wizard at League → Results → Import auto-detects most common header variants (iRacing exports work out of the box), so you usually do not need to rename columns by hand. This guide is the source of truth when auto-detection misses something or when you are building a CSV from scratch.
Quick start
Two ways to grab a template:
- Empty CSV —
/templates/results.csv. Header row only, in canonical order. - Empty CSV pre-filled with your roster —
GET /api/leagues/[leagueId]/import-template?seasonId=[seasonId]. Adds one row per approved registration with the driver name pre-populated and other fields blank. Useful when you already know the field for the round and just need to fill in finishing positions. - Sample CSV with realistic data —
/templates/results-sample.csv. Header row plus ten plausible rows (multiclass GT3+GT4, with a DNF and a DSQ) so you can see the shape.
Save your filled file as UTF-8 CSV with a comma delimiter (the default in Excel, Google Sheets, and Numbers). The importer also accepts JSON if you are pulling from an API; this guide is CSV-focused.
Column reference
The importer recognizes thirteen columns. Auto-detection matches on common header variants — for example, Driver Name, name, display_name, and driver all map to the same field — so do not panic if your existing export uses different labels.
Five columns are required for the import to succeed: every row needs a finishing position, a driver name, a start position, a lap count, and an incident count. Everything else is optional and can be left blank.
| Header | Field | Required | Notes |
|---|---|---|---|
Position | Finish position | Yes | Integer, 1-indexed. Must be at least 1. |
Driver Name | Display name | Yes | Trimmed; non-empty after trim. |
External ID | Cross-system identifier | No | iRacing cust_id, league member ID, etc. Used to remember driver mappings between imports. |
Car Number | Car number | No | String. Leading zeros preserved. |
Start Position | Grid position | Yes | Integer ≥ 1. iRacing 0-indexed positions are auto-bumped to 1. |
Laps Completed | Laps completed | Yes | Integer ≥ 0. |
Laps Led | Laps led | No | Integer ≥ 0. Defaults to 0. |
Incidents | Incident points | Yes | Integer ≥ 0. |
Interval | Time gap to leader | No | String — +3.215 or +1 lap. DNF/DSQ rows often leave this blank. |
Fastest Lap | Fastest lap time | No | m:ss.sss like 2:18.412, raw seconds, or iRacing tenths-of-ms. |
Average Lap | Average lap time | No | Same formats as fastest lap. |
Finish Status | Final status | No | One of running, dnf, dsq, dns. Numeric iRacing reason_out_id is also recognized (0 = running, 29 = dsq, anything else non-zero = dnf). Defaults to running. |
Car Class | Class name for multiclass | No | Must match a class name configured for the season (case-insensitive). Unrecognized class names import the row but leave class assignment empty. |
A handful of additional columns are recognized by auto-detection but are not in the canonical template — Team, iRating, and a qualifying lap time. These are persisted on the result row when present but are not required and are not part of the static template.
Required field details
The wizard's mapping step blocks Next if any of the five required fields is unmapped. The exact missing-field labels you will see come from FIELD_LABELS:
- Finish Position
- Driver Name
- Start Position
- Laps Completed
- Incidents
If your CSV does not contain start positions, fill the column with the same value as Position for each row — the importer treats start = finish as a valid (if unusual) outcome.
Lap time formats
The parser accepts three formats interchangeably for Fastest Lap and Average Lap:
m:ss.sssstrings —2:18.412becomes 138.412 seconds.- Plain seconds —
138.412is taken as-is. - iRacing tenths-of-ms — any number greater than 10000 is divided by 10000, so
1384120becomes 138.412 seconds.
Sentinel values are treated as "no time set":
- Empty string,
0,0:00.000 -159:59.999(iRacing's "did not set a time" sentinel)
Finish status normalisation
The importer normalises Finish Status aggressively because iRacing exports use numeric reason codes and other tools use strings. All of these become running:
- empty / blank
running,finished,0
DNF synonyms (become dnf): dnf, did not finish, ret, retired, disconnected, any other non-zero numeric reason code (except 29).
DSQ synonyms (become dsq): dsq, disqualified, dq, numeric 29.
DNS synonyms (become dns): dns, did not start.
Anything else falls back to running. If you want a row to count as DNF, use one of the strings above.
Wizard flow
After upload, the wizard walks you through four steps:
- Upload — pick a target session and drop or paste your file. Caps: 5 MB and 1000 rows per import.
- Map Columns — auto-detected mappings are pre-selected. Override anything that looks wrong. The Next button is gated on all five required fields being mapped.
- Resolve Drivers — every driver name (and external ID, when present) is matched against your league roster. You confirm fuzzy matches or create an "external driver" row for guests who have no Racey account.
- Review & Import — final preview with a count of importable rows and skipped rows. Click Import to apply.
Driver mappings (external ID → user) are remembered for future imports unless you uncheck the toggle.
Validation errors and how to fix them
Errors fall into three layers: parse errors (CSV cannot be read), mapping errors (rows can be read but key fields are missing or invalid), and import errors (rows passed parsing but the server rejects them).
Parse errors
| Message | Cause | Fix |
|---|---|---|
File is empty | The pasted text or file is empty after trimming. | Paste the data or re-upload. |
CSV file is empty or has no data rows | Header row only, no rows below. | Add at least one data row. |
CSV file has no column headers | The parser could not detect a header row. | Confirm the first line contains comma-separated header names, not data. |
Pasted data is too large — max 5 MB | Paste exceeded the 5 MB cap. | Split the file or upload as a .csv instead of pasting. |
Too many rows — max 1000 per import (got <n>) | Your file has more than 1000 data rows. | Split the file by class or session. The cap mirrors the server-side MAX_IMPORT_ROWS constant. |
Pasted data is too large toast | Same as above (file upload variant). | Same fix; the limit is identical for paste and upload. |
For unsupported file types you get an "Unsupported file type" toast; the importer accepts .csv, .json, and .txt.
Mapping warnings (per row)
These appear in the Review step. The row is dropped from the import but the rest of the file proceeds.
| Warning | Cause | Fix |
|---|---|---|
Row N: Invalid or missing position "<value>" | The mapped position column was empty, non-numeric, or less than 1. | Fix the position cell. iRacing's 0-indexed export is auto-bumped, but null or text is not. |
Row N: Missing driver name | The mapped driver-name column was empty after trimming. | Fill in a name. The importer cannot match an anonymous row. |
Position N appears X times | Two or more rows share the same finish position. | In multiclass races this is expected and informational. In single-class races it indicates a data error — fix the position cell. |
Import errors (server-side)
The server validates the final payload one more time and may reject the whole import:
| Message | Cause | Fix |
|---|---|---|
Session not found | The session ID no longer exists. | Reload the results page and pick a fresh session. |
Cannot import results for a cancelled round. Reschedule or reactivate the round first. | The target round is marked cancelled. | Reactivate the round before importing. |
Cannot import results for a postponed round. Reschedule or reactivate the round first. | Same as above for postponed rounds. | Reschedule the round, then re-import. |
No results with resolved drivers to import | Every row was either skipped or unresolved. | Map drivers in the Resolve step or create external-driver rows for guests. |
Forbidden: results import requires appropriate permissions | You do not have results.import for this league. | Ask a league admin to grant the permission. |
Results for this round are locked. Reopen the result set before making changes. | The round's results were already finalised. | Unlock the result set in the round admin before re-importing. |
Cannot import results for drivers who are not approved for this season: <ids> | One or more rows resolve to a Racey user who is not an approved entrant for the season. | Approve the registrations, or create external-driver rows for the unregistered users. |
Too many imports. Please wait a minute and try again. | You hit the per-user write rate limit (30 / minute). | Wait one minute. |
At least one result is required | The validated payload had zero rows. | Confirm your file has data rows below the header. |
At most 1000 results per import | Server enforcement of MAX_IMPORT_ROWS. | Split the file. |
Failed to import results | Generic catch-all when the database transaction fails. | Retry. If the failure is reproducible, check server logs or contact support. |
Common mistakes
- Empty rows at the bottom of the file. Excel often appends blank rows. The parser skips empty lines, but rows with whitespace in one cell are kept and then fail row-level validation. Trim the file before uploading.
- Header capitalisation. Auto-detection is case-insensitive, but if you handcraft the file, match the canonical headers in the table above for predictability.
- Lap time stored as Excel duration. When Excel detects a time-like value it sometimes converts to a serial fraction (e.g.
0.0958809...). Format the column as text before pasting your times in. - Comma in the driver name. Wrap the cell in double quotes (
"Smith, John"). All sample rows in the templates do this where applicable. - DNF rows with no laps. A driver who didn't start a lap can have
Laps Completed = 0andFinish Status = dnf— both valid. The row will still import as long asPositionis set. - Unrecognized class names. The class column is matched case-insensitively against the season's configured car classes. A typo silently leaves the row's class as null — check your season's class names before importing.
Related
/templates/results.csv— empty template/templates/results-sample.csv— sample data- Manual Result Import Guide — long-form guide for the manual entry flow (no CSV)
- Roster Worksheet Guide — companion sheet for season planning, plus the real roster workflow