Skip to main content

Connect a CRM

A CRM connected as a data source gives the assistant who the caller is before the conversation even starts. When someone calls, the assistant looks them up by phone or email and injects their record — name, lifecycle stage, last note, deal value — straight into the prompt. From the customer's perspective, the assistant just knows them. From yours, it's one toggle on the assistant.

This is different from a CRM tool (which lets the assistant create deals and log calls during the conversation). The two often work together — the data source pattern reads the contact in; the tool pattern writes activity out. Most production sales and support assistants use both.

How it works

The lookup happens at conversation start (or on the first prompt resolution). There's no indexing — every conversation makes one CRM API call. If the CRM record changes at 10:02, the next conversation at 10:03 sees the change.

Supported CRMs

  • HubSpot — OAuth connection, full contact and deal access.
  • Zoho — OAuth, contacts and leads.
  • GoHighLevel (LeadConnector) — API key, contacts and pipelines.
  • Freshdesk — API key, support contact records.
  • ModMed — healthcare-specific, requires a signed BAA.

Other providers (Postgres, custom HTTP) can be wired similarly via the tool-as-data-source pattern.

Four business use cases

B2B SaaS — HubSpot personalisation. An analytics startup connects HubSpot. The sales assistant greets returning leads by name, references their lifecycle stage, and skips qualification questions for already-qualified leads. Outcome: SDRs save 4 minutes per call on average.

Real estate — GoHighLevel context. A brokerage uses GHL as their lead pipeline. The voice receptionist looks up the caller by number, sees their current pipeline stage ("toured property A", "viewed two listings"), and asks the right next question instead of starting from scratch.

Healthcare — ModMed patient records. A dermatology practice connects ModMed. The voice assistant identifies the caller from the practice phone tree, retrieves their next appointment, current medications, and last visit notes, and answers questions in context — all under their BAA.

E-commerce — Zoho customer history. A meal-kit company connects Zoho. The chat assistant greets returning subscribers, references their subscription tier, and routes refund requests against the right rep based on the customer's account owner.

Setting up the connection

  1. Connect the CRM under Build → Tools & Integrations. Pick your provider, follow the OAuth (HubSpot, Zoho) or paste your API key (GHL, ModMed). Done once per workspace.
  2. Open the assistant under Build → Assistants → [your assistant] → Data sources.
  3. Toggle the CRM on. Behind the scenes this links the CRM connection to the assistant for lookup at conversation start.
  4. Add {{<provider>.<key>}} placeholders to your system prompt for the fields you want injected (see below).

Available placeholders

The exact keys depend on the CRM provider, but the shape is consistent — name, email, phone, company, plus provider-specific custom fields. In your system prompt:

Caller context:
- Name: {{hubspot.first_name}} {{hubspot.last_name}}
- Lifecycle stage: {{hubspot.lifecycle_stage}}
- Last note: {{hubspot.last_note}}
- Account owner: {{hubspot.owner_name}}

If the caller has no CRM record, those tokens resolve to empty strings and the prompt reads naturally.

For GoHighLevel use the leadconnector prefix:

Caller context:
- Name: {{leadconnector.first_name}}
- Pipeline stage: {{leadconnector.pipeline_stage}}

How identification works

The assistant tries, in order:

  1. Explicit contact ID passed in session metadata (from your widget config or API call).
  2. Phone number of the inbound caller, matched against the CRM's phone field.
  3. Email captured during the conversation, matched against the CRM's email field.
  4. No match — the conversation continues with empty CRM placeholders.

For chat widgets you typically pass the contact ID in the widget config so there's no need for "what's your email?" prompting. For phone widgets identification by caller number is automatic.

Refresh model

There's no indexing. Every conversation makes one CRM API call. Provider rate limits apply (HubSpot is generous; GHL is tighter). Looked-up values are cached within a single conversation, so multi-turn chats don't re-fetch.

If your CRM provider rate-limits you, surface that to support — there are knobs to tune the lookup behaviour per assistant.

Data source vs. tool

You can also wire the same CRM as a regular tool that the assistant decides to call. The difference:

  • Data source (this page) — Fired automatically, every conversation. Passive context. Use it for "know who is calling."
  • Tool — The assistant decides when to call it, mid-conversation. Use it for actions (create deal, log call, update contact).

Most production sales assistants have both: data-source wiring for context in, tool wiring for activity out.

Common problems

"The assistant says it doesn't know who I am, but I'm in the CRM."

Inbound caller phone has to match the CRM contact's phone field exactly (E.164 format). For chat widgets, pass contact_id in the widget config so identification doesn't depend on the caller volunteering an email.

"The prompt shows literal {{hubspot.first_name}} text in the reply."

The placeholder is malformed — usually a single brace or a typo. Use double curly braces with no spaces. Test in the Playground.

"OAuth keeps disconnecting."

HubSpot and Zoho refresh tokens silently; GHL's tokens are shorter-lived. The data source detail page surfaces a banner when re-auth is needed. Just click it to re-connect.

Where to next