Outbound webhooks are available on Team and Enterprise plans.
Prerequisites
- A ClickHouse server reachable over its HTTP or HTTPS interface, for example port
8443for HTTPS or8123for HTTP. The native protocol port (9000) is not used. - A ClickHouse user with a password and
INSERTpermission on the destination table. - The destination table created before you enable the endpoint. The connector does not create or alter tables.
Configuration
Grant insert permission
Give the connector user insert access on the destination table only. ClickHouseGRANT syntax:
Default destination behavior
Without a transformation, Svix inserts each webhook payload directly using the ClickHouseJSONEachRow format. Top-level payload fields are matched to columns by name.
ClickHouse is different from the other warehouse connectors in one important way: it does not add any columns of its own. There is no generated id column and no payload column unless you define them. You own the full schema.
Novu webhook bodies are nested, and message fields such as subscriberId and channel sit under data.object rather than at the top level. Because of that, plan on writing a transformation for this connector unless your table columns exactly match the top-level keys of the webhook body.
Create the destination table
This table stores a few flattened fields plus the full webhook body:received_at is not returned by the transformation below. Columns omitted from a JSONEachRow row take their declared default, so ClickHouse fills the insert time.
Transformation contract
The transformation receives one batch and returns the rows to insert: The handler receives one delivery batch:input.events, an array whose length is capped by the endpoint batch sizeinput.events[].eventType, the Novu event type, for examplemessage.sentinput.events[].payload, the webhook body
payload.object is the resource type as a string, such as "message", and the resource itself is under payload.data.object. For message events, fields such as subscriberId and channel are therefore at event.payload.data.object. Other event families use different resource shapes, so guard extracted fields with defaults.
- Output: an object with a
rowsarray. Each row is an object whose keys match your ClickHouse column names. Each row is inserted separately usingJSONEachRow.
event.payload.data.object:
String column.
Configure in the Dashboard
1
2
Enter connection details
Enter the URL, username, password, table name, and database.3
Configure the transformation
Paste the transformation above and adjust the keys so they match your column names exactly.4
Select event types
Subscribe to the event types you want to store. If you subscribe to more than one, confirm the transformation produces valid rows for every one of them, since a single table receives all of them.5
Test the endpoint
Click Create, open the endpoint, go to the Testing tab, and use Send Example for each subscribed event type. Confirm success in the Logs tab.Verify delivery
Query the table withclickhouse-client: