> ## Documentation Index
> Fetch the complete documentation index at: https://docs.salesfinity.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Call new leads from your CRM

> When an inbound lead is created or assigned to a rep in HubSpot or Salesforce, send it to that rep's list, so they call it first.

Many inbound leads reach your CRM before anyone sees them: from chat, events, routing tools, or
forms you can't change. Trigger on the CRM instead. When a lead is created or assigned to a rep,
send it to that rep's own list with a tag, and it becomes their next call.

## When to use it

* Inbound leads land in HubSpot or Salesforce from several places, and you want one trigger for
  all of them.
* Leads are assigned to reps in the CRM, by routing rules or by hand, and the owner should make
  the call.

Only one source and it already has a recipe, such as a [website form](https://docs.salesfinity.ai/workflows/website-forms.md)?
Start from the source. It's faster and carries more detail.

## What you need

* **One list per rep** who takes inbound leads, and each list's `_id`. The rep owns their list.
  See [Before you start](https://docs.salesfinity.ai/workflows/overview.md#before-you-start) and the API key there.
* **A map from CRM owner to list ID**, such as *Dana Ortiz → 6650c1f2a4b8e93d2c1f0a11*.
* **A way for the CRM to call out**: Zapier, Make, a HubSpot workflow, or a Salesforce flow.
  Which one depends on your CRM plan, below.

## Set it up

**1. Decide what counts as a new inbound lead**

Trigger on leads people raised their hand for, not on every new record. Imports, list uploads
and enrichment create records too. Filter on a field you trust, such as **Lead Source** or
**Original Source**, a lead status of *New*, or a lifecycle stage.

**2. Pick the moment**

* **When the lead is created**, if one inbound rep takes every lead.
* **When an owner is set**, if leads are routed or assigned first. The owner then decides which
  list the lead goes to.

**3. Build the trigger in your CRM**

See [HubSpot](#hubspot) or [Salesforce](#salesforce) below.

**4. Send the lead to the owner's list**

Turn the owner into a list ID, then send the request, with the tag `"New lead"` and the lead
source in `notes`.

## HubSpot

**Zapier or Make**

1. Trigger: in Zapier, **HubSpot** → **New Contact**, or **New Contact Property Change** on
   **Contact owner** if leads are routed first. In Make, **HubSpot CRM** → **Watch Contacts**.
2. **Filter by Zapier**: continue only when the lead source and status say it's a new inbound
   lead.
3. **Formatter** → **Utilities** → **Lookup Table**: the contact owner in, the rep's list ID out.
4. **Formatter** → **Numbers** → **Format Phone Number**, to E.164.
5. **Webhooks by Zapier** → **Custom Request**, as in [What to send](#what-to-send), with the
   list ID from step 3 in the URL.

**HubSpot workflow**

With **Data Hub Professional or Enterprise**, a contact-based workflow can call Salesfinity
itself with a **Custom code** action. (The **Send a webhook** action needs the same plan, and
builds only flat key and value pairs, so it can't send the `phone_numbers` list.)

1. **Enrollment trigger**: **Object created**, or **Property value changed** on **Contact
   owner** if leads are routed first, with your inbound filter.
2. Add a **Custom code** action. With **Add secret**, store your API key as
   `SALESFINITY_API_KEY`.
3. Under **Properties to include in code**, add `firstname`, `lastname`, `email`, `company`,
   `jobtitle`, `mobilephone`, `phone` and `hubspot_owner_id`, with the same names.
4. Paste the code below, with your owners and lists in `LISTS`.

```javascript theme={"system"}
const axios = require('axios');

// HubSpot owner ID → that rep's Salesfinity list _id
const LISTS = {
  '12345678': '6650c1f2a4b8e93d2c1f0a11',
};

exports.main = async (event, callback) => {
  const c = event.inputFields;
  const list_id = LISTS[c.hubspot_owner_id];
  if (!list_id) return callback({ outputFields: { sent: false } });

  // Numbers must already be in E.164, such as +17205550148
  const phone_numbers = [];
  if (c.mobilephone) phone_numbers.push({ type: 'mobile', number: c.mobilephone });
  if (c.phone) phone_numbers.push({ type: 'office', number: c.phone });

  await axios.post(
    `https://client-api.salesfinity.co/v1/contact-lists/${list_id}`,
    {
      first_name: c.firstname,
      last_name: c.lastname,
      email: c.email,
      company: c.company,
      title: c.jobtitle,
      phone_numbers,
      notes: 'New inbound lead in HubSpot',
      tag: 'New lead',
    },
    { headers: { 'x-api-key': process.env.SALESFINITY_API_KEY } },
  );

  callback({ outputFields: { sent: true } });
};
```

Calls made from Salesfinity are logged back on the HubSpot contact, found by email, phone number
or LinkedIn URL. See
[Calls on contacts that did not come from HubSpot](https://docs.salesfinity.ai/integrations/hubspot.md#calls-on-contacts-that-did-not-come-from-hubspot).

## Salesforce

**Zapier or Make**

1. Trigger: in Zapier, **Salesforce** → **New Lead**, or **Updated Field on Record** on the
   lead owner if leads are routed first. In Make, **Salesforce** → **Watch records**.
   Salesforce is a premium app in Zapier.
2. **Filter by Zapier**: continue only for the lead sources and statuses that mean a new
   inbound lead.
3. **Formatter** → **Utilities** → **Lookup Table**: the lead owner in, the rep's list ID out.
4. **Formatter** → **Numbers** → **Format Phone Number**, to E.164.
5. **Webhooks by Zapier** → **Custom Request**, as in [What to send](#what-to-send).

**Salesforce flow**

On Enterprise, Performance, Unlimited and Developer editions, a record-triggered flow can call
Salesfinity with an **HTTP Callout** action. (Outbound messages can't: they only send SOAP.)

1. Create an **External Credential** with the **Custom** authentication protocol. Store the
   API key on its principal, and add a custom header `x-api-key` that reads it. Give your
   flow's running user access to the principal with a permission set.
2. Create a **Named Credential** for `https://client-api.salesfinity.co` that uses it, with
   **Generate Authorization Header** cleared. The key stays there, not in the flow.
3. Store each rep's list ID on their user record, for example in a custom field *Salesfinity
   list ID*.
4. Build a **record-triggered flow** on **Lead**, when a record is created (or updated, when the
   owner changes), with your inbound filter in the entry conditions.
5. On the **Run Asynchronously** path, add an action, choose **Create HTTP Callout**, and set
   it up as a `POST` to `/v1/contact-lists/{list ID}` with the JSON body from
   [What to send](#what-to-send). Flows can't make callouts on the immediate path.

Calls are logged back as a completed Task on the Lead or Contact, found by email, phone number or
LinkedIn URL. See
[Calls on records that did not come from Salesforce](https://docs.salesfinity.ai/integrations/salesforce.md#calls-on-records-that-did-not-come-from-salesforce).

## What to send

| Field | From the CRM |
| - | - |
| `first_name`, `last_name`, `email`, `company`, `title` | The lead's own fields. Always send the email. |
| `phone_numbers` | Mobile and phone, each in E.164: `[{ "type": "mobile", "number": "+17205550148" }, { "type": "office", "number": "+17205550100" }]` |
| `linkedin` | The LinkedIn URL, if you store it. |
| `notes` | *New lead from Website chat, assigned to you at 10:42.* At most 2,000 characters. |
| `tag` | `"New lead"` |

```bash cURL theme={"system"}
curl https://client-api.salesfinity.co/v1/contact-lists/OWNERS_LIST_ID \
  --request POST \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "first_name": "Marcus",
    "last_name": "Bell",
    "email": "marcus.bell@northpine.com",
    "company": "Northpine Health",
    "title": "Director of Sales",
    "phone_numbers": [{ "type": "mobile", "number": "+13125550199" }],
    "notes": "New lead from Website chat. Lead source: Chat",
    "tag": "New lead"
  }'
```

```text Zapier theme={"system"}
1. Trigger: HubSpot → New Contact, or Salesforce → New Lead.
2. Filter by Zapier: only new inbound leads.
3. Formatter → Utilities → Lookup Table: owner → list ID.
4. Formatter → Numbers → Format Phone Number, to E.164.
5. Action: Webhooks by Zapier → Custom Request
   Method:  POST
   URL:     https://client-api.salesfinity.co/v1/contact-lists/{list ID from step 3}
   Headers: x-api-key     YOUR_API_KEY
            Content-Type  application/json
   Data:    the JSON from the cURL tab, with the lead's fields
            mapped into it, and "tag": "New lead".
```

```text Make theme={"system"}
1. Trigger: HubSpot CRM → Watch Contacts, or Salesforce →
   Watch records (Lead).
2. Filter: only new inbound leads.
3. Map the owner to the rep's list ID, for example with a Switch.
4. Action: HTTP → Make a request
   URL:               https://client-api.salesfinity.co/v1/contact-lists/{list ID}
   Method:            POST
   Headers:           x-api-key = YOUR_API_KEY
   Body content type: application/JSON
   Body input method: JSON string
   Body:              the JSON from the cURL tab, with the lead's
                      fields mapped into it, and your tag.
```

## Test it

1. Ask a rep to start dialing their list, or do it yourself on your own list.
2. Create a test lead in the CRM with your own name, email and mobile number, the inbound lead
   source, and that rep as the owner.
3. Check that the rep gets the notification, that the lead is **Next up**, and that it rings once
   the current call is logged.
4. Log the call, then open the lead in the CRM. The call should be on it.

## Good to know

* **Reassigning sends it again.** If you trigger on the owner, a lead moved to a new rep goes to
  the new rep's list too. The old rep's list keeps its copy.
* **A rep who left.** Leads sent to a list whose owner is no longer on your team are added, but
  nobody is notified. Update your owner map when the team changes.
* **Without the API.** Your CRM can create a call task instead, and reps import **All due tasks**
  from [HubSpot](https://docs.salesfinity.ai/integrations/hubspot.md#what-salesfinity-imports) or **All call tasks** from
  [Salesforce](https://docs.salesfinity.ai/integrations/salesforce.md#what-salesfinity-imports). That works, but the lead waits
  until the next import.
* **Filter first.** A tag means "call next". If an import or a sync can match your trigger, a
  rep's list fills with tagged leads that nobody asked to talk to.

For errors and what the rep sees, see
[Troubleshooting](https://docs.salesfinity.ai/dialer/speed-to-lead.md#troubleshooting) in the speed-to-lead guide.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.