Skip to content

Match to Client Task

Overview

The task has two actions, chosen with its Action setting:

Action What it does Items combine as
Match to Client Finds one client, returns its details, and links the event to it Alternatives, tried in order: the first that finds a client wins
Match to Clients Finds every client that fits and returns their IDs as a list All together: a client must fit every item you fill in

Match to Client is an identity lookup. It is how a workflow turns an email address or a phone number arriving from outside into the CRM record it belongs to. Match to Clients is a search: "every client in status Lead whose name contains Uniqon". Most of this page describes the first; Match to Clients has its own section.

This task does not create clients

If nothing matches, the task reports No client matched. and sets run to false. It has no create path at all. To create a client, follow it with a New Client task on the false branch of an If Statement.

When to use this task:

  • Connect an inbound form, email, webhook or call to the client it belongs to
  • Pull a client's status, origin, responsible manager or custom fields into a workflow
  • Check whether a client already exists before creating one
  • Get a list of every client that fits some conditions, to loop over (Match to Clients)

The Match to Client(s) task opened to its settings: Action set to Match to Client and one rule, contact cell number equals the caller number from the trigger

What this task cannot do

You may want to… This task Use instead
Filter clients by Origin Returns match_client_origin, but has no item to search on it MySQL Query, or the API
Filter by status A Client Status item does this, on either action —
Get every client that matches Match to Client returns one client Set Action to Match to Clients
Require several things at once Match to Client treats its items as alternatives Match to Clients, where every item must fit
Match on part of a value, or the opposite of a value Match to Client matches the whole value only Match to Clients: see How each item is matched
Get each matched client's details Match to Clients returns IDs only A Loop with a Match to Client on client_id inside it
Create the client when none matches No create path New Client

Quick Start

  1. Add the task and leave Action on Match to Client
  2. Pick what to match on, most reliable first (usually Contact Email, then Contact Cellphone Number)
  3. Give each a value, usually a variable from an earlier task: {{task_12345_email}}
  4. Follow it with an If Statement on client_matched, to handle "not found"
Action:               Match to Client
Contact Email:        {{task_55123_email}}
Contact Cell Number:  {{task_55123_phone}}

Matching Strategies

This section is about Match to Client. Its criteria are tried in the order they appear on the task and the first one that finds a client wins. They are alternatives, not conditions that combine. For conditions that combine, use Match to Clients.

flowchart TD
    A[Criterion 1] -->|hit| Z[Return that client]
    A -->|no hit| B[Criterion 2]
    B -->|hit| Z
    B -->|no hit| C[Criterion 3]
    C -->|hit| Z
    C -->|no hit| N[No client matched]

Order them most reliable first. An email address identifies one client; a company name or an email domain often identifies several, and the task will return whichever the database returns first.

By email — the most reliable

contact_email matches a linked contact's address exactly, after sanitising. If the value is not a valid email the criterion is skipped and the task moves on.

contact_email: {{task_46171_customer_email}}

By email domain — identifies a company, not a person

contact_email_domain takes the part after @ and matches contacts whose address shares that domain. This is the only criterion that is not an exact match on the whole value.

Use it as a fallback after contact_email, and expect metadata.total_matched above 1 — every contact at that company matches, and the task returns one of them.

By phone — format-tolerant, not fuzzy

contact_cell_number and contact_landline_number normalise the value to E.164 first, then try exact matches against known format variants, falling back to a partial match only if those miss. Different formats of the same number match; different numbers do not.

+27 12 345 6789
+27-12-345-6789
0123456789

If the value cannot be parsed as a phone number, the task writes a note into run_text and skips that criterion rather than failing.

By company name — exact only

company_name is an exact match on the client's company name. It is not case-insensitive fuzzy matching and it does not handle abbreviations: "Acme Trading" will not match "Acme Trading (Pty) Ltd".

By ID

client_id matches BaseCloud's own ID. o_client_id matches the external ID you store on the client, which is usually the right key when syncing with another system.

By custom field

client_field_id_<id> matches any client custom field by that field's ID, taken from Clients → open a client → Custom Fields.

client_field_id_42: {{task_46171_membership_number}}

Unresolved variables are rejected, not matched

A custom field criterion whose value still contains { or } is skipped. If an upstream variable did not resolve, the leftover braces stop it silently rather than matching nothing — check the value in the task's OUTPUT panel if a custom field match never hits.

By registration date

date_registered matches the client's registration timestamp, YYYY-MM-DD HH:MM:SS. Give the row a ± minutes window to match approximately:

