CSV Import & Export
Bring records into a collection from a CSV with guided field mapping and validation, and export the whole collection back out to a file.
Content doesn't always start in the admin. A client sends a spreadsheet of products, a legacy system dumps a CSV, or you need to hand someone the current data to review. Every collection list page has a built-in CSV importer and exporter for exactly this: import walks you through mapping columns and validating rows before anything is written, and export flattens the whole collection into a single file.
By the end of this page you should know how the import wizard maps and validates data, how images and links are handled, and what an export contains.
Importing a CSV
Open any collection list and click Import CSV in the toolbar — it appears only if you have create access for that collection. The wizard runs in a few steps: upload, map, preview, import, done.
Upload and map
Drop a UTF-8 .csv with a header row onto the upload zone. Blank rows are skipped automatically.
Next, map each CSV column to a collection field. The wizard auto-maps columns whose header matches a field name (case-insensitive), so usually you're just confirming its guesses. Set columns you don't need to Ignore field. Only writable fields appear in the dropdowns — system fields (id, createdAt, updatedAt) and virtual fields (join, row) are excluded.
Preview and validate
Before importing, the wizard shows the first 20 rows with their mapped values and validates each cell against its field type:
| Field type | Validation | Stored as |
|---|---|---|
text, textarea, richText, email, json | Passed through as a string | String |
number | Parsed as a number; thousands separators and currency symbols stripped | Number |
boolean | Accepts true/false, yes/no, 1/0 (case-insensitive) | Boolean |
date / datetime | Must parse to a valid date/datetime | ISO string |
select, radio | Must match one of the field's option values | String |
url | Must be a valid absolute URL | External-link object |
image | Must be a valid absolute URL (see below) | Media document ID |
Rows with any error are highlighted and skipped during import — not aborted. You can import the valid rows and fix the rest later.
How images and links are handled
Two field types do more than store the string:
image— the wizard fetches the URL at import time, uploads the file to your configured media collection, and stores the resulting document ID (not the original URL). So the image must be publicly reachable when you import, it lands in your configured storage adapter and is resized if you've set image sizes, and a failed fetch marks that row as a failure.url— stored as an external-link object with an empty label, which you can fill in later from the edit form.
Numbers
The importer is forgiving about number formatting: thousands separators (1,000), and currency prefixes or suffixes ($99.99, ₦5,000, €1.200) are all accepted. Everything except the decimal point is stripped before parsing, and the result must be a finite number — values like N/A or — fail validation.
Finishing, and fixing failures
Rows are imported one at a time with a live success/failure count. A row fails if a required field is blank, a value doesn't pass type validation, an image can't be fetched, or the API rejects the document (for example, a unique-constraint violation). Failures never stop the run — every valid row is created.
If any rows failed, a Download Errors CSV button appears. It's the original rows plus an _error column explaining each failure, so you can fix just those and re-import them. Note there's no upsert: re-importing sends fresh create requests, so importing the same rows twice creates duplicates.
Exporting a CSV
Click Export CSV on any collection list (read access is all it needs). The file downloads as {collection-slug}-export.csv once every page has been fetched.
An export always includes every record in the collection and these columns:
| Column | Contents |
|---|---|
ID | The document's id |
| Visible fields | Every field except password, hidden fields, and virtual join/row fields |
Last Updated | The updatedAt timestamp |
Complex values are flattened for the file: media becomes the file's storage URL, a relationship becomes the related document's title/name/label (falling back to its ID), arrays are joined with ; , and other objects are JSON-stringified.
Export CSV ignores the current search and filters — it always returns the whole collection. For a subset, you have two options: select the rows you want and use Export Selected from the bulk-actions bar (see The Collection List), or for a query-driven export, fetch the collection with the SDK and build the CSV from the result.
Exporting only selected rows
When you don't want the whole collection, select rows on the list with the checkboxes and click Export Selected in the bulk-actions bar. It downloads just those records, with the same columns and value flattening as a full export, to {collection-slug}-export-selected.csv. It's the fastest way to hand off an ad-hoc subset without writing any code.
Recommended path
Use Import CSV to seed or bulk-load a collection — lean on the preview step to catch mapping and validation problems before anything is written, and keep the errors CSV to fix failures in a second pass. Use Export CSV for a full snapshot of a collection; when you need only part of it, export programmatically with the SDK.
Server-side integration
Preview drafts on a server-rendered or statically generated frontend that can't receive postMessage — the admin hands your page a short-lived signed token, and your server redeems it for the draft.
Custom Admin Panel Location
Mount the embedded admin at whatever route you want by placing its component where your framework's router expects a page.