Skip to integration content

How to integrate Unify with ClickHouse

To integrate Unify with ClickHouse for storage, send prospect JSON to an authenticated ingestion receiver that durably queues work. A worker maps the records to ClickHouse’s input format and batches inserts or uses asynchronous inserts. Confirm database persistence separately from accepting the Unify request.[1][3]

By UnifyDocumentation reviewed
Connection
Via webhook + endpoint
Data storage
Tool
ClickHouse
Custom ingestion receiver
Data flow
Unify → Vercel Function → ClickHouse
JSON payload

At a glance

  1. Persist accepted records before acknowledging the Play
  2. Choose a client batch or asynchronous-insert strategy
  3. Confirm flush or insert completion in the worker

When this workflow makes sense

Start with the decision your team needs to make, then choose the connection that supports it.

Analytical ingestion benefits from treating the incoming webhook and the database insert as separate operations. A prospect may arrive one at a time, while the storage system benefits from batching. Define what each accepted record represents and how the worker makes progress visible. The consumer should be able to distinguish delayed data from rejected data.

A good fit when

Teams using ClickHouse for analytics and able to maintain a controlled ingestion service.

Reconsider the plan when

A transactional review queue with frequent per-person state changes may belong in another system. Choose ClickHouse because the downstream analytical workload needs it, not simply because it accepts HTTP.

Design the handoff

Use this framework to agree on the input, the next action, and who owns the result.

Suggested workflow design, based on the documented capabilities below.

StageDecision to make
IntakePersist accepted records before acknowledging the Play
BatchingChoose a client batch or asynchronous-insert strategy
PersistenceConfirm flush or insert completion in the worker
ConsumptionDefine how the analytical consumer recognizes delayed and repeated records

Explore the scenarios

Choose the situation that fits your team and work through the proposed plan.

Open a scenario to explore its plan. Checklists track your selections in this page only.

Collect a selected-prospect analytics feed

Prospects arrive individually but the analytical destination benefits from grouped writes.

The decision that matters

Decouple prompt intake acknowledgement from the worker’s insert strategy.

  1. Choose the row contract and durable intake
  2. Configure batching or asynchronous inserts
  3. Inspect a small controlled set after confirmed insertion
Your validation checklist
0 of 3 checks marked by you
Investigate a delayed or repeated handoff

A sender retry or worker recovery can replay the same accepted data.

The decision that matters

Record identity and database insert behavior are different decisions.

  1. Define how the application recognizes a repeated handoff
  2. Replay a controlled record
  3. Inspect the worker result and the analytical query output
Your validation checklist
0 of 3 checks marked by you

Illustrative workflow, not a preconfigured automation. Complete these checks in your own account.

Connect your tools to Unify

Set up your integration or walk through it with our team

Define success before launch

Inspect the data and the intended outcome separately. Connection status is only the first check.

Expected, not tested

The ingestion worker confirms the database insert and the expected prospect values can be read from the destination table.

Check the worker’s insert result and the stored row or event. A webhook acknowledgement confirms durable intake only; wait_for_async_insert=0 would acknowledge buffering before confirmed persistence.

Documentation-based reference. This workflow has not been tested end to end. Use a record or event you control before enabling live activity.

Questions answered

Common decisions when connecting Unify and ClickHouse.

Does ClickHouse have an HTTP endpoint?

Yes. Its HTTP interface supports database requests. This article proposes a separate receiver so authentication, durable intake, batching, and replay handling stay under application control.[3]

Why avoid one synchronous insert per prospect?

Frequent small inserts create many data parts. Batch in the client where practical or use asynchronous inserts for high-frequency small batches.[4]

Is async_insert the same as returning success immediately?

Not necessarily. With wait_for_async_insert=1, the client waits for the buffered data to be flushed. That differs from fire-and-forget acknowledgement.[5]

Can I send the example JSON unchanged to any table?

Map the fields to your actual table schema and use the expected input format. JSONEachRow describes rows; it does not define your table or business identity.[6]

Will ClickHouse storage synchronize back to Unify?

This is an outbound handoff only. The Unify Webhook action does not establish a return synchronization path.[2]

Limits & decisions

Check these boundaries before designing a live workflow around the connection.

  • Requires a custom receiver and a worker with deliberate ingestion settings
  • No schema, ordering key, or uniqueness guarantee is created by this article
  • Database credentials stay in the worker rather than the prospect payload
  • Review the target schema and replay behavior for your actual workload
  • No live ClickHouse query or insertion has been executed

What the connection supports

Understand the connection, the data involved, and the behavior that matters for a Unify + ClickHouse workflow.

Connection flowVia webhook + endpoint
Prospect data to analytical storage

POST / JSON to intake, then batched or async inserts

Documented behavior at a glance
DecisionWhat to know
TransportThe ClickHouse HTTP interface supports POST for data-changing queries[3]
FormatJSONEachRow represents rows as separate JSON objects[6]
EfficiencyBatching reduces the overhead of many small inserts[4]
Async processingAsynchronous inserts buffer data before a flush[5]
Acknowledgementwait_for_async_insert=1 waits for flush completion[5]

