> ## 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 people who fill in your website forms

> Send demo requests and contact-sales forms from HubSpot forms, Typeform, Webflow or your own site to Salesfinity, so a rep calls within minutes.

Someone asks for a demo on your website. Send them to Salesfinity with a tag, and the rep dialing
your inbound list calls them next, with what they asked for in front of them.

## When to use it

* Demo requests, contact-sales forms and pricing questions: forms where people ask to talk.
* The form lives in HubSpot, Typeform, Webflow or a similar builder, or posts to your own backend.

Leave out newsletter sign-ups, content downloads and job applications. They didn't ask for a call.

## What you need

* A list the rep dials, its `_id`, and an API key. See
  [Before you start](https://docs.salesfinity.ai/workflows/overview.md#before-you-start).
* A **phone number field** on the form, and wording that says you'll call, such as *"We'll call
  you to set up your demo."*
* Zapier or Make, or a developer who can add one request to your form's backend.

## Set it up

**1. Ask for a phone number, and say you'll call**

Add a phone field and make it required on the forms that should lead to a call. Ask for the
country code, or use a field that picks the country, so you can send the number in
international format.

**2. Catch each new submission**

| Form tool | In Zapier | In Make |
| - | - | - |
| HubSpot forms | **HubSpot** → **New Form Submission** | **HubSpot CRM** → **Watch Submissions for a Form** |
| Typeform | **Typeform** → **New Entry** | **Typeform** → **Watch Responses** |
| Webflow | **Webflow** → **New Form Submission** | **Webflow** → **Watch Events**, trigger type **Form Submission** |
| Your own backend | Not needed | Not needed |

Pick the one form that should lead to a call. One Zap or scenario per form keeps the tag and
notes right.

> [!NOTE]
>
> Typeform's and Webflow's own webhooks can't add the `x-api-key` header, and they send their
> own JSON layout. Put Zapier, Make or your own endpoint in between.

**3. Format the phone number**

In Zapier, add **Formatter** → **Numbers** → **Format Phone Number**, with the E.164 format
(`+17205550148`). In your own code, use a phone library such as `libphonenumber`.

**4. Send the person to Salesfinity**

Map the form fields into the request below. Use the tag `"Demo request"`, or one per form, and
put the form, the page and the message in `notes`.

## What to send

| Field | From the form |
| - | - |
| `first_name`, `last_name` | Name. A single name field goes in `first_name`. |
| `email` | Email. Needed so the same person isn't added twice. |
| `company`, `title` | Company and job title, if the form asks. |
| `phone_numbers` | `[{ "type": "mobile", "number": "+17205550148" }]` |
| `notes` | *Demo request on /pricing: "We have 12 SDRs and want to see parallel dialing."* At most 2,000 characters. |
| `tag` | `"Demo request"` |

```bash cURL theme={"system"}
curl https://client-api.salesfinity.co/v1/contact-lists/YOUR_LIST_ID \
  --request POST \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "first_name": "Priya",
    "last_name": "Raman",
    "email": "priya.raman@tidewater.io",
    "company": "Tidewater Software",
    "title": "Head of Sales Development",
    "phone_numbers": [{ "type": "mobile", "number": "+14155550123" }],
    "notes": "Demo request on /pricing: \"We have 12 SDRs and want to see parallel dialing.\"",
    "tag": "Demo request"
  }'
```

```javascript Node.js theme={"system"}
// On your server, after the submission is saved. Never in the browser:
// the API key works for your whole team.
const response = await fetch(
  `https://client-api.salesfinity.co/v1/contact-lists/${process.env.SALESFINITY_LIST_ID}`,
  {
    method: 'POST',
    headers: {
      'x-api-key': process.env.SALESFINITY_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      first_name: form.first_name,
      last_name: form.last_name,
      email: form.email,
      company: form.company,
      phone_numbers: [{ type: 'mobile', number: form.phone_e164 }],
      notes: `Demo request on ${form.page}: "${form.message}"`.slice(0, 2000),
      tag: 'Demo request',
    }),
  },
);

if (response.status !== 201) {
  console.error('Salesfinity', response.status, await response.text());
}
```

```python Python theme={"system"}
# On your server, after the submission is saved. Never in the browser:
# the API key works for your whole team.
import os
import requests

response = requests.post(
    f"https://client-api.salesfinity.co/v1/contact-lists/{os.environ['SALESFINITY_LIST_ID']}",
    headers={"x-api-key": os.environ["SALESFINITY_API_KEY"]},
    json={
        "first_name": form["first_name"],
        "last_name": form["last_name"],
        "email": form["email"],
        "company": form["company"],
        "phone_numbers": [{"type": "mobile", "number": form["phone_e164"]}],
        "notes": f'Demo request on {form["page"]}: "{form["message"]}"'[:2000],
        "tag": "Demo request",
    },
    timeout=60,
)

if response.status_code != 201:
    print("Salesfinity", response.status_code, response.text)
```

```text Zapier theme={"system"}
1. Trigger: your form tool's new-submission trigger (see the table
   above), for the one form that should lead to a call.
2. Formatter → Numbers → Format Phone Number, to E.164.
3. Action: Webhooks by Zapier → Custom Request
   Method:  POST
   URL:     https://client-api.salesfinity.co/v1/contact-lists/YOUR_LIST_ID
   Headers: x-api-key     YOUR_API_KEY
            Content-Type  application/json
   Data:    the JSON from the cURL tab, with the form's fields
            mapped into it, and "tag": "Demo request".
```

```text Make theme={"system"}
1. Trigger: your form tool's module for new submissions (see the
   table above).
2. Action: HTTP → Make a request
   URL:               https://client-api.salesfinity.co/v1/contact-lists/YOUR_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 form's
                      fields mapped into it, and your tag.
```

A successful request answers `201` with `{ "success": true }`.

## Test it

1. Start dialing the list, with your phone ready.
2. Fill in the form on your live site with your own name, email and mobile number.
3. Check that the notification shows, that **Next up** shows your name, and that your phone rings
   once the current call is logged. The notes should read the way the rep needs them.

## Good to know

* **Keep the API key on the server.** Call the API from your backend, Zapier or Make, never from
  JavaScript in the page. Anyone who can read the page could use the key.
* **Don't make the visitor wait.** Send the request after the submission is saved, in the
  background. If Salesfinity answers slowly or not at all, the form still works.
* **Retry the right errors.** Retry `429` and `5xx` after a pause. Don't retry `400` or `404`:
  the same request fails again. With a tag, a retry doesn't add the person twice. See
  [Retries](https://docs.salesfinity.ai/developers.md#retries).
* **Messages with quotes or line breaks.** In a Zapier **Custom Request**, they break the JSON and
  the API answers `400`. Clean the message first, as in
  [Clean up the reply text](https://docs.salesfinity.ai/workflows/outreach-replies.md#clean-up-the-reply-text). Code that builds
  the body with `JSON.stringify` or `json=` doesn't have this problem.
* **Filter out spam first.** A tag puts the person at the top of the list. Use your form tool's
  spam protection, and only send submissions that pass it.
* **Several reps on inbound?** Give each rep their own list and send each submission to one of
  them, for example by country or company size. In Zapier, a **Formatter** → **Utilities** →
  **Lookup Table** step can turn a field into a list ID.

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.