Installation
Installing the Zeotap Native App takes about ten minutes of operator time and a couple of minutes of SPCS warm-up while the compute pool pulls container images. The flow has five user-visible stages: install from Marketplace, bind references and approve EAIs, grant account-level privileges, run the two post-install SQL scripts, and visit the claim URL to finish.
You’ll run the SQL as ACCOUNTADMIN (or a role with equivalent CREATE NETWORK RULE, CREATE INTEGRATION, and CREATE USER privileges). Plan to do this once per Snowflake account; subsequent operator changes (upgrades, EAI rotations) only re-run the relevant section.
Prerequisites
- A Snowflake account in a region where SPCS is available.
- ACCOUNTADMIN access (or a role that can create network rules, external access integrations, users, roles, and grants).
- A warehouse Zeotap should run sync and loader jobs against. This is the warehouse SPCS jobs will charge credits to.
- A database Zeotap should write its
CDP_EVENTS,CDP_PLANNER, andCDP_AUDITschemas into. - The Zeotap listing visible in your Snowflake Marketplace (request access from your Zeotap account team if not).
1. Install from Marketplace
In Snowsight, find Zeotap in the Marketplace and click Get. Snowflake creates an Application object in your account from the Zeotap Application Package.
-- Equivalent SQL (Snowsight runs this for you when you click "Get")
CREATE APPLICATION zeotap
FROM APPLICATION PACKAGE zeotap_pkg
USING VERSION v1;After the application is created, Snowsight drops you into the application’s setup page.
2. Bind the warehouse reference and approve EAIs
The setup page shows one reference binding and a list of External Access Integrations to approve.
| Reference | What to bind | Required privileges on the bound object |
|---|---|---|
customer_warehouse | The Snowflake warehouse SPCS jobs should run against. | USAGE, OPERATE |
You’ll add the databases Zeotap reads from after the install is claimed — see Sources for the per-database GRANT script.
The EAI list covers Zeotap’s own egress (signalsmith_sf_api_access to reach the cloud control plane, claude_api_access for AI agents) plus the per-destination integrations you’ll bind in step 4. You only need to approve the bindings now; the actual EAIs are created by the post-install script.
3. Grant account-level privileges
The application also requests three account-level privileges. Grant them in Snowsight or with SQL:
GRANT CREATE COMPUTE POOL ON ACCOUNT TO APPLICATION zeotap;
GRANT BIND SERVICE ENDPOINT ON ACCOUNT TO APPLICATION zeotap;
GRANT CREATE WAREHOUSE ON ACCOUNT TO APPLICATION zeotap;These let the application provision its own SPCS compute pool and bind a public ingress endpoint for the cloud reverse-proxy to reach.
Once these grants land, the application’s setup script automatically creates the SPCS compute pool and the five long-running services. SPCS pulls the container images on first launch — this takes about two minutes. You can watch progress with:
SHOW SERVICES IN APPLICATION zeotap;
SELECT * FROM zeotap.app_data.APP_VERSION;When all five services show READY, the application is ready for the next stage.
4. Run post-install-eais.sql
This script is delivered separately from the application package. Snowflake Native Apps can declare external access integration references in their manifest, but the consumer’s account admin has to author the network rules and EAIs because they govern outbound network egress from your Snowflake account.
The template lives at snowflake-native-app/install/post-install-eais.sql in the Zeotap install package and is a templated SQL file with ${VAR} placeholders that the build pipeline substitutes before delivery. You receive a rendered version with the placeholders filled in — run the rendered version, never the template directly.
The file’s structure, with the placeholders shown:
-- =============================================================================
-- ${BRAND_DISPLAY_NAME} Native App — Post-install External Access Integration setup
-- =============================================================================
CREATE DATABASE IF NOT EXISTS ${BRAND_UPPER}_INFRA;
CREATE SCHEMA IF NOT EXISTS ${BRAND_UPPER}_INFRA.PUBLIC;
USE SCHEMA ${BRAND_UPPER}_INFRA.PUBLIC;
-- 1. Zeotap control plane (REQUIRED) — outbound to ${APP_API_HOST}
CREATE OR REPLACE NETWORK RULE ${BRAND_UPPER}_SF_NET_RULE
TYPE = HOST_PORT MODE = EGRESS
VALUE_LIST = ('${APP_API_HOST}:443', '${EVENTS_API_HOST}:443');
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION ${BRAND_UPPER}_SF_EAI
ALLOWED_NETWORK_RULES = (${BRAND_UPPER}_SF_NET_RULE)
ENABLED = TRUE;
GRANT USAGE ON INTEGRATION ${BRAND_UPPER}_SF_EAI TO APPLICATION ${BRAND_UPPER};
CALL ${BRAND_UPPER}.APP_DATA.REGISTER_REFERENCE_CALLBACK(
'${BRAND_UPPER}_SF_API_ACCESS', 'ADD',
SYSTEM$REFERENCE('EXTERNAL ACCESS INTEGRATION', '${BRAND_UPPER}_SF_EAI', 'PERSISTENT', 'USAGE')
);
CALL ${BRAND_UPPER}.APP_DATA.ATTACH_EAI('${BRAND_UPPER}_SF_API_ACCESS', NULL);
-- ... 21 more sections, one per destination family
-- (Anthropic/Claude, Google, Salesforce, HubSpot, Meta, LinkedIn, TikTok,
-- Snapchat, Pinterest, Slack, Mailchimp, Klaviyo, Customer.io, Intercom,
-- Braze, Amplitude, Mixpanel, S3, GCS, Azure Blob, Webhook)For each destination family the script:
- Creates a network rule allow-listing the destination’s hosts.
- Wraps the rule in an External Access Integration.
- Grants
USAGEon the integration to the Zeotap application. - Calls
REGISTER_REFERENCE_CALLBACKto record the binding inside the application. - Calls
ATTACH_EAItoALTER SERVICEand add the new integration to the running services without a restart.
Comment out any destination family you don’t intend to use. Re-running is idempotent — CREATE OR REPLACE rebuilds the network rule and EAI, and ATTACH_EAI rebuilds the full service-level EAI list each time.
5. Run post-install-auth.sql
This script bootstraps the proxy user, role, and keypair credential the cloud uses to reach into your install. See Auth Setup for the full explanation of why this exists.
-- =============================================================================
-- ${BRAND_DISPLAY_NAME} Native App — Post-install proxy-auth bootstrap
-- =============================================================================
CREATE USER IF NOT EXISTS ${BRAND_UPPER}_PROXY_USER
TYPE = SERVICE
DEFAULT_ROLE = ${BRAND_UPPER}_PROXY_ROLE
COMMENT = 'Cloud-proxy service user for ${BRAND_DISPLAY_NAME} Native App reverse-proxy';
CREATE ROLE IF NOT EXISTS ${BRAND_UPPER}_PROXY_ROLE
COMMENT = 'Role granted to ${BRAND_UPPER}_PROXY_USER';
GRANT ROLE ${BRAND_UPPER}_PROXY_ROLE TO USER ${BRAND_UPPER}_PROXY_USER;
GRANT APPLICATION ROLE ${BRAND_UPPER}.APP_PUBLIC TO ROLE ${BRAND_UPPER}_PROXY_ROLE;
EXECUTE IMMEDIATE $$
DECLARE
pubkey STRING;
register_result STRING;
BEGIN
pubkey := (
CALL ${BRAND_UPPER}.APP_DATA.GENERATE_PROXY_KEYPAIR(
'${BRAND_UPPER}_PROXY_USER',
'${BRAND_UPPER}_PROXY_ROLE'
)
);
EXECUTE IMMEDIATE
'ALTER USER ${BRAND_UPPER}_PROXY_USER SET RSA_PUBLIC_KEY = ''' || :pubkey || '''';
register_result := (CALL ${BRAND_UPPER}.APP_DATA.REGISTER_WITH_CLOUD());
RETURN register_result;
END;
$$;
SELECT * FROM ${BRAND_UPPER}.APP_DATA.CLOUD_REGISTRATION
ORDER BY registered_at DESC LIMIT 1;When the script finishes, the final SELECT returns one row with a claim_url column. That URL is what you open in the next stage.
The two scripts must run in this order: post-install-eais.sql first so the Zeotap control-plane EAI is bound, then post-install-auth.sql so the application can call out to the cloud to register the install. Reversing the order produces a register failed: connection refused error from REGISTER_WITH_CLOUD.
6. Visit the claim URL and sign in
Open the claim_url from CLOUD_REGISTRATION in a browser. It points to https://composable.zeotap.com/login/snowflake?app=<id>. Sign in with email or Google. Zeotap ties the install to your account and creates a default workspace inside the in-account Postgres. You’re redirected to the Zeotap dashboard.
The sidebar now shows a native-app selector next to the workspace picker. To start using Zeotap with your data, add a Snowflake source pointing at the database you want it to read from — see Sources for the GRANT script the form generates. The connection itself uses your bound customer_warehouse, so the only per-database step is running the GRANTs.
Common pitfalls
events.zeotap.comdoesn’t resolve. Snowflake validates each network rule’sVALUE_LISTagainst public DNS at create time and rejects unresolvable hosts. The rendered post-install template substitutes the real host Zeotap uses for ingest. If your install was rendered with a placeholder host, request a fresh build.Future grant on objects of type SCHEMA to APPLICATION is restricted. Snowflake forbidsGRANT ... ON FUTURE ... TO APPLICATION. The post-install script and the in-UI source GRANT block both grant on existing objects only. Re-run the GRANT script whenever you add new schemas or tables you want Zeotap to read.- Compute pool quota exceeded. Native Apps need a fresh compute pool and your account has a per-account compute-pool count limit. Drop unused pools or contact Snowflake support to raise the limit.
my.salesforce.comrejected at network-rule creation. That’s the shared root, not a real host. Replace with your instance host (e.g.acme.my.salesforce.com) before running the Salesforce section, or comment it out and use BYO-EAI per workspace destination.blob.core.windows.netrejected. Same problem — replace with<account>.blob.core.windows.netbefore running the Azure section. The template ships with this section commented out for that reason.
If the install hits a state these notes don’t cover, see Troubleshooting.