Skip to content

Snowflake

Import customer records, custom fields, and product usage from selected Snowflake tables or views. The connection is read-only and uses key-pair authentication; Sonora generates the keys and keeps the private key secure.

Ask Sonora to enable account and usage mapping and imports for your workspace.

Map customer name, ARR, renewal date, owner, email domains, and tier, plus custom fields and selected numeric usage metrics. Choose how rows match customers:

  • Create customers from Snowflake — use an account table with one row per customer and a stable account ID. Map its customer fields and link usage tables through that ID.
  • Attach to existing customers — turn on Attach to existing customers and choose the Identity source that owns their IDs, such as Salesforce or HubSpot. Rows match existing customers by that source’s external ID; unmatched rows do not create customers.

If warehouse and customer-source IDs differ, add a bridge table containing both.

Account attributes need a separate current-state table or view with one row per nonblank account ID. Publish the latest values in Snowflake before Sonora reads them. Daily usage rows often repeat ARR and metadata; Sonora neither sums those attributes nor chooses the latest historical row.

For Salesforce, carry the same salesforce_account_id as your usage tables. Select the connected Salesforce identity source and Attach to existing customers. Direct Salesforce IDs need no bridge. Unmatched IDs are reported as unresolved and create no customers in this mode.

Example column Map to
salesforce_account_id Each entity’s account-ID column
arr Customer attributes → ARR
segment Custom fields → customer_segment, string
contracted_seats Custom fields → contracted_seats, number
is_active Custom fields → is_active, boolean

Add a Custom fields entity for this table and choose each field’s stable key, source column and type. To import ARR too, add Customer attributes for the same table. Custom fields can run alone or alongside usage; attaching to existing customers requires no account name.

Grant the Sonora role access to the new database, schema and table or view. Run a dry-run, review unresolved IDs, and save. AI proposals change only the mapping; a sync imports values. Later syncs update mapped keys, preserve unrelated fields and respect manual overrides. Zero and false remain values; a source null sets the mapped value to null.

Sonora imports aggregated usage, not raw events. Each row is one account and product on one date, and each numeric column is a value you have already computed for that account. Sonora never adds rows together during import, so an event, click or session log does not work: each event would be read as the account’s whole value for that day. Roll the events up in a view and point Sonora at the view.

Column What to map
Account ID The customer ID, or a key linked through a bridge table
Date A date or timestamp for the measurement
Numeric measures The columns you select as metrics, such as API calls or seats
Product name (optional) An active product’s name in Sonora

Choose a Fallback product for a single-product table, or a Product column for multiple products. Blank product names use the fallback; unknown names are skipped. Default Warehouse product groups usage under a product named Warehouse.

How to aggregate depends on what the column counts:

  • Counts (events, API calls, reports run). Write one value per day. Set Aggregation to Sum so Sonora adds days up into weeks and months.
  • Snapshots (seats, storage, licenses). Write one value per day. Keep Aggregation on Last so a month shows its closing value.
  • Distinct users (active users, active admins). Count each period in your warehouse. Weekly active users are not the sum of daily active users, because someone active on Monday and Tuesday is one weekly user, not two. Sonora cannot recover distinct users from daily totals, so use separate daily, weekly, and monthly views with a different metric column for each period.

For example, once the respective periods are complete:

View account_id date events active_users_day active_users_week active_users_month
USAGE_METRICS 0015g00000AbCdE 2026-09-28 1284 41
USAGE_METRICS 0015g00000AbCdE 2026-09-29 1102 37
USAGE_METRICS 0015g00000AbCdE 2026-09-30 967 35
USAGE_METRICS 0015g00000AbCdE 2026-10-01 1350 44
USAGE_WEEKLY 0015g00000AbCdE 2026-09-28 88
USAGE_MONTHLY 0015g00000AbCdE 2026-10-01 131

September 28 is a Monday, so it dates that week’s count. October 1 dates October’s count. Empty cells indicate columns that are not in that view.

Views that build these metrics from an event log:

CREATE OR REPLACE VIEW REPORTING.ANALYTICS.USAGE_METRICS AS
WITH activity AS (
SELECT account_id, user_id, event_timestamp::DATE AS day
FROM REPORTING.ANALYTICS.EVENTS
)
SELECT account_id, day AS date, COUNT(*) AS events,
COUNT(DISTINCT user_id) AS active_users_day
FROM activity
GROUP BY 1, 2;
-- DATE_TRUNC('WEEK', …) starts weeks on Monday when WEEK_START is 0 or 1.
CREATE OR REPLACE VIEW REPORTING.ANALYTICS.USAGE_WEEKLY AS
WITH activity AS (
SELECT account_id, user_id, event_timestamp::DATE AS day
FROM REPORTING.ANALYTICS.EVENTS
)
SELECT account_id, DATE_TRUNC('WEEK', day) AS date,
COUNT(DISTINCT user_id) AS active_users_week
FROM activity
WHERE day < DATE_TRUNC('WEEK', CURRENT_DATE())
GROUP BY 1, 2;
CREATE OR REPLACE VIEW REPORTING.ANALYTICS.USAGE_MONTHLY AS
WITH activity AS (
SELECT account_id, user_id, event_timestamp::DATE AS day
FROM REPORTING.ANALYTICS.EVENTS
)
SELECT account_id, DATE_TRUNC('MONTH', day) AS date,
COUNT(DISTINCT user_id) AS active_users_month
FROM activity
WHERE day < DATE_TRUNC('MONTH', CURRENT_DATE())
GROUP BY 1, 2;

