
Overview
Automatically import records from any Snowflake table into Channels, where they’re analyzed and grouped into themes so you can turn rows of customer feedback into trends and insights over time. Learn more about Channels → Snowflake works a little differently from Dovetail’s other Channels sources:- Authentication uses a key pair, not OAuth. You create (or reuse) a Snowflake user set up for key-pair authentication and give Dovetail its private key.
- You choose a table and map its columns. For each table you import, you tell Dovetail which column is the unique identifier, which is the timestamp, and which holds the text to analyze.
Prerequisites
- A Dovetail workspace with Channels enabled, and Can edit or Full access on the Channel you’re adding the source to.
- A Dovetail workspace admin — the Snowflake connection is stored once for the whole workspace, and only admins can save it.
- Access to Snowflake with enough privileges to create a user and role (or an existing service user set up for key-pair authentication) and to grant it read access to the tables you want to import.
- A tool to generate an RSA key pair (for example,
openssl).
Dovetail’s Snowflake integration is read-only. It only runs
SELECT (and DESCRIBE TABLE) queries against the tables you configure and never writes back to Snowflake.Step 1 — Set up a Snowflake service user
Do this once in Snowflake (aSECURITYADMIN/ACCOUNTADMIN typically runs it). It creates a dedicated read-only role and user, then registers a key pair on that user. Adjust the object names to match your account.
Create a read-only role and grant minimal access
Generate a key pair
Generate an unencrypted PKCS#8 private key and its public key:Dovetail’s connection form accepts an unencrypted private key. Passphrase-protected keys aren’t supported in the UI, so don’t add
-passout/encryption when generating the key.Create the user and register the public key
Copy the public key body without the-----BEGIN PUBLIC KEY----- / -----END PUBLIC KEY----- lines and without line breaks, then:
If you leave Role blank in Dovetail (Step 2), Snowflake uses the user’s default role — so make sure the role that carries these grants is the user’s
DEFAULT_ROLE, or specify the role explicitly in Dovetail.Step 2 — Connect Snowflake in Dovetail
The connection is saved once for your whole workspace. You can start from Settings, or when you add Snowflake as a source to a Channel.1
Open the Connect data source modal
In Dovetail, open the Connect data source modal and select
Snowflake.2
Enter your connection details
Provide:
- Account identifier — your Snowflake account, for example
MYORG-MYACCOUNT(or a locator likexy12345). - Username — the service user, for example
DOVETAIL_USER. - Warehouse — the warehouse Dovetail runs queries against, for example
DEV_WAREHOUSE. - Role (optional) — the role to use; if blank, the user’s default role applies.
- Private key (PEM) — paste the full contents of
dovetail_key.p8, including the-----BEGIN PRIVATE KEY-----and-----END PRIVATE KEY-----lines.

Step 3 — Choose a table and map its columns
Once connected, tell Dovetail which table to import and what each column means.1
Enter the fully-qualified table name
In the Fully-qualified table name field, enter
DATABASE.SCHEMA.TABLE (for example MY_DB.MY_SCHEMA.FEEDBACK), then select Load columns. Dovetail runs DESCRIBE TABLE and lists the columns.2
Map the three required columns
Choose a column for each role. Each must be a different column:
- Unique identifier — uniquely identifies each row.
- Timestamp — when the record was created; drives ordering and incremental sync.
- Text to analyze — the free-text field Dovetail analyzes and themes.
3
Pick a backfill window
Under From the last, choose how far back to import existing rows:
Last 7 days, Last 30 days, Last 90 days, or Last 6 months. The default is Last 30 days.4
Confirm setup
Confirm setup and finish. Dovetail imports matching rows and keeps syncing new rows automatically.
Column type restrictions
Each role only accepts certain Snowflake column types:
If a dropdown shows “No matching columns in this table”, the table has no column of the required type — pick a different table or adjust the table so it has a suitable column.