date_registered: 2026-03-14 10:22:00     window: 10

A badly formatted timestamp, or a window that is not a positive number, is reported in run_text and the criterion is skipped.

The Custom Fields section of a client panel, with a count of 15, the pencil, Hide Empty, a search box and Add Field. The first fields are Property Type: Single-family home, Service Area: North Shore, Lead Source: Website Form, Maintenance Plan: None, Water Heater Age (yrs): 11 and Next Service Due: 2026-11-03

Custom fields are defined per tenant on the client record itself — the pencil edits the set, Add Field creates one. The name you give a field here is the name you reference from a task.

Match to Clients: every client that matches

Set Action to Match to Clients and the task stops being an identity lookup. It finds every client that matches all the items you fill in, and hands back their IDs as one comma-separated list, ready for a Loop task.

It differs from Match to Client in Match to Client Match to Clients
How items combine Tried in order, first hit wins Every filled-in item must match. Blank items are ignored
What comes back One client and its details A list of client IDs, newest first, up to 10,000
The event Linked to the client it found Not linked to anyone

How each item is matched

Between each item's field and its value there is a small button reading Matches, so the row reads as a sentence. Click it and it steps to the next way of matching, and round again at the end:

The button reads The item finds
Matches Records where the field is exactly your value. For a status or a dropdown, any of the options you pick
Does not match Records where the field is anything else, blank included. For a status or a dropdown, none of the options you pick
Contains Records where your value appears anywhere in the field. Capital letters make no difference
Does not contain Records where your value appears nowhere in the field, blank included
Is empty Records where the field is blank. No value is needed
Has any value Records where the field is filled in. No value is needed
Client/Company Name   [Contains]   Uniqon

finds Uniqon, Uniqon Holdings, The Uniqon Group (Pty) Ltd and uniqon trading.

Each item offers only the choices that mean something on it:

Item Choices
Client/Company Name, O_Client ID, Contact Email, Text and Multi-line Text custom fields All six
Contact Cellphone and Landline Number, dropdown and number custom fields Matches, Does not match, Is empty, Has any value
Client Status, Client ID, Contact Email Domain Matches, Does not match
Date Registered None. It is matched by its ± minutes

The choice is made per item, so one task can mix them, for example a company name that contains Uniqon and a Client Status that does not match Lost.

Several statuses or options at once. A Client Status item, and a dropdown custom field, lets you tick several options. With Matches a client holding any of them is found; with Does not match, only clients holding none of them. In Variable mode, give the IDs separated by commas.

Contact items look at every contact of the client. "Contact Email does not match info@acme.com" finds the clients where no contact has that address, so a client with no contacts at all is included. "Contact Email is empty" finds the clients where no contact has an email address.

The same button, with the same choices and wording, is on the Contact task's matching items and on the Table task's filters.

Short values match a lot

Contains with one or two letters matches most of your clients. The list stops at 10,000 and run_text says so when it does.

How it is stored

Each item is one row: its field, its value, and how it is matched. Built through an AI connection, an item is { "field", "value", "how" }:

The button reads Stored as how
Matches left out
Does not match not_equals
Contains contains
Does not contain not_contains
Is empty empty
Has any value not_empty
[
  { "field": "company_name", "value": "Uniqon", "how": "contains" },
  { "field": "client_status", "value": "4,7", "how": "not_equals" },
  { "field": "contact_email", "value": "", "how": "empty" }
]

how only takes effect when Action is Match to Clients. A how the field cannot take is refused when the task is saved through an AI connection. Several statuses or dropdown options go in value as IDs separated by commas.

What Match to Clients returns

Field Type Example Notes
client_matched boolean true Whether at least one client matched.
client_ids string 777874,612,598 Comma-separated, newest first. Empty when nobody matched.
client_count number 3 How many IDs are in the list.
matched_by string company name (contains) The items that were used, each with its choice when it is not Matches.
run_text string Found 3 clients matching all 1 item.

| clients | array | [{"client_id":777874,…}] | Only with Return client data ticked: the first 100 matched clients. |

Feed client_ids to a Loop task. Inside the loop, a Match to Client on client_id gives you each client's details. Or tick Return client data and loop over clients instead, with nothing to look up inside the loop.

Return client data

Off by default. Tick Return client data to also get the details of the matched clients in clients, ready for a Loop. It is the same box as the Table task's Return row data and the Contact task's Return contact data.

clients holds the first 100 clients only, newest first. client_ids still lists every match, so you can tell when there were more than 100.

