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

# Import & Export Data

> Move your dictionary, threads, workflows, expansions, and custom utilities in and out of Vowen using a single JSON file.

<div style={{ marginTop: "-2.5rem" }}>
  <Info>Import/Export requires a paid plan. <a href="https://vowen.ai" className="font-semibold underline-offset-2" style={{ color: "#8b5cf6", backgroundColor: "rgba(139, 92, 246, 0.12)", border: "1px solid rgba(139, 92, 246, 0.35)", padding: "2px 8px", borderRadius: "6px", fontSize: "0.85em", textDecoration: "none", whiteSpace: "nowrap" }}>Pro</a> unlocks Import and Export from the Settings → Data section.</Info>
</div>

## Overview

Vowen stores all your customisations in a single JSON file you can export, share, and re-import on another machine. The same file format is used whether you're:

* Migrating from one computer to another
* Sharing a curated pack of expansions with your team
* Building a starter pack programmatically (e.g. asking an LLM to generate one)

The importer **never overwrites** existing items. Anything that already exists in your settings (matched by shortcut, name, or trigger) is skipped — only new items are added.

## How to import

1. Open Vowen → **Settings**
2. Scroll to the **Data** section
3. Click **Import Data**
4. Drop your `.json` file onto the dropzone (or click to browse)
5. Review the preview — Vowen shows the count of each item type found in the file
6. Click **Import** to confirm

## How to export

1. Open Vowen → **Settings** → **Data** section
2. Click **Export Data**
3. Choose where to save the resulting `.json` file

