> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anyreach.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Loading rows

> Import a CSV, add rows by hand, and understand the difference between replacing and adding.

Open a table and use the **Import** tab. Drop a CSV or JSON file, click to browse, or paste rows straight into the box.

## What you can load

**CSV** with a header row. The header names must match your declared column names. Cells are converted to the types you declared — `10` becomes a number, `true` becomes a yes/no.

```csv theme={null}
plan_id,name,monthly_price,region,available
pro-eu,Pro,49,EU,true
pro-us,Pro,55,US,true
```

**JSON** as an array of objects. Taken as written, so types are whatever the JSON says.

```json theme={null}
[
  { "plan_id": "pro-eu", "name": "Pro", "monthly_price": 49, "region": "EU", "available": true }
]
```

Files up to 10 MB. Above that, load through a [workflow](/custom-data/keeping-data-fresh) instead — the browser has to hold the whole file in memory to preview it.

## Two ways to apply

This is the important distinction on the page.

<CardGroup cols={2}>
  <Card title="Replace all rows" icon="rotate">
    What you load becomes the table's **entire contents**. Anything missing is deleted.
  </Card>

  <Card title="Add or update these rows" icon="plus">
    Touches only the rows you loaded. Deletes nothing.
  </Card>
</CardGroup>

**Replace** is how a mirror works. If your source drops a product, the product disappears here too, because absence is the signal. It is also the one that can empty your table from a truncated copy-paste.

**Add or update** is for data you own directly — appending this week's codes, correcting a price.

<Warning>
  If you're pasting a partial list — the ten rows you just edited — use **Add or update**. **Replace** would delete the other nine hundred.
</Warning>

## What a truncated paste actually costs

Less than you'd fear, because **nothing is erased**. A row dropped by a bad
replace is marked deleted, not removed — it stops appearing everywhere
immediately, and it comes back on its own the moment you apply a correct
snapshot.

So the recovery from *"I pasted ten rows and deleted nine hundred"* is to paste
the right nine hundred. No support ticket, no backup restore.

That's worth knowing rather than relying on: during the window between the two
applies, your agents genuinely cannot see those rows and will tell callers they
don't exist. Get the file right first.

## The preview

Before you apply anything, you'll see:

* **How many rows** were parsed, and the first five
* **Columns not in the schema** — stored, but invisible to agents until you declare them
* **Duplicate row keys** — with a count and the worst offenders

Duplicates block the import. Two rows sharing a key are the same row, so there's no way to store both — it means the key column is wrong for this data. The message names the values so you can see the pattern:

```
1,421 rows repeat an address already used
#N/A — 7 times
1030 Macarthur Highway, Tarlac City — 2 times
```

## What the result tells you

After applying:

|               |                                                      |
| ------------- | ---------------------------------------------------- |
| **Received**  | rows in what you sent                                |
| **Written**   | rows that actually changed                           |
| **Unchanged** | rows that were already identical                     |
| **Deleted**   | rows removed because they were absent (replace only) |

**Unchanged is the useful number.** Re-applying identical data writes nothing at all — no timestamps move. So if you're syncing on a schedule and every run reports `written: 0`, your data is genuinely stable; the sync isn't broken.

A **type mismatch** warning means a cell didn't match its declared type — a price cell reading `"call us"`. The row is stored as-is rather than rejected: one bad cell in a 5,000-row source shouldn't kill the whole load. Fix it upstream.

## Adding rows by hand

The **Rows** tab has an editor for one row at a time — useful for a correction, not for bulk work.

Two things worth knowing:

* Clearing a field removes that value from the row, rather than storing an empty string.
* Columns you haven't declared are preserved when you edit. Editing a price doesn't discard the twenty other columns that came from your source.

## Deleted rows come back

Deleting a row doesn't erase it — it marks it gone. It stops appearing everywhere immediately, but if the same key shows up in a later import, the row **returns**, even if nothing about it changed.

That's what makes a scheduled mirror safe. A store closed for renovation vanishes from your source, disappears from agent lookups, and comes back on its own when it reopens. You don't reconcile anything.

The one place data is truly erased is deleting the whole table.