Each client in the list carries:

Field Example Notes
client_id 777874
client_name Uniqon Holdings The company name.
client_link https://… Opens the client in the CRM.
o_client_id CRM-8891 Your external ID, empty if unset.
client_status_id 3
client_status_label Active customer
origin Website
notes Prefers email. The client's main notes.
date_registered 2026-09-28 10:00:00
responsible_manager 57 The responsible user's ID.
responsible_manager_name Thabo Nkosi Empty when the client has no responsible manager.
responsible_manager_email thabo@example.com
contact_ids 881,882 Comma-separated IDs of the client's contacts.
custom_field_<id>_label Region One pair for each custom field the client has a value in.
custom_field_<id>_value North For a dropdown, the option ID(s).
custom_field_<id>_value_full Plumbing, Heating Dropdown fields only: the names of the options picked.
custom_field_<id>_value_file_name contract.pdf Attachment fields only, with _value_url, _value_size and _value_upload_date.
custom_field_<id>_value_file_names a.jpg, b.jpg Multiple-attachment fields only, with _value_urls, _value_sizes and _value_upload_dates, each comma-separated.

The custom field names are the ones Match to Client uses for one client, so a workflow reads them the same way in either.

Inputs

Builder fields

The Field column is the label as it appears in the task builder; Key is the name the value is stored under and referenced by.

Field Key Type Default Notes
Action Action select match Options: Match to Client · Match to Clients
Matching Criteria _rows client-match-rows –
Return client data return_client_data checkbox 0 Only shown when Action is match_all

Every row is a match criterion. Add one row per criterion. A new task starts with contact_email and contact_cell_number; the rest you add yourself.

On Match to Client, criteria are evaluated in the order they appear on the task, and evaluation stops at the first one that matches a client. Order is therefore significant: put your most reliable identifier first. A criterion whose value resolves to empty is skipped.

On Match to Clients, order does not matter: a client must fit every row that is filled in. A row left blank is ignored, but a row whose variable resolved to nothing stops the task, because ignoring it would return more clients than asked for.

The table below gives the whole-value meaning of each key. On Match to Clients each row also carries how it is matched: see How each item is matched.

Key Type Required What it matches
contact_email string no A linked contact's email address. Exact match after sanitising; skipped if the value is not a valid email.
contact_email_domain string no The domain part of a linked contact's email — pass a full address, the task takes everything after @. The only non-exact criterion.
contact_cell_number string no A linked contact's cell number. Normalised to E.164 first; if the value is not a valid number the task says so in run_text and skips the criterion.
contact_landline_number string no A linked contact's landline, normalised the same way.
company_name string no The client's company name. Exact.
client_id number no BaseCloud's own client ID.
o_client_id string no Your external / original client ID, if you store one.
client_status number no The client's status, by its ID (not its name). On Match to Clients, several IDs separated by commas match a client in any of them.
client_field_id_<id> string no Any client custom field, by that field's ID — for example client_field_id_42. On a hit, criteria reports Custom Field: 42.
date_registered timestamp no The client's registration timestamp, format YYYY-MM-DD HH:MM:SS. Optionally give a ± minutes window in the row's setting; a non-numeric or non-positive window, or a badly formatted timestamp, is reported in run_text and the criterion is skipped.

Custom field criteria are how you match on your own identifiers

client_field_id_<id> is the general escape hatch — any custom field on the client can be a match key. The <id> is the custom field's ID from Clients → open a client → Custom Fields.

Settings, Client Statuses: eight statuses from New Lead to Lost, each with a handle to drag it by, its ID, a preview of its coloured badge, a colour swatch and an on/off switch, and Add Status

Statuses are defined per tenant in Settings → Client Statuses, so the list differs between accounts — a status that exists in one tenant may not exist in another. Each carries a numeric ID, and that ID is what a task reads and writes; the label is only what people see. Deactivating a status hides it from dropdowns without removing it from records that already hold it.

Outputs

Field names below are exactly as the task emits them. Reference them as {{task_<ID>_<field>}} — for example {{task_46171_match_client_status_label}}.

Always emitted

Field Type Example Notes
run boolean true false when nothing matched.
run_text string Successfully matched client. On failure, No client matched. Also carries per-criterion skip messages and the over-cap warning.
status number 1 1 when a client was matched, 0 when not.
criteria string contact_email Which criterion produced the match. For a custom field, Custom Field: 42. Empty when nothing matched.
client_matched boolean true Whether a client was found.
metadata object see below Match counts and the capped match list.