Technical setup reference

References and requirements for the ClickHouse connection.

Connection requirements and setup checklist

Before connecting

  • A Unify Play with a Webhook action
  • An HTTPS receiver, durable job storage, and a worker maintained by your team
  • A destination table and an agreed definition of record identity
  • A database service identity with only the required permissions
  • A ClickHouse HTTPS endpoint and an existing table suited to the intended analytical queries
  • An agreed batching or asynchronous-insert strategy and replay policy
  1. Build authenticated intake

    Implement the custom header check and validate the fictional prospect object. Persist accepted work before returning within Unify’s 8-second deadline. Keep batching and database retries in the ingestion worker.[1][2][7]

  2. Choose the ingestion strategy

    Batch records in the worker when practical. If the application sends frequent small batches, consider ClickHouse asynchronous inserts rather than a synchronous insert for every incoming prospect.[4]

  3. Map rows and authenticate the worker

    Use a restricted ClickHouse identity over HTTPS. Map validated fields to the target columns and serialize row objects as JSONEachRow for the worker’s insert request. Keep database credentials separate from the webhook secret.[3][6]

  4. Confirm the database acknowledgement

    When using asynchronous inserts, use wait_for_async_insert=1 so acknowledgement follows the buffer flush and insertion errors can be returned. This wait belongs in the worker, after durable intake has already acknowledged Unify.[5]

  5. Check the stored data and repeats

    Inspect the inserted sample through a bounded query against the destination table. Test your replay policy and the chosen table’s duplicate behavior before enabling live traffic.[3][4]

Request configuration

Method
POST
URL pattern
https://YOUR_APP.vercel.app/api/unify-to-clickhouse
Headers
Content-Type: application/json
X-Unify-Webhook-Key: YOUR_WEBHOOK_SECRET
Authentication
Suggested receiver authentication: implement X-Unify-Webhook-Key validation in your own HTTPS service. Store its expected value server-side and configure Unify API Key (Header) with the matching secret. This is an application contract you implement, not a built-in database header. Keep database credentials and token renewal in the receiving service.

Choose JSON as the body format. Unify sets Content-Type automatically. The receiver must respond within Unify’s 8-second timeout; request responses are not passed to later Play steps.[2]

Replace URL placeholders with the actual receiver URL from your account or deployed application. These example URLs are not working endpoints.

Example handoff payload

Start with a fictional prospect. Validate the resolved values before using a real record.

Inspect the sample payload and field mapping
Example request body
{
  "event": "prospect_handoff",
  "prospect_name": "Alex Morgan",
  "prospect_email": "alex@example.com",
  "company_name": "Example Company",
  "company_domain": "example.com"
}

Fictional data. Replace sample values before using a real Play.

This JSON is the intake contract. The worker converts accepted records to the destination’s schema and JSONEachRow format; it does not forward arbitrary SQL from the payload. Use the field mapping to distinguish record data from fixed settings. Select available fields in your Play and inspect Expand preview; do not replace configuration values with prospect data.[2]

Payload fieldValue to send
eventA fixed label you choose for this workflow
prospect_nameUse {{ person.first_name }} and {{ person.last_name }} for the prospect name
prospect_emailUse {{ person.email }}; decide how to handle missing values
company_nameUse {{ company.name }}
company_domainUse {{ company.domain }}

The Play sends one JSON prospect object to your receiver. The worker maps it to the actual ClickHouse columns and may combine records into JSONEachRow batches. Incoming property names do not create or select table columns automatically.

Troubleshooting

Start with the stage where the expected data or action stops appearing.

Frequent small inserts create too many parts

Revisit client-side batching or enable asynchronous inserts for small batches. Do not treat each incoming prospect as a reason for a separate synchronous insert.[4][5]

The database acknowledgement arrives before durable storage

Inspect wait_for_async_insert. The recommended value 1 waits for the buffer flush and lets insertion errors reach the worker.[5]

A record cannot be parsed or appears twice

Compare serialized field names and values with the target schema. Then inspect replay behavior separately; data format validation does not establish business-level uniqueness.[6][4]

Sources & review

Official documentation reviewed on September 15, 2026.

Technical claims link to primary documentation from Unify and the destination tool. Scenarios, field choices, and recovery plans are editorial implementation examples. Documentation review is separate from execution testing.

Documentation reviewed; end-to-end execution not tested. No named technical reviewer has signed off on these articles yet.

Content updated: . Report a correction to Unify with the tool name, source URL, and behavior you observed.

  1. [1] Unify: Webhook action
  2. [2] Unify: Webhooks in Plays
  3. [3] ClickHouse: HTTP interface
  4. [4] ClickHouse: Selecting an insert strategy
  5. [5] ClickHouse: Asynchronous inserts
  6. [6] ClickHouse: JSONEachRow
  7. [7] Vercel: Functions for the proposed receiver

Get started with Unify

Create your account or book a demo with our team