Skip to main content
Import/Export requires a paid plan. Pro unlocks Import and Export from the Settings → Data section.

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 → SettingsData section
  2. Click Export Data
  3. Choose where to save the resulting .json file
The export includes every customisation listed in the 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.
{
  "_vowen": true,
  "version": 1,
  "exportedAt": "2026-06-01T12:00:00.000Z",
  "appVersion": "import",
  "dictionary": [],
  "threads": [],
  "workflows": { "builtin": [], "custom": [] },
  "expansions": [],
  "customUtilities": []
}

Required top-level keys

KeyTypeNotes
_vowenbooleanMust be true. The importer rejects files without this marker.
versionnumberFile-format version. Use 1.
exportedAtstringISO 8601 timestamp. Informational.
appVersionstringVowen version that produced the file. Informational.
dictionaryarrayVocabulary words. May be [].
threadsarrayText replacement rules. May be [].
workflowsobjectHas builtin and custom arrays. Both may be [].
expansionsarrayText expansion shortcuts. May be [].
customUtilitiesarrayCustom 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

{
  "shortcut": ":email",
  "body": "<p>[email protected]</p>",
  "format": "html",
  "replacement": "[email protected]",
  "enabled": true,
  "isBuiltin": false,
  "createdAt": 1780409992000
}
FieldRequiredDescription
shortcutyesThe trigger you’ll type. Must start with : (e.g. :sig). Triggers must be unique.
bodyyesThe content to paste. Either plain text or an HTML fragment depending on format.
formatyes"plain" or "html".
replacementyesPlain-text fallback. Used by apps that don’t support rich paste (Terminal, code editors, single-line inputs). For format: "plain" this should equal body.
enabledyestrue to activate the expansion immediately on import.
isBuiltinyesAlways false for user-imported expansions.
createdAtyesUnix timestamp in milliseconds. Used only for sort order.
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.

Plain expansions

{
  "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:
ElementHTML
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:
CharacterEntityUse 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

{
  "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:
TokenResolves 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.
{
  "id": 1,
  "text": "Anthropic",
  "createdAt": 1780000000000
}
Existing words are skipped by case-insensitive match on text.

Threads

Voice-triggered text replacements applied during transcription.
{
  "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

{
  "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

{
  "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:
{
  "_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>[email protected]</p>",
      "format": "html",
      "replacement": "Best,\nJane Doe\n[email protected]",
      "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.
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.
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

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 section are present, even as empty arrays.
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.
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.
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.
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.