Emitted only when a client matched

Field Type Example Notes
match_client_id number 10482 The matched client's BaseCloud ID.
match_client_name string Acme Trading Company name.
match_client_o_client_id string CRM-8891 Your external ID, empty if unset.
match_client_origin string Website The client's origin — the first_contact field. Returned, not searchable.
match_client_notes string Prefers email. The client's main notes. Empty if none.
match_client_status_id number 3 Status ID.
match_client_status_label string Active customer Human-readable status. Empty if the status row cannot be resolved — the lookup is non-fatal.
match_client_responsible_manager number 57 The responsible user's ID.
match_client_responsible_manager_name string Thabo Nkosi Empty if the user cannot be resolved. Non-fatal by design, so treat empty as "unknown", not "unassigned".
match_client_responsible_manager_email string thabo@example.com Same, empty if unresolved.
contact_ids string 881,882,883 Comma-separated IDs of every contact linked to the client. A string, not an array — split it before looping.

The matched contact, when a client matched

The task also returns one contact belonging to the matched client, under a nested match object. Flattening joins the names with _, so you reference them as match_contact_*:

Field Type Example Notes
match_contact_id number 881 The contact's ID.
match_contact_name string Thandi First name.
match_contact_surname string Mokoena Surname.
match_contact_email string thandi@acme.co.za
match_contact_cell_number string +27821234567
match_contact_landline_number string +27123456789 Empty string when the contact has none.
match_client_id (nested twin) number 10482 match.client_id, the same value as the top-level field.

Which contact you get depends on how the client was found. When an email or phone criterion wins, it is the contact that carried the matching value — the one the workflow was looking for. When a client-level criterion wins (client_id, o_client_id, company_name, client_field_id_<id> or date_registered) there is no such contact, so the task returns the client's first linked contact.

These fields were absent on client-level criteria before 2026-09-23

Until then only the contact criteria emitted them, so a task that changed which criterion won — including one that changed by itself, because an upstream value started resolving — silently dropped every match_contact_* reference downstream. Blank WhatsApp template parameters and empty To addresses were the usual symptom. All criteria now return a contact.

Custom fields, when a client matched

Every client custom field is emitted as a group of fields keyed by the field's ID:

Field Type Notes
custom_field_<id>_id number The stored value's row ID.
custom_field_<id>_label string The field's label.
custom_field_<id>_access_level number The field's access level.
custom_field_<id>_value string The value.

Two field types add more:

  • Attachment fields also emit custom_field_<id>_value_file_name, _value_url and _value_size.
  • Multi-client fields also emit custom_field_<id>_client_ids (comma-separated IDs) and custom_field_<id>_value_text (the matching company names, comma-separated). If that name lookup fails, _value_text is left empty and the task still succeeds.

metadata

{
  "total_matched": 3,
  "matches": [{ "client_id": 10482 }],
  "warning": "Too many matches found. Please refine your search criteria."
}
Key Meaning
total_matched How many clients matched the criterion that hit. Not capped — a true count.
matches The matching rows, capped at 50. A 400-match criterion reports total_matched: 400 and 50 entries here.
warning Present only when total_matched exceeds 50. run_text also gains a warning in that case.

total_matched above 1 means your criterion is not unique

The task still returns a single client. If total_matched is large, the criterion identified a group rather than a record — company name and email domain do this often.

Emitted only when the date filter ran

Field Type Notes
date_filter_applied boolean Present when date_registered was used with a minutes window.
date_filter_minutes number The ± window in minutes that was applied.

Real-World Examples

Connect a form submission to its client

Form Submission (trigger)
  └─ Match to Client
        contact_email:        {{task_55001_email}}
        contact_cell_number:  {{task_55001_phone}}
  └─ If Statement   run is true
      ├─ true  ─ Email        to {{task_15001_match_client_responsible_manager_email}}
      └─ false ─ New Client   create the record, then continue

Email first, phone as the fallback. The If Statement is what handles "not found", because the match task cannot create.

Route an inbound call to the account manager

Call Connect Trigger
  └─ Match to Client
        contact_cell_number: {{task_50001_caller_number}}
  └─ If Statement   run is true
      └─ Workflow Note
            log against client {{task_15001_match_client_id}}
            assigned to {{task_15001_match_client_responsible_manager}}

Sync from an external system by its own ID

Webhook In (trigger)
  └─ Match to Client
        o_client_id: {{task_29001_customer_id}}
  └─ Edit Client
        client: {{task_15001_match_client_id}}

