CertSafari
    Snowflake SnowPro Advanced: Data Engineer (DEA-C02)· Lessons

    Domain 5 · Lesson 17/22

    Snowflake External Functions: How They Work and CREATE EXTERNAL FUNCTION

    Define and create external functions.

    12 min read
    3.57% of exam
    4 sources
    Published 5 Oct 2026
    Docs as of 4 Oct 2026

    What you will be able to do

    • Name the four components of an external function (external function, remote service, proxy service, API integration) and say what each one does
    • Trace one external function call from the SQL statement to the remote service and back, including the JSON batch format
    • Write a CREATE EXTERNAL FUNCTION statement and pick the right optional parameters
    • Spot the places where an external function cannot be used, and design a remote service that handles batching and retries

    Key concept

    External function — An external function is a UDF that holds no code of its own. It is a Snowflake object that stores where to send each row and how to authenticate. The work itself runs in a remote service outside Snowflake, which Snowflake reaches through a cloud proxy service.

    1.Four pieces: function, proxy, remote service, integration

    An external function is a kind of UDF, but it has no handler code. Inside Snowflake it is a database object in a specific database and schema. It stores what Snowflake needs to reach the code, including the URL of the proxy service. Three other pieces sit around it. The remote service is the code that does the work. It must behave like a function and return a value. It must accept JSON input, return JSON output and expose an HTTPS endpoint. It can be an AWS Lambda function, a Microsoft Azure Function, or an HTTPS server such as Node.js on an EC2 instance. The proxy service relays requests and responses between Snowflake and the remote service. It can also authenticate requests and support subscription billing. The API integration is a Snowflake object that holds the security information needed to work with the proxy.

    The four components of an external function
    ComponentWhere it livesRoleExamples
    External functionSnowflake database and schemaStores the proxy URL and the API integration to use; called like any UDFmy_database.my_schema.my_external_function
    Proxy serviceCloud providerRelays data to and from the remote service; can authenticate callers and enforce paid subscriptionsAmazon API Gateway, Microsoft Azure API Management service
    Remote serviceOutside SnowflakeExecutes the code; accepts JSON, returns JSON, exposes an HTTPS endpointAWS Lambda function, Microsoft Azure Function, HTTPS server on EC2
    API integrationSnowflake (created with CREATE API INTEGRATION)Stores security information for the proxy or remote service—

    Why choose this over an ordinary UDF? The remote code can be written in languages internal UDFs don't support, such as Go and C#. It can use libraries an internal UDF can't reach, such as commercial machine-learning scoring libraries. The same service can also be called from software outside Snowflake. The cost is setup: before the first call, an administrator has to configure the cloud platform, and that work needs knowledge of the platform's security.

    Checkpoint 1 of 7· Match them up

    Match each component to its job

    Tap a term, then the definition that fits it.

    Sources1

    2.One call, end to end: POST, batches and JSON rows

    While a query runs, Snowflake reads two things: the external function definition, which gives the proxy URL and the name of the API integration, and the API integration itself, which gives the proxy resource and its authentication details. Snowflake then builds an HTTP POST containing the data as JSON, HTTP headers and the integration's authentication information, and sends it to the proxy. The proxy forwards the request to the remote service. The result travels back the same way to the SQL statement. If the remote service replies with a status code that means 'still processing', Snowflake polls with HTTP GET requests until it gets the result, the call times out or an error comes back.

    Checkpoint 2 of 7· Put it in order

    Put the steps of an external function call in order

    1. 1.Snowflake sends an HTTP POST with JSON data, headers and authentication to the proxy service
    2. 2.The remote service returns the result back through the chain to the SQL statement
    3. 3.A client program sends Snowflake a SQL statement that calls the external function
    4. 4.The proxy service forwards the request to the remote service
    5. 5.Snowflake reads the external function definition and the corresponding API integration

    Rows go out in batches. Batching allows more parallelism and can keep the remote service from being overloaded. Each batch has a unique batch ID, and retries usually happen one batch at a time. The POST body is a JSON object with a single key, data. Its value is an array with one entry per row. The first element of each row is the row number, and the function arguments follow.

    Request body for f(integer, varchar, timestamp): row number first, then the three argumentsjson
    { "data": [ [0, 10, "Alex", "2014-01-01 16:00:00"], [1, 20, "Steve", "2015-01-01 16:00:00"], [2, 30, "Alice", "2016-01-01 16:00:00"], [3, 40, "Adrian", "2017-01-01 16:00:00"] ] }

    The response uses the same shape. It returns one row per input row, each holding a row number and exactly one value. The value can be compound, such as an OBJECT. The row numbers must match the request and come back in the same order. Snowflake also sends headers such as sf-external-function-current-query-id, for linking calls back to Snowflake queries, and sf-external-function-query-batch-id.

    Response body: each row returns its row number and one OBJECT valuejson
    {
        "data":
            [
                [ 0, { "City" : "Warsaw",  "latitude" : 52.23, "longitude" :  21.01 } ],
                [ 1, { "City" : "Toronto", "latitude" : 43.65, "longitude" : -79.38 } ]
            ]
    }
    HTTP status codes Snowflake recognizes from the remote service
    CodeMeaning to Snowflake
    200Batch processed successfully
    202Batch received and still being processed; Snowflake polls with GET
    Any other valueTreated as an error

    Checkpoint 3 of 7· Check yourself

    In the JSON request Snowflake sends, what is the first element of each row array?

    Sources12

    3.Writing CREATE EXTERNAL FUNCTION

    The DDL has three parts. The first is the signature: name, arguments and RETURNS type. The arguments should match what the remote service expects. The second is API_INTEGRATION, which names the integration used to authenticate to the proxy. The third is AS, the invocation URL of the proxy and resource. Everything else is optional. Because functions are resolved by name and argument types, external functions can be overloaded. CREATE OR ALTER EXTERNAL FUNCTION updates an existing function in place.

    CREATE EXTERNAL FUNCTION syntaxsql
    CREATE [ OR REPLACE ] [ SECURE ] EXTERNAL FUNCTION <name> ( [ <arg_name> <arg_data_type> ] [ , ... ] )
      RETURNS <result_data_type>
      [ [ NOT ] NULL ]
      [ { CALLED ON NULL INPUT | { RETURNS NULL ON NULL INPUT | STRICT } } ]
      [ { VOLATILE | IMMUTABLE } ]
      [ COMMENT = '<string_literal>' ]
      API_INTEGRATION = <api_integration_name>
      [ HEADERS = ( '<header_1>' = '<value_1>' [ , '<header_2>' = '<value_2>' ... ] ) ]
      [ CONTEXT_HEADERS = ( <context_function_1> [ , <context_function_2> ...] ) ]
      [ MAX_BATCH_ROWS = <integer> ]
      [ COMPRESSION = <compression_type> ]
      [ REQUEST_TRANSLATOR = <request_translator_udf_name> ]
      [ RESPONSE_TRANSLATOR = <response_translator_udf_name> ]
      AS '<url_of_proxy_and_resource>';
    Optional parameters and what they control
    ParameterDefaultWhat to know
    CALLED ON NULL INPUT / RETURNS NULL ON NULL INPUT (STRICT)CALLED ON NULL INPUTSTRICT skips the call and returns NULL if any input is NULL
    VOLATILE / IMMUTABLEVOLATILESnowflake does not check IMMUTABLE; set it explicitly
    HEADERSnoneConstant strings sent as sf-custom-<name>; no underscores in names; total 8 KB or less
    CONTEXT_HEADERSnoneContext function results such as CURRENT_ROLE() sent as sf-context-<name>, plus a -base64 copy
    MAX_BATCH_ROWSSnowflake estimatesA maximum for constrained services, not a tuning knob

    Two defaults catch people out. VOLATILE is the default, and Snowflake doesn't verify IMMUTABLE: if you mark a non-deterministic service IMMUTABLE, the behaviour is undefined. Snowflake therefore recommends always setting the option explicitly. MAX_BATCH_ROWS exists only for remote services with memory or similar limits. Leave it unset unless the service needs a cap. If calls time out while every component looks healthy, one documented step is to try a smaller batch size.

    Checkpoint 4 of 7· Check yourself

    You define HEADERS = ( 'volume-measure' = 'liters' ). Which HTTP header does the remote service receive?

    Checkpoint 5 of 7· Exam question

    A data engineer used ACCOUNTADMIN to create an API integration named `address_api_integration` that points to a third-party address validation service. An analyst role now needs to run `CREATE EXTERNAL FUNCTION` bound to that integration, but the statement fails with an insufficient privileges error. What should the engineer grant to let the analyst role create the function without over-provisioning access?

    Sources3

    4.Calling it from SQL, and where it can't go

    To a SQL user, an external function looks like any other UDF. It takes parameters, returns a value (which can be a VARIANT holding JSON), and can be nested inside larger expressions. You call it by its fully qualified name.

    Calling an external function by its fully qualified namesql
    select my_database.my_schema.my_external_function(col1) from table1;

    The limits are what the exam tests. External functions must be scalar: one value per input row. Only functions can be built this way, not stored procedures. They can't be shared through Secure Data Sharing, and neither can any shared object that uses one, such as a shared view. They can't be used in a CREATE TABLE DEFAULT clause or in a COPY transformation. A batch response can be at most 10MB. Because the optimizer can't see inside the remote service, external functions carry more overhead than built-in functions or internal UDFs and usually run more slowly.

    The remote service also has to be designed for how Snowflake calls it. Batch sizes, the order of batches and the order of rows within a batch can all vary. ORDER BY is usually applied after the external function runs. So each row's result must depend only on that row. Snowflake retries on transient network errors, 429 responses and 5XX responses, so the service may see the same row more than once. A retried batch keeps its batch ID, which makes the ID usable as an idempotency token.

    Checkpoint 6 of 7· Check yourself

    Which use of an external function is supported?

    Checkpoint 7 of 7· Exam question

    A security reviewer is auditing an AWS-hosted external function. The Lambda proxy is fronted by an IAM role, and the reviewer wants to be certain that only this specific Snowflake account's integration can assume that role, not any other AWS API Gateway caller who discovers the role's ARN. Which mechanism enforces that requirement?

    Sources14

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Set MAX_BATCH_ROWS to make an external function run faster.Why is that wrong?

      MAX_BATCH_ROWS is a ceiling for remote services with memory or similar limits. If you leave it unset, Snowflake picks the batch size.

      Covered in Writing CREATE EXTERNAL FUNCTION

    2. 2.An external function can enrich rows inside a COPY INTO transformation while loading.Why is that wrong?

      COPY transformations are on the list of places where external functions can't be used, along with DEFAULT clauses and shared objects.

      Covered in Calling it from SQL, and where it can't go

    3. 3.The remote service receives each row exactly once, in ORDER BY order.Why is that wrong?

      Snowflake may retry a batch, so a row can arrive more than once. Batch and row order can vary, so each row should be processed independently.

      Covered in Calling it from SQL, and where it can't go

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “To be called by the Snowflake external function feature, the remote service must: Accept JSON inputs and return JSON outputs.”
      ↩︎ Four pieces: function, proxy, remote service, integration
      “The proxy service can increase security by authenticating requests to the remote service.”
      ↩︎ Four pieces: function, proxy, remote service, integration
      “Snowflake sends one or more HTTP GET requests to retrieve the result from the remote service”
      ↩︎ One call, end to end: POST, batches and JSON rows
      “Currently, external functions must be scalar functions. A scalar external function returns a single value for each input row.”
      ↩︎ Calling it from SQL, and where it can't go
      “an external function does not contain its own code; instead, the external function calls code that is stored and executed outside Snowflake”
      ↩︎ Key concept
      “A COPY transformation.”
      ↩︎ Exam trap 2
      “Snowflake does not call a remote service directly. Instead, Snowflake calls a proxy service, which relays the data to the remote service.”
      ↩︎ Prediction
      “Snowflake stores security-related external function information in an API integration.”
      ↩︎ Checkpoint
      “The proxy service receives the POST and then processes and forwards the request to the actual remote service.”
      ↩︎ Checkpoint
      “An external function can appear in any clause of a SQL statement in which other types of UDF can appear.”
      ↩︎ Checkpoint
    2. 2.
      “the row numbers in the returned data must correspond to the row numbers in the data that Snowflake sent”
      ↩︎ One call, end to end: POST, batches and JSON rows
      “The first column is always the row number (i.e. the 0-based index of the row within the batch).”
      ↩︎ Checkpoint
    3. 3.
      “Snowflake recommends that you set this explicitly rather than accept the default.”
      ↩︎ Writing CREATE EXTERNAL FUNCTION
      “This is the name of the API integration object that should be used to authenticate the call to the proxy service.”
      ↩︎ Writing CREATE EXTERNAL FUNCTION
      “This parameter is not a performance tuning parameter. This parameter specifies a maximum size, not a recommended size.”
      ↩︎ Exam trap 1
      “This causes Snowflake to add two HTTP headers to every HTTPS request: sf-custom-volume-measure and sf-custom-distance-measure”
      ↩︎ Checkpoint
    4. 4.
      “When Snowflake retries a request for a specific batch, Snowflake uses the same batch ID as it used earlier for the same batch.”
      ↩︎ Calling it from SQL, and where it can't go
      “Snowflake strongly recommends that the remote service process each row independently.”
      ↩︎ Exam trap 3

    Continue to page 2 of 2

    Securing Snowflake External Functions: Privileges, API Integrations and SECURE

    Spotted a mistake, or was something unclear? Tell us.