Overview
Besides acting (sending messages, creating deals, opening tasks), a flow can now read what already exists in the platform and decide from it. There are seven lookup nodes:
| Node | What it reads | Outputs |
|---|---|---|
| Find contact | A contact by email, phone, identifier or custom attribute | Found Β· Not found Β· Error |
| Find conversations | The contact's conversations (status/inbox filters) | Found Β· Empty Β· Error |
| CRM lookup | The contact's deals (pipeline, stage and status filters) | Found Β· Empty Β· Error |
| Task lookup | Tasks linked to the contact or the conversation | Found Β· Empty Β· Error |
| Commerce lookup | The contact's latest purchase/payment event and history | Found Β· Empty Β· Error |
| Charge lookup | The contact's charges by status (Payments module) | Found Β· Empty Β· Error |
| Booking lookup | The contact's next or last appointment (Calendar module) | Found Β· Empty Β· Error |
Plus a smart wait:
- Wait until: pauses the flow until a condition (the same editor as the Condition node, groups included) becomes true β re-checking at regular intervals β or until the timeout elapses.
A lookup never crashes the flow: any failure exits through the Error port, which you can wire to a fallback path.
Prerequisites
- The Flow Builder module enabled; Administrator to edit and publish.
- Charge lookup requires the Payments module; Booking lookup requires the Calendar module. The others work on any account (CRM/Tasks/Commerce degrade to the Empty output when the module is unavailable).
Step by step
Example: dedupe leads arriving via webhook.
- On the Webhook trigger, map the payload's email into the
lead_emailvariable (use the Auto-map fields button). - Add Find contact with Look up by = Email and Value =
{{ vars.lead_email }}. Wire Not found to the path that creates the contact/deal. - Wire Found into a CRM lookup with Deal status = Open.
- On the CRM node's Found output, end the flow (the lead already has an open deal); on Empty, create the deal.
Tip: the gallery ships the "Webhook lead intake (dedupe + CRM)" template with this flow ready.
Settings & options
- Result variable: each lookup writes what it found into a variable (e.g.
found_contact,found_deal). List lookups add_countand_listcompanions β use{{ vars.found_deal.title }},{{ vars.found_deal_count }}and so on. - Subject contact: defaults to the conversation/session contact; pick From a variable to point at another one (an id or the result of a previous Find contact).
- Use the found contact in this flow (Find contact): downstream nodes β including
{{ contact.* }}β read the found contact. When the conversation already pins a different contact, the switch is safely ignored (the variable stays available). - Wait until: define the conditions (flat list or ALL/ANY groups), the check interval (minimum 60 s) and the timeout (required, up to 30 days). The Condition met output fires as soon as the condition passes β including immediately when the contact replies; Timeout fires when the deadline elapses. Checks are bounded (at most 500 per wait) and never consume the flow's step budget.
Use cases
- Dedupe before create: Find contact + CRM lookup before opening a deal (ready-made template).
- VIP routing: Find conversations and compare
{{ vars.found_conversations.count }}to recognize recurring customers ("VIP routing" template). - Payment rescue: Commerce lookup + Wait until
{{ commerce.stage }}=payment_confirmed("Pending payment rescue" template). - Overdue charge: Charge lookup with status Overdue and resend the link ("Overdue charge notice" template).
Tips, limits & best practices
- Lookups return at most 10 items (newest first).
- Stored data are safe summaries (essential fields only β never a full record dump).
- Wait until re-evaluates LIVE data when the condition uses context tokens
(e.g.
{{ commerce.stage }}); variables written by earlier lookups are snapshots of the moment they ran. - Always wire the Error output to a fallback path on critical flows.
Troubleshooting
- Always lands on Empty: check the subject contact (does the session have one?) and the filters
(status/pipeline). The session trace shows
countand the reason (no_contact) per step. - Charge/booking lookup lands on Empty as "unavailable": the corresponding module is disabled for the account.
- Wait until never fires: check the interval/timeout and whether the condition uses a token that actually changes (a static variable will never change on its own).