Documentation Index
Fetch the complete documentation index at: https://docs.dovetail.com/llms.txt
Use this file to discover all available pages before exploring further.
Dovetail CLI
The Dovetail CLI (dt) is a command-line tool for importing content into your Dovetail workspace from external sources — Notion, Confluence, Google Drive, Airtable, Productboard, EnjoyHQ, Marvin, Condens, and local files. Use it when you want to bulk-migrate historical research, run repeatable imports from a scriptable workflow, or stage a migration locally before sending data to Dovetail.What can you do with the Dovetail CLI?
- Bulk import from 9+ sources — Notion, Confluence, Google Drive, Airtable, Marvin, Condens, EnjoyHQ, Productboard, and local files
- Preserve formatting and metadata — Headings, lists, tables, code blocks, attachments, author info, dates, and tags come through intact
- Preview before committing — See exactly what will be imported before data touches your workspace
- Resume interrupted imports — If an import fails partway through, pick up where you left off—no re-processing needed
- Batch multiple sources — Configure migrations from Notion and Confluence in one config file, run them together
- Filter and limit — Import only records matching specific titles, dates, or file types
- Test connections — Validate API credentials and workspace permissions before running the full migration
Security and permissions
The CLI authenticates to Dovetail using a personal API key from your workspace settings. It only has write access to the destinations you configure — it cannot read or modify anything else in your workspace. Source credentials (Notion token, Confluence API token, etc.) are stored locally in your dt.yaml or as environment variables and are never transmitted anywhere except the source service itself.Prerequisites
Before you install, make sure you have:- A Dovetail workspace and an API key. Generate one in your workspace settings.
-
What plans support the CLI?
- All plans except plans that have HIIPA enabled.
- Your workspace URL — for example, https://yourcompany.dovetail.com.
-
One of the supported install paths:
- npm install: Node.js and npm.
- Build from source: Go 1.25 or later, plus make.
- The credentials for each source you plan to import from. These vary by source — see Authenticate below.
Install
You can install the CLI in two ways. Most people should use npm.Install via npm
Build from source
You’ll need Go 1.25 or later.make install builds the dt binary and installs it to~/.local/bin/dt.If ~/.local/bin isn’t on your PATH, add it:
- make build — compile the binary without installing it.
- make test — run the test suite.
- make lint — run golangci-lint.
Install shell completions
After installing, you can turn on autocompletion for dt subcommands and flags:Authenticate
Authentication happens at two levels: the CLI authenticates to your Dovetail workspace, and each source you connect authenticates separately to its own provider.Authenticate to Dovetail
Set your Dovetail API key as an environment variable, then run the setup wizard:dt init is an interactive wizard that:
- Confirms your workspace URL (for example, https://yourcompany.dovetail.com).
- Stores your API key.
- Walks you through adding your first source.
dt init --force to overwrite an existing configuration.
You can also set your workspace URL persistently in your config under dovetail.base_url. This is important — it ensures every link the CLI generates points to the right workspace.
Authenticate each source
Every source has its own credential. Most use a personal access token set via environment variable; Google Drive uses OAuth or a service account.| Source | Status | Auth method | Environment variable |
|---|---|---|---|
| Notion | GA | Internal integration token | NOTION_TOKEN |
| Confluence | GA | API token + email + base URL | CONFLUENCE_API_TOKEN, CONFLUENCE_EMAIL, CONFLUENCE_BASE_URL |
| Google Drive | GA | OAuth (personal) or service account (org) | GOOGLE_APPLICATION_CREDENTIALS (service account only) |
| Airtable | GA | Personal access token with data.records:read and schema.bases:read | AIRTABLE_TOKEN |
| Productboard | GA | Public API access token | PRODUCTBOARD_API_TOKEN |
| EnjoyHQ | Experimental | Workspace API token | ENJOYHQ_API_TOKEN |
| Marvin | Experimental | None (local export folder) | — |
| Condens | Experimental | None (local zip export) | — |
| Local files | GA | None | — |
Supported sources & field mapping
Notion
What gets migrated:- Pages and database entries with all formatting (headings, lists, tables, code blocks, callouts, toggles)
- Inline attachments and cover images
- Metadata: author, creation date, last-modified date, tags, properties
- Child pages (up to 3 levels of nesting, configurable)
- Notion Integration created at https://www.notion.so/my-integrations
- All databases you want to migrate must be explicitly shared with the integration
- Integration must have “Read” permissions at minimum
Confluence
What gets migrated:- Cloud pages and blog posts with full HTML content and formatting
- Attachments (PDFs, images, Word docs, etc.)
- Labels and metadata (author, creation/modification dates, space key)
- Parent-child page relationships preserved
- Comments (available as metadata)
- Confluence Cloud workspace (Server/Data Center not supported)
- Atlassian API token from https://id.atlassian.com/manage-profile/security/api-tokens
- Your Confluence base URL (e.g., https://mycompany.atlassian.net/wiki)
- Account email address
- Permission to access the spaces you’re migrating (typically Editor or Admin)
- 300 requests per minute per API token (Atlassian limit)
- The CLI automatically retries with exponential backoff; no action needed
Google Drive
What gets migrated:- Google Docs (exported as HTML with formatting)
- Google Sheets (optionally, as CSV)
- PDFs, images, and other files (as attachments)
- Folder structure and hierarchy preserved
- File metadata (owner, creation/modification dates)
- OAuth (personal/shared drives, recommended for most users)
- Google Cloud project with Drive API enabled
- OAuth 2.0 Desktop client ID created
- dt source add gdrive opens your browser to sign in
- No credential file needed; token is stored securely
- Service account (org/shared drives)
- Service account created in Google Cloud
- JSON key file downloaded
- Drive folder explicitly shared with the service account email
- Set
GOOGLE_APPLICATION_CREDENTIALSenvironment variable
- 10 million read requests per day (per project)
- 600 requests per minute per user
- The CLI automatically retries rate-limited requests
- Large files (>50 MB) may take longer to transfer; no timeout
- Empty files are skipped
- Google Sheets are converted to CSV format
Airtable
What gets migrated:- Records from all tables/views
- All field values (text, numbers, attachments, linked records, etc.)
- Attachment files uploaded as Dovetail attachments
- Linked record metadata (record name, ID)
- Field names and types preserved
- Airtable personal access token from https://airtable.com/create/tokens
- Required scopes:
data.records:read and schema.bases:read - Read access to the base(s) you’re migrating
- 5 requests per second (Airtable limit)
- The CLI respects this automatically; no backoff needed
- Linked records are imported as metadata; you can later link them in Dovetail
- Attachment metadata is preserved (file name, size, URL)
Marvin
What gets migrated:- Video/audio recordings → uploaded as data with automatic transcription
- Insights (reports) → imported as docs with markdown content
- Interview metadata (date, duration, tags, participant info)
- Manual export from Marvin (no public API), or use Claude Code /
marvin-downloadskill - Folder structure:
- In Marvin, go to each project → All Actions → Download Video
- Copy insight markdown into
content.mdfiles in the folder structure above - Run:
- Video/audio files are uploaded as attachments; Dovetail generates transcripts automatically
- Transcription typically completes within 10 minutes for 1-hour recordings
- Insights are imported as plain markdown docs; no special formatting required
- Maximum file size: 5 GB per recording
Condens
What gets migrated:- Sessions (interview notes, transcripts, video) → data records
- Artifacts (reports, deliverables) → docs
- Video attachments automatically included
- Session metadata (date, participants, tags)
- Condens export ZIP file from Project → Settings → Export data
- No API credentials needed
- ZIP is processed locally; never uploaded to Dovetail servers
- Large projects (>1 GB) may take 5–10 minutes to process
- Video formats supported: MP4, WebM, MOV (same as Dovetail)
EnjoyHQ
What gets migrated:- Stories (customer feedback) with HTML content → data records
- Projects (plans + summaries) → docs
- Documents (feedback text) → data records
- Labels, state, customer info preserved
- EnjoyHQ API token from workspace settings
- Read access to stories, projects, and documents
- 100 requests per minute
- The CLI automatically respects this limit
Productboard
What gets migrated:- Notes (customer feedback, research) → data records
- Features (with descriptions, metadata) → docs
- Linked data (initiatives, objectives)
- Metadata (date, priority, status, owner)
- Productboard API token from Settings → Integrations → Public API
- Read access to notes and features
- 60 requests per minute (Productboard public API)
- The CLI automatically queues and retries
Local files
What gets migrated:- Markdown (.md) → record body
- Text files (.txt, .html) → record body
- PDFs, images, videos, Word docs → attachments
- Folder structure preserved
- Local folder with files you want to import
- No credentials needed
- File permissions: must have read access
- Symlinks are followed
- Hidden files (starting with .) are skipped
- Maximum file size: 5 GB
Configuration
Configuration file structure (dt.yaml)
The CLI uses a YAML configuration file to manage migrations:
Configuration resolution order
The CLI resolves configuration from (highest to lowest priority):- CLI flags —
dt migrate run --source notion --limit 100 - Environment variables —
export NOTION_TOKEN="..." - dt.yaml file —
sources.notion.token - Defaults — Built-in sensible defaults
Environment variables reference
| Variable | Used by | Purpose |
|---|---|---|
DOVETAIL_API_KEY | All sources | Dovetail workspace authentication |
NOTION_TOKEN | Notion | Notion integration token |
CONFLUENCE_API_TOKEN | Confluence | Confluence API authentication |
CONFLUENCE_EMAIL | Confluence | Confluence account email |
CONFLUENCE_BASE_URL | Confluence | Confluence workspace URL |
GOOGLE_APPLICATION_CREDENTIALS | Google Drive | Path to service account JSON key |
AIRTABLE_TOKEN | Airtable | Airtable personal access token |
ENJOYHQ_API_TOKEN | EnjoyHQ | EnjoyHQ API token |
PRODUCTBOARD_API_TOKEN | Productboard | Productboard API token |
Running migrations
Preview before importing
Always preview first to see exactly what will be imported:- Number of records that will be imported
- Size of attachments
- Any records that will be skipped (and why)
- Estimated import time
Run the migration
- Fetch records from the source
- Transform them into Dovetail format
- Upload in batches with progress updates
- Show a summary of imported records and any errors
Advanced migration options
Duplicate handling & upsert behavior
By default, running a migration multiple times creates duplicate records. To prevent duplicates on re-runs:- Records are matched by source ID (Notion page ID, Confluence page ID, etc.)
- If a record with the same source ID exists in Dovetail, it’s updated (not duplicated)
- New records are created if they don’t exist
- The upsert feature works with all sources except local files
Important: If you delete a record in Dovetail, running —upsert again will re-create it from the source.
Testing & validation
Validate a source connection
Before running a full migration, test that your credentials work:- API token is valid and not expired
- Token has necessary permissions
- You have access to at least one database/page
- Network connectivity to the source API
Validate migration configuration
Check yourdt.yaml syntax and workspace connectivity:
Workspace health check
See what’s already in your Dovetail workspace:- Workspace name and URL
- Number of projects, docs, records
- Configured migrations
- Any incomplete or failed imports
Workspace statistics
Quick count of content:Diagnostic check
Full system diagnostics:- Configuration file validity
- Dovetail API connectivity
- Source credentials
- Staging directory available
- Disk space
Troubleshooting
Rundt doctor first whenever something is wrong. It checks your config, your network connection to Dovetail, every configured source credential, and the staging directory. Most issues show up there before you have to debug deeper.
| Symptom | Likely cause | What to do |
|---|---|---|
401 Unauthorized | Your Dovetail API key or a source token is invalid or expired. | Regenerate the token, update the relevant environment variable, and re-run dt source validate. |
403 Forbidden | Your Dovetail API key lacks permission, or the source account can’t read the content you’re asking for. | Confirm your Dovetail role includes API access. For sources, check that the source account has read access to the database, folder, space, or base in question. |
no records fetched | The source can authenticate, but it can’t see the content. | Source-specific: in Notion, share the database with your integration; in Google Drive, share the folder with your service account email; in Confluence, check that the space allows your account to read pages; in Airtable, confirm the token hasdata.records:read and schema.bases:read scopes. |
rate limited | The source’s API has thrown a rate-limit error. | No action needed — the CLI retries automatically with exponential backoff. If it keeps happening, lower —limit or run fewer migrations in parallel. |
| Migration interrupted (network drop, terminal closed) | The CLI exited before finishing. | Run dt migrate resume to pick up where it left off. |
| Migration appears stuck or silent | Default output is quiet. | Re-run with —verbose (or -v) for per-record progress. |
dt: command not found after install | Your shell can’t find the binary on PATH. | For npm installs, add the global npm bin directory to PATH. For source builds, add ~/.local/bin to PATH. |
dt --version shows an old version after upgrading | A stale binary is shadowing the new one. | Run which dt to find the active binary. Remove or rename the old one, or reinstall. |
dt doctor, checked the table above, and you’re still stuck, capture the output of dt doctor and dt migrate run --verbose and contact Dovetail support via support@dovetail.com or the Support in-app chat.
Uninstall
How you uninstall depends on how you installed.If you installed via npm
If you built from source
Remove the binary:Clean up configuration and staging
Uninstalling the binary doesn’t remove your config file or any staging directories from completed migrations. To remove them:- Delete your config file (
dt.yamlin whichever directories you ran the CLI from). - Run
dt cleanbefore uninstalling to remove staging directories. After uninstall, remove any remaining staging directories manually. - Unset the environment variables you exported (
DOVETAIL_API_KEY, NOTION_TOKEN, and so on) from your shell profile.
Revoke credentials
Uninstalling the CLI doesn’t revoke the tokens or OAuth grants it used. For a complete cleanup:- Delete your Dovetail API key in your workspace settings.
- Revoke each source token from the source’s own settings (Notion integrations page, Atlassian API tokens, Airtable tokens page, Productboard public API, and so on).
- For Google Drive OAuth, revoke access at myaccount.google.com/permissions. For service accounts, delete the JSON key from your Google Cloud project.
Need a source the CLI doesn’t yet support, or hitting something the troubleshooting table doesn’t cover? Let us know.