---
title: "Import from a CSV"
description: "Map any spreadsheet export into HelpDocs. Full CSV column reference, multilingual rows, redirects from your old URLs, and re-importing to pick up changes."
url: "https://support.helpdocs.io/article/5p5b55ggim-import-from-a-csv"
category: "Getting Started"
updated_at: "2026-09-06T16:27:14Z"
---

# Import from a CSV

If you can get your content out of your current tool as a spreadsheet, you can bring it into HelpDocs. Head to **Settings &gt; Migrations**, choose **CSV file**, and upload it. The rest works like [any other import](/article/9WWNm9f5h6-import-data-from-another-service): you get a preview, and nothing is written until you press the button.

You don't need to reformat your export. Upload the file as it comes out of your old tool. We read the headers, guess which HelpDocs field each column is, and show you the guesses so you can correct them.

### Mapping your columns

After the upload you'll see a list of HelpDocs fields with a dropdown next to each, pre-filled with our best guess from your headers. A column called *Body HTML* lands on Body, *Answer* lands on Body, *Collection* lands on Category. Change anything we got wrong, and leave a field on **(none)** if your export has nothing for it.

**Title** is the only field you have to map. You can't start the import without it.

| Field                   | What goes in it                                                                                                                                                         |
|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Title** required      | The article title.                                                                                                                                                      |
| **Body / content**      | The article itself. HTML is expected and comes through as formatting. Plain text works too.                                                                             |
| **Description**         | The short summary shown in listings and used as the meta description.                                                                                                   |
| **Short version**       | The condensed version of the article, if your export has one.                                                                                                           |
| **Old article URL**     | Where this article lived before. We turn it into a redirect so your existing links keep working. See [Keeping your old links working](#keeping-your-old-links-working). |
| **Slug**                | The URL slug. Leave it blank and we build one from the title.                                                                                                           |
| **Tags**                | Separate them with commas, semicolons or pipes.                                                                                                                         |
| **Category / folder**   | The folder name. Rows sharing a name land in the same new folder.                                                                                                       |
| **Old folder URL**      | Where the folder lived before, turned into a redirect the same way.                                                                                                     |
| **Author**              | Matched to a member of your team in the review step.                                                                                                                    |
| **Language code**       | The language of this row, like `en` or `fr`. See [Importing more than one language](#importing-more-than-one-language).                                                 |
| **Published**           | Accepts true, yes, 1, published or live, and false, no, 0, draft or unpublished. Anything else, or an unmapped column, publishes the article.                           |
| **External ID**         | The article's ID in your old system. Worth mapping even if you don't think you need it, for the two reasons below.                                                      |
| **HelpDocs article ID** | Only offered in Update existing mode, where it's the match key.                                                                                                         |

### Why External ID is worth mapping

The external ID is how HelpDocs recognises an article as one it has seen before. Map it and you get two things:

- You can re-run the same export later in **Update existing** mode and have it update your articles instead of duplicating them.
- Rows in different languages can be tied together into a single multilingual article.

Each external ID belongs to one article at a time. Deleted articles don't hold on to theirs, so you're free to undo an import and run it again, or re-import a source whose articles you've since deleted.

One consequence worth knowing: if you delete an article, then import something that reuses its external ID, and then restore the deleted one from your deleted articles list, the restored copy comes back without an external ID. The article that's live keeps it. Everything else about the restored article is untouched, but a future Update existing import won't match it until you give it an ID again.

### Importing more than one language

Put each language on its own row, map the **Language code** column, and give every row for the same article the same **External ID**. We fold those rows into one article with a language version for each.

| Title               | Body                                           | Language | External ID |
|---------------------|------------------------------------------------|----------|-------------|
| Reset your password | &lt;p&gt;Click Forgot password...&lt;/p&gt;    | `en`     | `acct-001`  |
| Mot de passe oublié | &lt;p&gt;Cliquez sur Mot de passe...&lt;/p&gt; | `fr`     | `acct-001`  |
| Cancel your plan    | &lt;p&gt;Head to Billing...&lt;/p&gt;          | `en`     | `bill-002`  |

That's three rows and two articles: the first two are the same article in English and French. The review step shows you both numbers, so you can check the grouping worked before you import.

- Turn on [multilingual](/article/43QNppaDit-setting-up-multilingual-docs) in your account first, and add the languages you're importing.
- Whichever row matches your account's default language becomes the original, and the rest become translations of it. Row order doesn't decide this, so an export that happens to list French first is fine.
- Two rows claiming the same article in the same language are a contradiction we can't resolve, so we keep the first and skip the second.
- Rows with no external ID can't be grouped, and each becomes its own article.
- The folder comes from whichever row holds the original. You can put the translated folder name on the other rows without ending up with two folders.

### Keeping your old links working

Map your export's URL column to **Old article URL** and we'll add a [redirect](/article/QEx7nXwz5j-adding-url-redirects) from each old address to the article that replaced it. Do the same with **Old folder URL** for your categories.

Both absolute and relative URLs work, so either of these is fine:

```
https://docs.example.com/article/reset-password
/article/reset-password
```

We match on the path, so anything after it is ignored. Query strings and anchors on an old URL won't stop the redirect from matching.

On a multilingual import, a row in a language other than your default redirects to that language's version of the article, so a French URL lands on the French article.

### Re-importing to pick up changes

Choose **Update existing** and map the same External ID column you used the first time. Articles that match are updated in place, anything new is created, and nothing is deleted. Redirects from a previous import are kept.

### Importing translations of articles you already have

In **Update existing** mode you also get an option to **import as translations of existing articles**. Tick it, choose the target language, and each row is added as that language version of the article it matches instead of changing the original. Rows that match nothing are skipped. Articles are matched on their HelpDocs ID for this, so map that column.

### A few things to know

- The first row of the file must be the headers.
- Empty rows, and rows with neither a title nor a body, are skipped.
- Bodies come in as written. An `H1` inside a body becomes an `H3`, since the article title is the top heading level.
- Importing doesn't merge folders. If your CSV files an article under Billing and you already have a folder called Billing, you'll get a second one. Use **Import into folder** to keep the whole import together instead.

Changed your mind after importing? Press **Undo** next to the import under Recent migrations and everything it created is removed. You can fix the file and import it again straight away.

### Need a hand?

If your export isn't coming across the way you expect, get in touch through the widget and send us a sample of the file. We're happy to take a look.