o_client_id is the right key here: it identifies exactly one client, where an email might match several contacts at the same company.

Branch on the client's status

Webhook In (trigger)
  └─ Match to Client
        contact_email: {{task_46001_email}}
  └─ If Statement   {{task_15001_match_client_status_label}} equals "Active customer"
      ├─ true  ─ SMS    send the renewal offer
      └─ false ─ Email  send the win-back message

The match task returns the status of the client it found, and the branching happens in an If Statement afterwards. To find clients by status instead, add a Client Status item.

Look up by your own membership number

Webhook In (trigger)
  └─ Match to Client
        client_field_id_42: {{task_46001_membership_number}}

Where 42 is the custom field's ID from Clients → open a client → Custom Fields.

Handling several matches

On Match to Client, a criterion can match many clients. The task still returns one, and tells you how many it saw.

Signal Meaning
metadata.total_matched = 1 The criterion identified exactly one client. This is what you want.
metadata.total_matched > 1 The criterion identifies a group. You get one of them, and which one is not something you control.
metadata.total_matched > 50 metadata.matches is capped at 50 entries and metadata.warning is set. total_matched is still the true count.

To make a match unique, use a more specific criterion — email or an ID rather than a domain or a company name. Adding more criteria does not narrow a match: they are alternatives, and an earlier one that hits stops the rest from ever running.

If what you actually need is every client matching a condition, set Action to Match to Clients.

Best Practices

  • Put your most reliable criterion first. Evaluation stops at the first hit, so order is the main thing you control.
  • Prefer identifiers over names. Email, client_id and o_client_id identify one record. Company name and email domain frequently identify several.
  • Normalise before matching. Run a Phone Formatter on numbers and a Formatter on text so the value you match on is consistent.
  • Check run before using the output. On no match, every match_client_* field is absent, not empty — a downstream task referencing them gets nothing.
  • Treat an empty match_client_status_label or ..._manager_name as "unknown". Those lookups are non-fatal and leave the field empty rather than failing the task.
  • Split contact_ids before looping. It is a comma-separated string, not an array.
  • Watch metadata.total_matched. A value above 1 is the early warning that your criterion is not unique.

Troubleshooting

Symptom Cause and fix
No client matched. No criterion hit. Check each value actually resolved — an unresolved {{variable}} becomes empty and is skipped.
A custom field criterion never matches The value still contains { or }, so it was rejected. Fix the upstream variable.
Cell number "…" is not a valid phone number format. in run_text The value could not be parsed as a phone number, so that criterion was skipped. Normalise it with Phone Formatter first.
Invalid timestamp format "…" in run_text date_registered needs YYYY-MM-DD HH:MM:SS.
Invalid time range "…" in run_text The ± window must be a positive number of minutes.
The wrong client comes back The criterion matched several clients — check metadata.total_matched. Use a more specific criterion; adding more criteria will not help, because the first hit wins.
Warning: N clients matched this criteria More than 50 matched. metadata.matches is capped; total_matched is accurate. Narrow the criterion.
Status or manager name is empty on a successful match Those resolutions are non-fatal. The IDs (match_client_status_id, match_client_responsible_manager) are still populated.
Expected a client to be created This task never creates. Add a New Client task on the false branch of an If Statement.

Frequently Asked Questions

Does this task create a client if none matches? No. It has no create path. Follow it with New Client on the false branch of an If Statement.

Can I match on status? Yes. Add a Client Status item. On Match to Clients you can tick several statuses, or set it to Does not match to leave statuses out.

Can I match on Origin? No. Origin comes back in the output for the client that was found, but there is no item to search on it.

Can I require two criteria to match at once? Yes, with Match to Clients: every item you fill in must fit. On Match to Client the criteria are alternatives and the first hit wins.

Can I get all clients that match, rather than one? Yes. Set Action to Match to Clients. See Match to Clients.

Can I find clients whose name contains a word? Yes, with Match to Clients: add a Client/Company Name item and click the Matches button before its value until it reads Contains. See How each item is matched.

Can I find clients that are not in a status, or whose field is blank? Yes, with Match to Clients: click the button before the value to Does not match or Is empty. See How each item is matched.

Does it match contacts or clients? It matches clients, sometimes by looking through their linked contacts. The output describes the client; contact_ids lists that client's contacts.

Is matching case-sensitive? Email is sanitised before matching. Company name is an exact match — treat it as unreliable for anything but data you control.

What happens to criteria after the first hit? They never run. That is why ordering matters and why a later, more specific criterion cannot correct an earlier, looser one.