The export includes every customisation listed in the [file format](#file-format) below.

## File format

An import file is a single JSON object. Every key shown below must be present even if its value is an empty array — the importer validates the shape before parsing the contents.

```json theme={null}
{
  "_vowen": true,
  "version": 1,
  "exportedAt": "2026-06-01T12:00:00.000Z",
  "appVersion": "import",
  "dictionary": [],
  "threads": [],
  "workflows": { "builtin": [], "custom": [] },
  "expansions": [],
  "customUtilities": []
}
```

### Required top-level keys

| Key               | Type    | Notes                                                           |
| ----------------- | ------- | --------------------------------------------------------------- |
| `_vowen`          | boolean | Must be `true`. The importer rejects files without this marker. |
| `version`         | number  | File-format version. Use `1`.                                   |
| `exportedAt`      | string  | ISO 8601 timestamp. Informational.                              |
| `appVersion`      | string  | Vowen version that produced the file. Informational.            |
| `dictionary`      | array   | Vocabulary words. May be `[]`.                                  |
| `threads`         | array   | Text replacement rules. May be `[]`.                            |
| `workflows`       | object  | Has `builtin` and `custom` arrays. Both may be `[]`.            |
| `expansions`      | array   | Text expansion shortcuts. May be `[]`.                          |
| `customUtilities` | array   | Custom utility hotkeys. May be `[]`.                            |

If any of `dictionary`, `threads`, or `workflows` is missing, the import is rejected with the message *"This file doesn't appear to be a Vowen export."*

## Expansions (rich text supported)

Expansions are the most flexible item type and the only one alongside threads that supports rich text (bold, lists, links, headings, colours, highlights, alignment).

### Schema

```json theme={null}
{
  "shortcut": ":email",
  "body": "<p>contact@example.com</p>",
  "format": "html",
  "replacement": "contact@example.com",
  "enabled": true,
  "isBuiltin": false,
  "createdAt": 1780409992000
}
```

| Field         | Required | Description                                                                                                                                                   |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `shortcut`    | yes      | The trigger you'll type. **Must start with `:`** (e.g. `:sig`). Triggers must be unique.                                                                      |
| `body`        | yes      | The content to paste. Either plain text or an HTML fragment depending on `format`.                                                                            |
| `format`      | yes      | `"plain"` or `"html"`.                                                                                                                                        |
| `replacement` | yes      | Plain-text fallback. Used by apps that don't support rich paste (Terminal, code editors, single-line inputs). For `format: "plain"` this should equal `body`. |
| `enabled`     | yes      | `true` to activate the expansion immediately on import.                                                                                                       |
| `isBuiltin`   | yes      | Always `false` for user-imported expansions.                                                                                                                  |
| `createdAt`   | yes      | Unix timestamp in milliseconds. Used only for sort order.                                                                                                     |

<Note>
  Shortcuts already present in your settings are **skipped on import**. If you want to update an existing expansion, delete it first in the app, then re-import.
</Note>

### Plain expansions

```json theme={null}
{
  "shortcut": ":addr",
  "body": "123 Main Street, Suite 400, New York, NY 10001",
  "format": "plain",
  "replacement": "123 Main Street, Suite 400, New York, NY 10001",
  "enabled": true,
  "isBuiltin": false,
  "createdAt": 1780409992000
}
```

For plain expansions, `body` and `replacement` are identical.

### Rich-text expansions (HTML)

When `format` is `"html"`, the `body` is parsed as an HTML fragment by Vowen's rich editor and the rich version is placed on the OS clipboard. Apps that read the rich slot (Gmail, Notion, Apple Mail, Slack rich compose, Word, Google Docs) receive the formatted version; apps that only read plain text (Terminal, code editors, `<input>` fields) get `replacement`.

#### Supported HTML

Vowen's editor is built on Tiptap with the StarterKit, Link, TextStyle, Color, Highlight, and TextAlign extensions. The following tags round-trip cleanly:

| Element         | HTML                                                              |
| --------------- | ----------------------------------------------------------------- |
| Paragraph       | `<p>...</p>`                                                      |
| Line break      | `<br>`                                                            |
| Bold            | `<strong>...</strong>`                                            |
| Italic          | `<em>...</em>`                                                    |
| Strikethrough   | `<s>...</s>`                                                      |
| Inline code     | `<code>...</code>`                                                |
| Code block      | `<pre><code>...</code></pre>`                                     |
| Heading         | `<h1>...</h1>`, `<h2>...</h2>`, `<h3>...</h3>`                    |
| Bulleted list   | `<ul><li>...</li></ul>`                                           |
| Numbered list   | `<ol><li>...</li></ol>`                                           |
| Link            | `<a href="https://example.com" rel="noopener noreferrer">...</a>` |
| Coloured text   | `<span style="color: #ff0000">...</span>`                         |
| Highlight       | `<mark>...</mark>`                                                |
| Alignment       | `<p style="text-align: center">...</p>`                           |
| Blockquote      | `<blockquote><p>...</p></blockquote>`                             |
| Horizontal rule | `<hr>`                                                            |

#### Special characters

Use HTML entities inside `body` for any character that has meaning in HTML:

| Character | Entity              | Use in                             |
| --------- | ------------------- | ---------------------------------- |
| `<`       | `&lt;`              | Anywhere literal `<` should appear |
| `>`       | `&gt;`              | Anywhere literal `>` should appear |
| `&`       | `&amp;`             | Anywhere literal `&` should appear |
| `"`       | `&quot;`            | Inside attribute values            |
| £         | `&pound;`           | Or use the literal character       |
| ‘ ’       | `&lsquo;` `&rsquo;` | Smart single quotes                |
| “ ”       | `&ldquo;` `&rdquo;` | Smart double quotes                |

In `replacement` (plain text) you can use the literal characters directly — no escaping needed.

#### Rich expansion example

```json theme={null}
{
  "shortcut": ":pay",
  "body": "<p>You can pay by PayPal or Bank Transfer.</p><p><strong>PayPal:</strong> <a href=\"https://www.paypal.me/example\" rel=\"noopener noreferrer\">https://www.paypal.me/example</a></p><p><strong>Bank Details:</strong></p><ul><li>Account Holder: Example Ltd</li><li>Sort Code: 401234</li><li>Account Number: 12345678</li></ul>",
  "format": "html",
  "replacement": "You can pay by PayPal or Bank Transfer.\n\nPayPal: https://www.paypal.me/example\n\nBank Details:\n• Account Holder: Example Ltd\n• Sort Code: 401234\n• Account Number: 12345678",
  "enabled": true,
  "isBuiltin": false,
  "createdAt": 1780409992000
}
```

### Dynamic tokens

Both `plain` and `html` bodies support these tokens, which are resolved at expansion time:

| Token            | Resolves to                                                                      |
| ---------------- | -------------------------------------------------------------------------------- |
| `{{DATE}}`       | ISO date (e.g. `2026-06-01`)                                                     |
| `{{TIME}}`       | 24-hour time (e.g. `14:30`)                                                      |
| `{{DATE:<key>}}` | A preset date format (see the **Add Expansion** modal in-app for available keys) |
| `{{TIME:<key>}}` | A preset time format                                                             |

## Other item types

### Dictionary

Vocabulary words that bias transcription accuracy.

```json theme={null}
{
  "id": 1,
  "text": "Anthropic",
  "createdAt": 1780000000000
}
```

Existing words are skipped by case-insensitive match on `text`.

### Threads

Voice-triggered text replacements applied during transcription.

```json theme={null}
{
  "id": 1,
  "trigger": "my address",
  "replacement": "123 Main Street, Suite 400, New York, NY 10001",
  "body": "123 Main Street, Suite 400, New York, NY 10001",
  "format": "plain",
  "createdAt": 1780000000000
}
```

Threads also support rich text (`format: "html"` with `body` as HTML), following the same conventions as expansions. Existing threads are skipped when both `trigger` and `replacement` are exact matches.

### Workflows

```json theme={null}
{
  "builtin": [
    { "id": "email-reply", "enabled": true }
  ],
  "custom": [
    {
      "name": "Summarise to bullets",
      "prompt": "Rewrite the following as 3-5 concise bullet points.",
      "model": "claude-sonnet-4-6",
      "enabled": true
    }
  ]
}
```

* **builtin** entries only flip the enabled state of workflows that ship with Vowen; unknown ids are ignored.
* **custom** entries are added as new workflows. Existing custom workflows are skipped by case-insensitive `name` match.

### Custom utilities

```json theme={null}
{
  "name": "Open Calculator",
  "hotkey": "F19",
  "enabled": true
}
```

Existing utilities are skipped by case-insensitive `name` match. After import, the keyboard hook is automatically re-registered with the new hotkeys.

## Validation rules

The importer enforces these rules and surfaces a single error if any fail:

* The file extension must be `.json`.
* The file must parse as valid JSON.
* `_vowen` must be `true`.
* `dictionary`, `threads`, `workflows`, `workflows.custom` must all be arrays/objects of the correct shape.
* Each expansion must have a `shortcut` (string) starting with `:` and either `body` or `replacement` non-empty.
* Each thread must have `trigger` and `replacement` as strings.
* Each custom workflow and utility must have a `name` string.

Malformed individual entries are silently skipped — they don't fail the whole import.

## Minimal example (just expansions)

A valid file can contain expansions only. The other keys must still be present as empty arrays:

```json theme={null}
{
  "_vowen": true,
  "version": 1,
  "exportedAt": "2026-06-01T00:00:00.000Z",
  "appVersion": "import",
  "dictionary": [],
  "threads": [],
  "workflows": { "builtin": [], "custom": [] },
  "expansions": [
    {
      "shortcut": ":sig",
      "body": "<p>Best,</p><p><strong>Jane Doe</strong><br>jane@example.com</p>",
      "format": "html",
      "replacement": "Best,\nJane Doe\njane@example.com",
      "enabled": true,
      "isBuiltin": false,
      "createdAt": 1780409992000
    }
  ],
  "customUtilities": []
}
```

## Generating a file with an LLM

If you have a list of shortcuts in any format (a spreadsheet, a Word doc, a wiki page), you can hand it to ChatGPT, Claude, Gemini, or any other LLM along with the prompt below. The model will produce a ready-to-import `.json` file.

<Tip>
  Copy the prompt below verbatim, paste your source material under **My shortcuts** at the bottom, and ask the model to return only the JSON inside a code block. Save the response as `vowen-import.json` and drop it into Vowen's Import Data dialog.
</Tip>

````markdown theme={null}
You are building an import file for Vowen, a desktop dictation app that
supports text expansions. I will give you a list of shortcuts and their
expanded responses. Your job is to produce a single JSON file conforming
exactly to the schema below.

# File shape (all keys required)

```json
{
  "_vowen": true,
  "version": 1,
  "exportedAt": "<ISO 8601 timestamp>",
  "appVersion": "import",
  "dictionary": [],
  "threads": [],
  "workflows": { "builtin": [], "custom": [] },
  "expansions": [ /* one object per shortcut */ ],
  "customUtilities": []
}
```

# Each expansion object

```json
{
  "shortcut": ":example",
  "body": "<HTML fragment>",
  "format": "html",
  "replacement": "<plain text fallback>",
  "enabled": true,
  "isBuiltin": false,
  "createdAt": <unix ms, increment by 1 per expansion>
}
```

# Rules for `body` when format is "html"

- Wrap each paragraph in `<p>...</p>`.
- Use `<strong>` for bold, `<em>` for italic, `<a href="URL" rel="noopener noreferrer">URL</a>` for links.
- Bulleted lists: `<ul><li>item</li><li>item</li></ul>`.
- Numbered lists: `<ol><li>item</li></ol>`.
- Headings: `<h1>` to `<h3>`.
- Escape `<`, `>`, `&` as `&lt;`, `&gt;`, `&amp;` inside text.
- Use `&pound;` for £, `&lsquo;`/`&rsquo;` for ‘ ’, `&ldquo;`/`&rdquo;` for “ ”.
- Do NOT wrap the whole body in `<html>` or `<body>` tags.

# Rules for `replacement`

- A plain-text equivalent of `body` with no HTML tags.
- Use real line breaks (`\n` in JSON strings) between paragraphs.
- Use `• ` to mark bulleted list items.
- Keep URLs as plain text.

# Rules for `shortcut`

- Must start with `:`.
- Use only lowercase letters, digits, and underscores after the `:`.
- Keep it short and mnemonic. If the source uses `:foo**bar**baz` style
  formatted text, treat the bold markers as cosmetic and concatenate
  the letters: `:foobarbaz`.
- Must be unique across the whole file.

# Output

Return ONLY the final JSON file inside a single ```json fenced block.
No preface, no explanation, no trailing prose.

# My shortcuts

<paste your list here — table, doc, or freeform>
````

## Troubleshooting

<AccordionGroup>
  <Accordion title="This file doesn't appear to be a Vowen export">
    The file is missing `_vowen: true` or one of the required top-level keys (`dictionary`, `threads`, `workflows`). Check that all keys from the [file format](#file-format) section are present, even as empty arrays.
  </Accordion>

  <Accordion title="The file format is invalid">
    One of the required keys exists but is the wrong type. `dictionary` and `threads` must be arrays; `workflows` must be an object containing a `custom` array.
  </Accordion>

  <Accordion title="Not a valid JSON file">
    The file doesn't parse as JSON. Common causes: trailing commas, unescaped quotes inside `body` strings, smart quotes around keys. Paste the file into a JSON validator to locate the syntax error.
  </Accordion>

  <Accordion title="Import succeeded but some items are missing">
    Items with shortcuts/triggers/names that already exist are skipped — the success toast shows how many were added. Delete the existing entry in the app first if you want to replace it.
  </Accordion>

  <Accordion title="Rich-text expansion pastes as plain text">
    The target app doesn't support rich paste (Terminal, code editors, single-line inputs). Vowen falls back to the `replacement` string in these apps — this is expected behaviour.
  </Accordion>
</AccordionGroup>