The weekly and monthly views hold back periods in progress. Map each view separately. The weekly query requires Monday-based weeks; if your account uses another week start, set WEEK_START = 1 on the Sonora service user before querying the view. See Snowflake’s week settings.

Incremental usage syncs resume from the latest imported date for each table. Later changes to earlier dates can be missed, so avoid adding weekly or monthly totals to older daily rows. Contact Sonora if you need to reload corrected history.

After the first sync, open Settings → Products. New metrics default to Last aggregation:

Metric Aggregation Chart tabs
Daily counts, such as events Sum Day, Week, Month
Snapshots, such as seats or storage Last The periods you need
Distinct users for a specific period Last Only that period

Your Snowflake administrator needs permission to create users, roles, and warehouses, and grant data access. SECURITYADMIN alone cannot create warehouses by default; see Snowflake’s access-control guide.

Replace the database, schema, and view names below:

-- Read-only role for Sonora
CREATE ROLE IF NOT EXISTS SONORA_SVC_ROLE;
-- Grants on the database and schema
GRANT USAGE ON DATABASE REPORTING TO ROLE SONORA_SVC_ROLE;
GRANT USAGE ON SCHEMA REPORTING.ANALYTICS TO ROLE SONORA_SVC_ROLE;
-- Grants on each view you want imported
GRANT SELECT ON VIEW REPORTING.ANALYTICS.USAGE_METRICS TO ROLE SONORA_SVC_ROLE;
-- Small dedicated warehouse keeps costs low and easy to attribute
CREATE WAREHOUSE IF NOT EXISTS SONORA
WAREHOUSE_SIZE = 'XSMALL'
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE;
GRANT USAGE ON WAREHOUSE SONORA TO ROLE SONORA_SVC_ROLE;
-- Service account
CREATE USER IF NOT EXISTS SONORA_SVC
TYPE = SERVICE
DEFAULT_ROLE = SONORA_SVC_ROLE
DEFAULT_WAREHOUSE = SONORA;
GRANT ROLE SONORA_SVC_ROLE TO USER SONORA_SVC;

Grant SELECT on every account, usage, and bridge table or view you map. Use ON TABLE for tables and ON VIEW for views. Each additional database and schema also needs USAGE. If a network policy applies, allow Sonora’s static IPs.

Open Settings → Integrations → Snowflake → Configure and enter:

Field Example
Account Identifier ACME-AB12345
Username SONORA_SVC
Role SONORA_SVC_ROLE
Warehouse SONORA
Database REPORTING
Schema ANALYTICS

Find your identifier in Snowsight’s account details, or run:

SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME();

See Snowflake’s account-identifier guide.

Click Generate key pair in Sonora. This saves the connection immediately. Copy the Public Key, remove the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- lines, and join the remaining lines into one string:

ALTER USER SONORA_SVC SET RSA_PUBLIC_KEY = '<public key from Sonora>';

The role running this command needs ownership of the user or MODIFY PROGRAMMATIC AUTHENTICATION METHODS on it. See Snowflake’s key-pair setup. Return to Sonora and click Test connection.

In Generate mapping, choose From connection, discover and select your tables, then click Generate. Alternatively, choose From file to upload a description of your tables. Review customer matching, mapped fields, usage date and metric columns, and product selections. If Product usage path is shown on an existing connection, choose Account-linked product usage to activate the newly mapped usage tables.

Click Run dry-run to check access and customer matching without importing records. Re-run after edits; usage mappings need a successful check before saving. Set your Sync Schedule, save, then click Sync now on the connection.

Authentication fails — Check the account identifier, username, and registered public key. Remove PEM headers and line breaks. If you regenerate the key in Sonora, update it in Snowflake too.

Tables are missing or unreadable — Check the configured database and schema, then run SHOW GRANTS TO ROLE SONORA_SVC_ROLE;. Confirm USAGE on the warehouse, database, and schema, and SELECT on each mapped table or view.

Rows are skipped — Review dry-run results, account IDs, bridges, dates, and product names. Existing-customer matching needs the correct identity source and an already imported customer.

Connection times out — Check the account identifier, network policy, and warehouse’s AUTO_RESUME setting.

Map a current contacts table or view to People (contacts). Each row needs an email and an account key that resolves through the mapping’s selected identity source, such as a Salesforce account ID. Run the dry-run to review unresolved accounts, then save and sync. The same mapping can include account attributes and either usage path.

Optional columns map to first name, last name, title, phone, LinkedIn URL, external ID and a boolean champion flag. Email matching is case-insensitive. Sync creates missing contacts and fills blank core fields on existing contacts; it preserves populated fields and existing customer assignments. Unresolved accounts, employee addresses and suppressed contacts are skipped. Contact counts appear by table in sync history.

A mapped champion boolean updates on resync; blank or invalid values leave the existing flag alone. Supply a boolean-compatible source column rather than a buying-role label. This flag does not replace Champion Status enrichment or drive the enrichment-based “Champions Only” email audience. Contact custom fields, economic-buyer roles and manual ownership of imported champion flags are not part of this import. Contact CSV fill remains available for custom roles on existing contacts.