This destination invokes a Microsoft Azure function whenever data changes in your model. It makes it possible to build your own custom integrations that execute code written in any language that Azure functions supports.
This destination was designed to be as flexible as possible. You can exercise granular control over function triggers, batching, rate limits, concurrency limits, and even error handling. Together, these features let you integrate Hightouch with any internal tool or third-party API.
Under the hood, the Azure functions destination gives you Hightouch's powerful sync engine, so you continue to benefit from the security and observability features available in our native SaaS destinations.
Example use cases include:
Syncing data to web APIs not yet natively supported
Enriching data using external sources like Clearbit and ZoomInfo
Transforming and filtering data using code instead of SQL
When setting up the Azure functions destination for the first time, you need to enter your function's URL and it's access key for authorizing invocations.
Once you've connected to your Azure function in your Hightouch workspace, the next step is to configure a sync that invokes your function whenever rows are added, changed, or removed in your model.
Hightouch monitors your data model for added, changed, and/or removed rows. In this step, you specify which of these events should invoke your function.
Suppose you want to use an Azure function to send a confirmation email whenever a customer places a new order or updates an existing order. Your model might look something like SELECT * FROM orders. The Azure function should be triggered whenever rows are added—for example, when customers place new orders—or whenever rows change—when orders are updated. Therefore, you would want to enable the Rows added and Rows changed triggers. When invoking your function, Hightouch passes along metadata about why the function was invoked.
All function invocations are synchronous, meaning that Hightouch invokes your Azure function and waits for its response.
In this step, you tell Hightouch how to handle rows present in your model results during the first sync run.
Certain workflows, such as hydrating a CRM for the first time, may require performing a backfill of all rows during the initial sync. For other use cases, such as sending confirmation emails, you might only want to invoke your function in response to future data changes.
By default, Hightouch separately invokes your Azure function for each added, changed, or removed row.
Certain high-throughput use cases may require batching together multiple rows in the payload. Hightouch supports batches of up to 1000 rows per function invocation.
Batching isn't recommended unless absolutely necessary for performance reasons. Enabling this feature requires your Azure function to be either idempotent or significantly more fault tolerant in the event of a partial batch failure.
In this step, you declare whether function invocations should be throttled.
To determine the ideal limits, you should consider whether your function interacts with any downstream services that have limits of their own.
Most modern web APIs enforce rate limits, which set a maximum allowed number of requests per second, minute, or hour. Occasionally, APIs may also have concurrency limits, which set a maximum allowed number of requests that can be processed simultaneously. Rate limits and concurrency limits both affect overall sync speed.
Azure functions can fail for many reasons. Hightouch's retry logic for this destination doesn't discriminate between invocation errors, for example, missing permissions, runtime errors, for example, due to syntax issues, or function errors, for example, due to uncaught exceptions. Hightouch retries all errors eventually.
In this step, you decide whether errors should be retried immediately or during the next sync run. If you choose to retry immediately, you can specify how many retries should be attempted during the sync run. If all these retries fail, Hightouch retires the request during subsequent sync runs until it succeeds.
If an error is gracefully caught in your function, you can flag it as a rejected row and provide a custom error message using the response format specified in the error handling section.
You can also include retry logic inside of your Azure function. After exhausting all retry attempts during a function invocation, respond with an error so that Hightouch knows to reinvoke the function later.
The payload, also known as the "event document," contains your row data in JSON format, along with additional metadata. When writing your Azure function, you can assume that all function invocations include a payload following this schema:
When batching is enabled, rows sharing a common operation type—add, change, remove—are batched together. Function invocations always represent exactly one operation type.
If your Azure function fails to process any rows, it can respond with an array of "rejected rows" that encountered errors. Each rejected row should be identified by its primary key/value and may be associated with an optional error message. Hightouch retries these rows.
If there is an error, the response payload looks like this:
While processing these rows, your Azure function encounters two errors:
Alice's email can't be found in the downstream service
Bob's email already exists in the downstream service
To surface these errors in Hightouch, your function should respond like this:
{"errors":[{"primary_key_value":"928713","reason":"Email not found"},{"primary_key_value":"283743","reason":"Email already exists"}]}
The primary key values (928713 and 283743) refer to customer_id values. The customer_id column was designated the primary_key_column in the function invocation payload.
If your function experiences an invocation error, for example, exceeding Azure function rate limits, runtime error, for example, due to syntax issues, or function error, for example due to uncaught exceptions, all rows in the batch are automatically marked as rejected rows.
To date, our customers haven't experienced any errors while using this destination. If you run into any issues, please don't hesitate to . We're here to help.
Hightouch provides complete visibility into the API calls made during each of your sync runs. We recommend reading our article on debugging tips and tricks to learn more.