## 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.

1. On the **Webhook** trigger, map the payload's email into the `lead_email` variable (use the
   **Auto-map fields** button).
2. Add **Find contact** with *Look up by* = Email and *Value* = `{{ vars.lead_email }}`.
   Wire **Not found** to the path that creates the contact/deal.
3. Wire **Found** into a **CRM lookup** with *Deal status* = Open.
4. 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 `_count` and `_list` companions — 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 `count` and 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).

## See also

- [Flow Builder: trigger data, mapping and transformation](/hc/ajuda/articles/automation-flows-flow-builder-dados-e-mapeamento-en)
- [Flow Builder: build conversational flows visually](/hc/ajuda/articles/automation-flows-flow-builder-en)
- [Flow Builder: native actions and the contact action node](/hc/ajuda/articles/automation-flows-flow-builder-acoes-nativas-en)