External Access Integration is a Snowflake feature that lets code inside UDFs, stored procedures, and Streamlit apps access external HTTPS endpoints directly. Previously, external communication was only possible through External Functions (via API Gateway), but this feature enables direct communication using Python/Java HTTP libraries (such as requests or urllib).
UDF / Stored Procedure / Streamlit
│
├─ EXTERNAL_ACCESS_INTEGRATIONS = (my_eai) <- set on the function definition
│
└─ External Access Integration (my_eai)
│
├─ ALLOWED_NETWORK_RULES = (rule_1, rule_2) <- controls the destinations
│ └─ Network Rule (rule_1)
│ ├─ TYPE = HOST_PORT
│ └─ VALUE_LIST = ('api.openai.com:443')
│
└─ ALLOWED_AUTHENTICATION_SECRETS = (api_key_secret) <- credentials
└─ Secret (api_key_secret)
└─ TYPE = GENERIC_STRING / OAUTH2 / PASSWORD-- Network Rule that allows access to an external host
CREATE OR REPLACE NETWORK RULE openai_rule
MODE = EGRESS
TYPE = HOST_PORT
VALUE_LIST = ('api.openai.com:443');
-- Allowing several hosts
CREATE OR REPLACE NETWORK RULE multi_api_rule
MODE = EGRESS
TYPE = HOST_PORT
VALUE_LIST = (
'api.openai.com:443',
'api.anthropic.com:443',
'hooks.slack.com:443'
);Set the Network Rule's MODE to EGRESS (outbound direction). Use TYPE HOST_PORT to allow combinations of hostname and port. For HTTPS, specify port 443.
-- Generic String secret (an API key)
CREATE OR REPLACE SECRET openai_api_key
TYPE = GENERIC_STRING
SECRET_STRING = 'sk-proj-xxxxxxxxxxxxxxxxxxxx';
-- OAuth2 secret (the token refreshes automatically)
CREATE OR REPLACE SECRET salesforce_oauth
TYPE = OAUTH2
API_AUTHENTICATION = salesforce_security_integration
OAUTH_REFRESH_TOKEN = 'xxxxxxxx';
-- Password secret (Basic authentication)
CREATE OR REPLACE SECRET basic_auth_secret
TYPE = PASSWORD
USERNAME = 'api_user'
PASSWORD = 'secure_password_123';-- Create the External Access Integration
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION openai_eai
ALLOWED_NETWORK_RULES = (openai_rule)
ALLOWED_AUTHENTICATION_SECRETS = (openai_api_key)
ENABLED = TRUE;
-- Combining several Network Rules and Secrets
CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION multi_api_eai
ALLOWED_NETWORK_RULES = (multi_api_rule)
ALLOWED_AUTHENTICATION_SECRETS = (openai_api_key, slack_webhook_secret)
ENABLED = TRUE;-- Call an external API from a Python UDF
CREATE OR REPLACE FUNCTION call_openai_chat(prompt VARCHAR)
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = '3.10'
PACKAGES = ('requests')
HANDLER = 'run'
EXTERNAL_ACCESS_INTEGRATIONS = (openai_eai)
SECRETS = ('api_key' = openai_api_key)
AS $$
import requests
import _snowflake
def run(prompt):
api_key = _snowflake.get_generic_secret_string('api_key')
response = requests.post(
'https://api.openai.com/v1/chat/completions',
headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
},
json={
'model': 'gpt-4o-mini',
'messages': [{'role': 'user', 'content': prompt}],
'max_tokens': 500
},
timeout=30
)
response.raise_for_status()
return response.json()['choices'][0]['message']['content']
$$;
-- Call the UDF
SELECT call_openai_chat('What is Snowflake? Explain it in 30 words.');-- Slack notification procedure
CREATE OR REPLACE PROCEDURE send_slack_alert(message VARCHAR)
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = '3.10'
PACKAGES = ('requests')
HANDLER = 'run'
EXECUTE AS CALLER
EXTERNAL_ACCESS_INTEGRATIONS = (multi_api_eai)
SECRETS = ('webhook_url' = slack_webhook_secret)
AS $$
import requests
import _snowflake
def run(session, message):
webhook_url = _snowflake.get_generic_secret_string('webhook_url')
response = requests.post(
webhook_url,
json={'text': f':warning: Snowflake Alert: {message}'},
timeout=10
)
response.raise_for_status()
return f'Sent: {response.status_code}'
$$;
CALL send_slack_alert('The ETL pipeline failed');| Secret TYPE | Use Case | Retrieval Function in Code |
|---|---|---|
| GENERIC_STRING | API keys, tokens, webhook URLs | _snowflake.get_generic_secret_string() |
| OAUTH2 | OAuth access tokens (auto-refresh) | _snowflake.get_oauth_access_token() |
| PASSWORD | Username/password for Basic authentication | _snowflake.get_username_password() |
| Aspect | External Function | External Access Integration |
|---|---|---|
| Communication path | Through API Gateway | Direct HTTPS from UDF/procedure |
| Proxy server | Cloud API Gateway required | Not required |
| Authentication setup | API Integration (IAM roles, etc.) | Network Rule + Secret |
| Supported languages | Used as a SQL function | Python / Java / Scala |
| Use case | Integrating with existing API Gateways | Direct calls to new external APIs |
| Operation | Required Privilege |
|---|---|
| CREATE NETWORK RULE | CREATE NETWORK RULE privilege on the schema |
| CREATE SECRET | CREATE SECRET privilege on the schema |
| CREATE EXTERNAL ACCESS INTEGRATION | CREATE INTEGRATION privilege (ACCOUNTADMIN recommended) |
| Using EAI in a UDF | USAGE on the EAI + USAGE on the Secret |
Security & Integrations
Question 1
You want to send HTTPS requests directly from a Python UDF to an external REST API, without using an API Gateway (such as AWS Lambda). Which combination of objects is minimally required?
Correct answer: B
To call an external API directly from a UDF without going through an API Gateway, use External Access Integration. Because creating an EAI requires specifying ALLOWED_NETWORK_RULES, you must first create a Network Rule. If authentication is needed, also create a Secret. API Integration is the object used when working with External Functions (via API Gateway).
What is the difference between External Access Integration and API Integration?
API Integration is an authentication configuration that lets an External Function call an external API through a cloud provider's API Gateway. External Access Integration, on the other hand, is a network-level access permission that allows code inside a UDF or stored procedure (Python, Java, etc.) to send HTTP requests directly. API Integration is an indirect call via API Gateway, while External Access Integration is a direct call from function code.
Can I use wildcards for hostnames allowed in a Network Rule?
Wildcards (such as *.example.com) cannot be used for hostnames in VALUE_LIST. You must list each fully qualified domain name (FQDN) individually. If you need to access multiple subdomains, add each one explicitly to VALUE_LIST. This is an intentional security constraint designed to strictly control allowed destinations.
How do I securely manage secrets (API keys, etc.) in a UDF that uses External Access Integration?
Use Snowflake's Secret object (CREATE SECRET). Store API keys or OAuth tokens in a Secret, then allow it via ALLOWED_AUTHENTICATION_SECRETS on the External Access Integration. Inside UDF code, you can retrieve the secret's value with _snowflake.get_generic_secret_string() (Python), eliminating the need to hard-code API keys. Access to Secrets is controlled via RBAC.
Practice with certification-focused question sets
Try free questionsNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
Snowflake Certifications: All 11 Exams Explained (2026)
Every SnowPro certification — Associate, Core, Specialty, Ad...
Snowflake Exam Difficulty Ranking: All 11 Certs Compared (2026)
All 11 SnowPro exams ranked by difficulty with study-time es...
Snowflake Study Guide: Fastest Pass Route by Exam (2026)
How to pass SnowPro certifications efficiently — official ma...
SnowPro Core (COF-C03): Complete Exam Guide (2026)
Pass the SnowPro Core exam — six domains, scope, sample ques...
SnowPro Associate Platform (SOL-C01): Complete Guide (2026)
The entry-level SnowPro Associate exam — scope, weighting, s...