For most ranches starting on CattleIQ, the first step is bringing records over from existing spreadsheets. That's what the importer does, and this guide walks you through using it.
We're here to help
Spreadsheet prep can be squirrely. We can help, just open a support ticket and we'll send you a quote.
Default
If you've only got a handful of records, adding them by hand is likely faster than preparing a spreadsheet for import.
Turning it on
Go to Settings > Ranch Account > Import/Export. There's a single toggle: Enable Data Import. Turn it on. Two things change:
- An Import button appears in the page actions of the Animals view.
- An Export button appears in the page actions of any report and on workday pages.
Building your spreadsheet
The importer reads a flat spreadsheet with a specific set of columns, and the work is in getting your spreadsheet to match. This section walks through the columns, starting with what every animal needs and building up to events and genetics.
What to know
Before you start, a few universal rules:
- Column names are case-insensitive.
id[0].idandID[0].IDare the same column. - Whitespace inside column names is ignored.
- Date columns accept ISO format (
2026-04-22) or native spreadsheet dates. - Set up your Identifier Types and Labels in CattleIQ before you import. Rows referencing unknown ones will fail or skip.
- Values for sex, status, classification, labels, identifier types, breeding method, and pregnancy status match your account's labels without case sensitivity, and with whitespace trimmed. Partial matches don't work.
- To add multiple events for one animal, repeat its
id[0].idandid[0].typeon each event row so it can be mapped to the correct animal. - Core/base fields only need to appear on one row per animal; the importer collects all rows for an identifier and figures out the establishing values from across them. Row order doesn't matter.
- If you do repeat core fields across rows, they have to match. Mismatches error the row out, which is your safety net for typos.
Core columns
An animal record needs three things: an identifier, an identifier type, and a sex. Everything else is optional or defaulted.
id[0].id | id[0].type | sex | status | class | birth |
|---|---|---|---|---|---|
| M103 | Tag | Male | Active | Bull | 2025-04-12 |
| F087 | Tag | Female | Active | Cow | 2023-03-18 |
id[0].idandid[0].type: the animal's primary identifier (the ID itself paired with its type). Required.sex: Female, Male, or Neutered male. Required.status: Active, Inactive, or Reference. Defaults to Active.class: the animal's classification (Bull, Cow, Calf, etc.). Must match an entry in your account's classifications.birth: date of birth in ISO format or as a spreadsheet date.
Additional identifiers
Many ranches carry more than one ID per animal. Use indexed columns for additional identifiers:
id[0].id | id[0].type | id[1].id | id[1].type | id[2].id | id[2].type |
|---|---|---|---|---|---|
| M103 | Tag | 18M004 | Bangs | R12345 | Registration |
| F087 | Tag | 18M092 | Bangs |
The first identifier (id[0]) is the animal's primary. Additional ones (id[1], id[2], and so on) are searchable but secondary. Each ID-and-type combination has to be unique across the herd.
Labels
Apply labels using indexed columns:
id[0].id | id[0].type | label[0] | label[1] | label[2] |
|---|---|---|---|---|
| M103 | Tag | Sire | South pasture | |
| F087 | Tag | Replacement heifer | South pasture | Triple J |
Each label has to match a label you've created in your account; the importer doesn't auto-create labels. Empty cells are fine. See Using labels for the broader system.
Lineage
Lineage columns reference parent animals by their primary identifier:
id[0].id | id[0].type | dam.id | dam.id-type | sire.id | sire.id-type | grafteddam.id | grafteddam.id-type |
|---|---|---|---|---|---|---|---|
| F125 | Tag | F087 | Tag | M103 | Tag | ||
| F126 | Tag | F087 | Tag | M103 | Tag | F099 | Tag |
If a referenced parent doesn't already exist in the file or your account, the importer creates a placeholder for it with Reference status. Use grafteddam.* for a cow that raised but didn't birth a calf.
Events
Events use the multi-row pattern. Repeat the animal's id[0].id and id[0].type for each event, and use the event columns for the date and details. The animal's core fields don't need to appear on event rows; they get picked up from whichever row in the file establishes them.
Weight events. Repeat the row per measurement.
id[0].id | id[0].type | weight.date | weight.weight |
|---|---|---|---|
| M103 | Tag | 2026-04-22 | 685 |
| M103 | Tag | 2026-05-10 | 720 |
Bred events. bred.enddate is for breeding windows that span multiple days. bred.method is AI, Natural, etc. bred.sire.* references the sire's primary identifier.
id[0].id | id[0].type | bred.date | bred.enddate | bred.method | bred.sire.id | bred.sire.id-type |
|---|---|---|---|---|---|---|
| F087 | Tag | 2026-05-01 | 2026-05-15 | AI | M103 | Tag |
Pregnancy checks. preg.status is the result of the check.
id[0].id | id[0].type | preg.date | preg.status |
|---|---|---|---|
| F087 | Tag | 2026-07-15 | Pregnant |
Sales. One sale per animal.
id[0].id | id[0].type | sale.date |
|---|---|---|
| M103 | Tag | 2026-11-08 |
Deaths. One death per animal. death.text is optional, for cause or notes.
id[0].id | id[0].type | death.date | death.text |
|---|---|---|---|
| F088 | Tag | 2026-09-30 | Calving complication |
Notes. note.text is the body of the note. Multiple notes per animal are fine.
id[0].id | id[0].type | note.date | note.text |
|---|---|---|---|
| F087 | Tag | 2026-05-12 | Limping after fence damage |
Genetics
If genetics is enabled in your account (see Genetics), the importer also accepts genetic trait columns. .value is the EPD; .rank is the percentile.
id[0].id | id[0].type | bw.value | bw.rank | cem.value | cem.rank |
|---|---|---|---|---|---|
| M103 | Tag | 1.2 | 35 | 8 | 60 |
Available traits include birth weight (bw), calving ease maternal (cem), and others. The Genetics doc has the full list. Breed composition uses egbc.<breed> columns: egbc.an for Angus, egbc.he for Hereford, and so on.
Running the import
Once your spreadsheet is ready, the rest is a few clicks.
Pick the file
From the Animals page, click Import. Pick your file (.csv, .xls, .xlsx, or .xlsm). If the workbook has multiple sheets, you'll be asked which one to import from.
Click Review import data. The app analyzes the file and shows you a preview before anything commits.
Review the preview
The preview is the part where most issues surface. You'll see a summary at the top:
- How many rows have errors and won't be imported
- How many rows have warnings (will be imported, but flagged for your review)
- How many new animals will be created
- How many existing animals will be updated
Below that, a sortable, filterable table shows every row with its status (Fail, Create, or Update). Each row that has problems can be expanded to see the specific error or warning messages.
Common errors:
- Missing identifier: rows with no usable ID column can't be matched or created.
- Invalid identifier type:
id[0].typedoesn't match a type in your Identifier Types list. - Ambiguous match: the row's identifier matches more than one existing animal.
- Invalid sex / status / classification: the value doesn't match an item in the corresponding list.
- Conflicting data: two rows reference the same animal but disagree (e.g. different dams).
Common warnings:
- Skipped column names: the header is unrecognized; data in that column won't import.
- Sex/classification mismatch: e.g. an animal marked female with a male-specific classification.
- Pregnancy event on a non-female: imported as the animal record, but the event itself is dropped.
Fix what you can in your source spreadsheet, re-upload, and re-run. The errors and warnings tell you exactly what's wrong, so iterating gets fast once you've gotten the file mostly right.
Confirm and commit
When the preview looks good, check the boxes for what you want to do (create new animals, update existing animals, or both) and click Create and update animals.
The import runs in the background with a progress bar. Successful rows commit; failed rows are skipped. If anything fails, you'll see a summary at the end with the row numbers and the failure reasons.
What re-importing does
If you re-import a row whose primary identifier matches an existing animal, the importer updates that animal rather than creating a duplicate. Any non-empty value you supply overwrites the existing field; blank cells or omitted columns leave existing values alone. New events get appended, and exact duplicates are skipped, so re-importing the same row twice won't double up.
So you can iterate: import once to bring records over, then re-import later to add events or corrections without recreating anything. If you're only adding events, leave the core fields out of your re-import file. Any stray value in a column like sex, status, dam.id, or birth would overwrite the existing data.
Exporting
Once Import/Export is enabled, Export shows up on report pages and workday pages.
Click Export, confirm the count, and the app generates an XLSX file (animals.xlsx) with seven sheets:
- Animal Records: one row per animal in the result set, with all identifiers, sex, status, lineage references, labels, and (if enabled) full genetic data
- Weight Events, Bred Events, Pregnancy Check Events, Notes, Sales, Deaths: one row per event for the animals in the export
The export reflects the current view. Whatever's in the report or workday after base filters and exposed filters apply is what you'll get. If you've selected specific rows, only those animals are exported.
The export columns line up with the import schema, which means an export is also a valid input file. Useful for backups, for sharing with a vet or accountant, or for moving data to a tool the import doesn't support.
What's next
Importing is the foundation for the other workflows in CattleIQ. Once your records are in, App tour and setup covers the orienting tour, Building reports covers the analytics, and Genetics covers the specific case of bringing in genetic test results.