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]
- Connection
- Via webhook + endpoint
- Data storage
- Tool
- ClickHouse
- Custom ingestion receiver
- Data flow
- Unify → Vercel Function → ClickHouse
- JSON payload
At a glance
- Persist accepted records before acknowledging the Play
- Choose a client batch or asynchronous-insert strategy
- 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.
| Stage | Decision to make |
|---|---|
| Intake | Persist accepted records before acknowledging the Play |
| Batching | Choose a client batch or asynchronous-insert strategy |
| Persistence | Confirm flush or insert completion in the worker |
| Consumption | Define 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.
Decouple prompt intake acknowledgement from the worker’s insert strategy.
- Choose the row contract and durable intake
- Configure batching or asynchronous inserts
- Inspect a small controlled set after confirmed insertion
Investigate a delayed or repeated handoff
A sender retry or worker recovery can replay the same accepted data.
Record identity and database insert behavior are different decisions.
- Define how the application recognizes a repeated handoff
- Replay a controlled record
- Inspect the worker result and the analytical query output
Illustrative workflow, not a preconfigured automation. Complete these checks in your own account.
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.
POST / JSON to intake, then batched or async inserts
| Decision | What to know |
|---|---|
| Transport | The ClickHouse HTTP interface supports POST for data-changing queries[3] |
| Format | JSONEachRow represents rows as separate JSON objects[6] |
| Efficiency | Batching reduces the overhead of many small inserts[4] |
| Async processing | Asynchronous inserts buffer data before a flush[5] |
| Acknowledgement | wait_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
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]
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]
Request configuration
- Method
POST- URL pattern
https://YOUR_APP.vercel.app/api/unify-to-clickhouse- Headers
Content-Type: application/jsonX-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
{
"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 field | Value to send |
|---|---|
event | A fixed label you choose for this workflow |
prospect_name | Use {{ person.first_name }} and {{ person.last_name }} for the prospect name |
prospect_email | Use {{ person.email }}; decide how to handle missing values |
company_name | Use {{ company.name }} |
company_domain | Use {{ 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]
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.