Each table you import is its own data source. To analyze more than one table in the same Channel, add Snowflake again and select a different table.
Authentication and permissions
Dovetail authenticates with Snowflake key-pair authentication: it connects as your service user using the private key you provided and the public key you registered on that user. The connection is workspace-level — saved once and shared by everyone in the workspace — and only workspace admins can save or remove it. Dovetail only ever runsSELECT CURRENT_VERSION() (to validate the connection), DESCRIBE TABLE (to list columns), and SELECT against the tables you configure. What Dovetail can read is capped by the role’s grants — if the role loses access to the warehouse, database, schema, or table, syncing stops.
There’s no token to refresh: access ends when you remove the connection in Dovetail, or when the key or grants are revoked in Snowflake.
What gets imported
Each row in your table becomes one Channels data point:
Every column that isn’t one of the three mapped roles is imported as a field on the data point, so you can filter and group by it. Field types are mapped from Snowflake: booleans → Boolean, numeric types → Number, date/time types → Date, text types → Text. Semi-structured and other types (
VARIANT, OBJECT, ARRAY, BINARY, GEOGRAPHY, GEOMETRY) are imported as JSON text.
Rows that are skipped
A row is skipped if its unique identifier is empty, its text column is empty, or its timestamp can’t be parsed as a date.Sync behavior
- Backfill window. On the first sync, Dovetail imports rows whose timestamp falls within the window you selected (
Last 7 days,Last 30 days,Last 90 days, orLast 6 months). - Ongoing sync. Dovetail records the latest timestamp it has seen (using the unique identifier as a tiebreaker for rows sharing a timestamp) and, on each sync, pulls rows with a newer timestamp. Rows are read in ascending timestamp order, up to 1,000 per page.
- Choose your timestamp column carefully. Because the sync advances by the timestamp column, only rows with a timestamp later than the high-water mark are picked up. New rows flow in as long as their timestamp increases; edits to older rows that don’t change the timestamp won’t be re-imported. Pick an insert/created timestamp that only ever moves forward for records you want analyzed.
Troubleshooting
“JWT token is invalid” / authentication fails. The private key in Dovetail doesn’t match the public key registered on the Snowflake user, or the username/account is wrong. Confirm you registered the public key withALTER USER … SET RSA_PUBLIC_KEY, that you pasted the matching private key into Dovetail, and that the account identifier and username are correct.
“Snowflake rejected these credentials” / can’t connect. Double-check the account identifier format (for example MYORG-MYACCOUNT or a locator like xy12345), the warehouse name, and that the role has USAGE on that warehouse.
“Couldn’t read columns from Snowflake.” The table name must be fully qualified as DATABASE.SCHEMA.TABLE, and the role needs USAGE on the database and schema plus SELECT on the table.
Connected, but no rows import. Likely causes:
- The role is missing a grant —
USAGEon the warehouse/database/schema orSELECTon the table. - No rows have a timestamp within (or after) the backfill window.
- Rows were skipped because the unique identifier or text column was empty, or the timestamp couldn’t be parsed.
-----BEGIN PRIVATE KEY-----). Passphrase-protected keys aren’t supported.
Disconnect or delete the Snowflake source
There are two distinct actions on a Channels source. Disconnect. Stops Dovetail from ingesting any new rows from this source. Anything already imported stays in the Channel. To disconnect, open the Channel, go to the sources list, click••• on the Snowflake source, and select Disconnect. You’ll see:
Are you sure you want to disconnect [source name] from [Channel name]? This will immediately stop the Channel from ingesting any new data. Any data already imported from this source will remain in the Channel.Delete. Removes the source and deletes every data point that was imported from it. This is permanent. To delete, click
••• on the Snowflake source and select Delete. You’ll see:
Are you sure you want to delete [source name] from [Channel name]? This will delete all associated data points. This is permanent and cannot be undone.To remove the workspace-wide connection entirely, go to ⚙️ Settings → Integrations, open Snowflake, and select Remove connection. To fully revoke access on the Snowflake side, unset the key or drop the service user: