CSV format
The columns Resurf reads when it imports a CSV, and the exact values each one takes.
- Required
- A type column
- Lists
- Separated by ;
- On
- Mac
How Resurf reads the file
The first line names the columns. Every line after it is one capture. Resurf matches columns by their exact name, in any order, and ignores columns it doesn't know, so you only need the ones you use.
The only required column is type. Blank lines are skipped. In messages, the header is row 1, so your first capture is row 2.
Download the template CSV to start from a file that already imports.
A small example
Three captures: a link, a note whose text is in a Markdown file, and an image. The note and image files sit in folders next to the CSV, and their paths are relative to the CSV's folder.
my-import/
captures.csv
notes/launch-checklist.md
assets/board.pngtype,title,source_url,user_note,tags,spaces,created_at,note_path,asset_path
link,How to price a product,https://example.com/pricing,Read before the launch,pricing;research,Research,2024-03-01T09:30:00Z,,
note,Launch checklist,,,launch,Projects,2024-03-02T18:00:00+01:00,notes/launch-checklist.md,
image,Mood board,https://example.com/board,,design;inspiration,Design,2024-03-03T12:00:00Z,,assets/board.pngEmpty cells are fine. The link gets a Note, two tags and a space. The note's date uses a time zone offset; the others use Z for UTC.
Columns you'll use
| Column | What it holds | Example |
|---|---|---|
type | Required. The kind of capture, one of the values below, exact case. | link |
title | The capture's title. | How to price a product |
source_url | Where it came from. For a link, the link itself. | https://example.com |
description | Short text under the title. | A long look at pricing. |
user_note | Your own Note on the capture, written in the cell. | Read before the launch |
tags | Tag names separated by semicolons. | pricing;research |
spaces | Space names separated by semicolons, matched by name in any case. | Research;Ideas |
created_at | When it was saved, as an ISO 8601 date with a time zone. Empty means the time of the import. | 2024-03-01T09:30:00Z |
pinned_at | Any date pins the capture. | 2024-03-01T09:30:00Z |
note_path | A Markdown file with the note's text, relative to the CSV's folder. | notes/launch.md |
note_url | A web address to download the note's text from. | https://example.com/note.md |
asset_path | The file for an image, PDF, video, audio or file capture, relative to the CSV's folder. | assets/board.png |
asset_url | A web address to download that file from. | https://example.com/board.png |
original_filename | The file name to keep. | board.png |
capture_id | A Resurf ID. Only Resurf exports have one, and it's what lets a second import skip captures you already have. | cap_… |
deleted_at | Any date marks the row as deleted, and the import skips it. | 2024-03-01T09:30:00Z |
Type values
Write the type exactly as shown: lower case, except voiceNote.
| Type | Use it for |
|---|---|
note | A note. Its text comes from note_path or note_url. |
quote | A quote. Its text comes from note_path or note_url. |
link | A web page. Put the address in source_url. |
article | A web page saved as an article. |
product | A product page. |
social | A post from a social site. |
image, pdf, video, audio | A file of that kind, from asset_path or asset_url. |
voiceNote | A voice recording. |
file | Any other file. |
color | A color note, as Resurf exports it. |
Anything else, including Link or URL, makes the row invalid.
Limits and formats
- The file must be UTF-8. A byte order mark at the start is fine. In Excel, save as CSV UTF-8 (Comma delimited).
- Commas separate columns. A file that uses semicolons or tabs between columns won't import.
- Wrap a cell in double quotes when it contains a comma, a quote or a line break, and double any quote inside it:
"She said ""yes"", then left". - Column names are lower case and exact:
TypeorSource URLwon't match. - Dates need a time and a time zone:
2024-03-01T09:30:00Zor2024-03-01T09:30:00+01:00. A date alone, like2024-03-01, makes the row invalid. - A note's text can't go in a cell. It comes only from a file (
note_path) or a web address (note_url). For a short line of your own, useuser_note. - A note or quote row without
note_pathornote_urlimports with an empty body. An image, PDF, video, audio or file row withoutasset_pathorasset_urlimports with no file. - Without a license, Resurf stops an import that would go past 50 captures before it adds anything. On the free plan you can have 4 spaces; space names past that are left out without a message.
Every column
A Resurf export writes these 42 columns, in this order.
capture_id,external_id,schema_version,type,title,description,user_note,source_kind,source_url,domain,source_app,source_file_name,tags,spaces,space_ids,primary_space,primary_space_id,created_at,updated_at,device_name,pinned_at,later_at,deleted_at,note_path,note_url,asset_path,asset_url,mime_type,original_filename,source_json,organization_json,state_json,content_json,files_json,comments_json,ai_suggested_title,ai_suggested_tags,ai_suggested_spaces,ai_tldr,ai_source_fingerprint,ai_processor_version,ai_generated_atThe columns ending in _json and starting with ai_ carry what only Resurf knows: comments, files, AI summaries. Leave them out of files you build yourself. When one is present, Resurf reads it, so a hand-edited one that isn't valid JSON makes the row invalid.
If something goes wrong
The preview shows up to three problems. The toast after the import counts what failed.
| You see | What to do |
|---|---|
Row 2, type: invalid value ''. on every row | There's no type column, its name isn't exactly type, or the file isn't comma-separated. |
Row N, type: invalid value 'Link'. | The type is in the wrong case or isn't a type. Use one of the type values exactly. |
Row N, created_at: invalid ISO 8601 date | Add a time and a time zone, such as 2024-03-01T00:00:00Z. |
Couldn't read the CSV, Malformed CSV quote at line N | A quote mark sits inside a cell that isn't wrapped in quotes. Wrap the cell in quotes and double the quote inside it. |
Row N: asset not found at … | Check the path is relative to the CSV's folder and spelled exactly. If it's right and still fails, use asset_url or note_url, or drag the files onto Resurf instead. |
Row N: hosted asset downloads are disabled | Turn on Download hosted assets in the import options. |
Row N: … returned HTTP 404. | The web address is broken. Fix or remove it. |
| Importing N captures needs a license | The import would go past the free 50 captures. Activate a license, or import fewer rows. |
| The same captures twice | Rows without a Resurf capture_id are new every time. See Import. |
Questions
Can an AI write this file for me?
Yes, for saved links. Move from another app has a prompt to paste into ChatGPT or Claude with your export attached; it writes a captures.csv in this format.
Do I need every column?
No. Only type is required. A file with type, title and source_url is enough for a list of links.
Can I put a note's text in the CSV?
Not in a cell. Put each note in its own Markdown file and give its path in note_path, or give a web address in note_url. For a short line of your own, use user_note. To bring in a folder of Markdown files, dragging the folder onto Resurf is simpler.
Why are my links dated today?
The file has no created_at, or it's empty, so Resurf uses the time of the import. Add created_at with the original dates.
Can I put captures in Later or Archive?
Not with a simple column. Rows land in the Inbox unless they name a space. A date in later_at on its own archives the capture rather than putting it in Later, so leave that column out of files you build. A Resurf export carries the full state in state_json.