# Freshsales

[Freshsales](https://www.freshworks.com/crm/lp/sales-crm-software/) is a CRM tool that lets you discover the best leads, drive them to closure, and nurture them to boost contextual engagement.

RudderStack supports Freshsales as a destination where you can seamlessly send your event data.

## Connection compatibility

{{< destination-config >}}

## Get started

Once you have confirmed that the source platform supports sending events to Freshsales, follow these steps:

1. From your [RudderStack dashboard](https://app.rudderstack.com/), add a source. Then, from the list of destinations, select **Freshsales**.
2. Assign a name to the destination and click **Continue**.

## Connection settings

To successfully configure Freshsales as a destination, you will need to configure the following settings:

- **API Key**: Enter your Freshsales API key.

{{< info >}}
For more information on obtaining your Freshsales API key, refer to the [FAQ]({{< ref "#FAQ" >}}) section below.
{{< /info >}}

- **Domain**: Enter the full organization URL associated with your Freshsales account. For example, `testcompany.myfreshworks.com`.

{{< info >}}
For more information on your organization URL and how to change it, refer to this [Freshsales support guide](https://support.freshworks.com/en/support/solutions/articles/50000002731-what-is-and-how-can-i-change-my-organization-url-).
{{< /info >}}

- **Map your events with Freshsales Standard Events**: Use this setting to map the standard Freshsales events with the custom event names.

## Identify

You can use the [`identify`]({{< ref "event-spec/standard-events/identify.md" >}}) call to create or update your Freshsales contact.

RudderStack uses the Freshsales [Upsert a Contact](https://developers.freshworks.com/crm/api/#upsert_a_contact) API to pass the relevant user information via the following parameters:

| Attribute | Type | Description |
| :------| :-----| :-----|
| `unique_identifier` | String | RudderStack passes the user's `email`. |
| `contact` | Hashed Object |  RudderStack passes the other relevant user details required to create or update the user in Freshsales. |

{{< info >}}
If `email` already exists, the contact details are updated. Otherwise, RudderStack creates a new user in Freshsales.
{{< /info >}}

A sample `identify` call is shown below:

```javascript
rudderanalytics.identify("1hKOmRA4GRlm", {
  email: "alex@example.com",
  firstName: "Alex",
  lastName: "Keener",
  state: "Louisiana",
  country: "USA",
  postalCode: "90009",
});
```

### Supported mappings

The following table lists the mappings between the RudderStack and Freshsales properties:

| RudderStack property | Freshmarketer property | 
| :--------------| :---------| 
| `traits.email`<br/> `context.traits.email` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | `emails` | 
| `traits.firstname`<br/> `traits.first_name`<br/> `traits.firstName`<br />`context.traits.firstname`<br/> `context.traits.first_name`<br/> `context.traits.firstName` | `first_name` | 
| `traits.lastname`<br/> `traits.last_name`<br/> `traits.lastName`<br />`context.traits.lastname`<br/> `context.traits.last_name`<br/> `context.traits.lastName` | `last_name` | 
| `traits.subscriptionStatus`<br/> `context.traits.subscriptionStatus` | `subscription_status` | 
| `traits.job_title`<br/> `traits.jobTitle`<br/> `context.traits.job_title`<br/> `context.traits.jobTitle` | `job_title` | 
| `traits.phone`<br/> `context.traits.phone` | `work_number` | 
| `userId` | `external_id` | 
| `traits.mobileNumber`<br/> `context.traits.mobileNumber` | `mobile_number` | 
| `traits.address`<br/> `context.traits.address` | `address` | 
| `traits.address.city`<br/> `traits.city`<br/> `context.traits.address.city`<br/> `context.traits.city` | `city` | 
| `traits.address.state`<br/> `traits.state`<br/> `context.traits.address.state`<br/> `context.traits.state` | `state` | 
| `traits.address.postalCode`<br/> `traits.zip`<br/> `traits.zipcode`<br/> `context.traits.zip`<br/> `context.traits.zipcode`<br/> `context.traits.address.postalCode` | `zipcode` | 
| `traits.address.country`<br/> `traits.country`<br/> `context.traits.address.country`<br/> `context.traits.country` | `country` | 
| `traits.salesAccounts`<br/> `context.traits.salesAccounts` | `sales_accounts` | 
| `traits.territoryId`<br/> `context.traits.territoryId` | `territory_id` | 
| `traits.leadSourceId`<br/> `context.traits.leadSourceId` | `lead_source_id` | 
| `traits.ownerId`<br/> `context.traits.ownerId` | `owner_id` | 
| `traits.subscriptionTypes`<br/> `context.traits.subscriptionTypes` | `subscription_types` | 
| `traits.medium`<br/> `context.traits.medium` | `medium` | 
| `traits.campaignId`<br/> `traits.campaign_id`<br/> `context.traits.campaignId`<br/> `context.traits.campaign_id`<br/> `context.campaign.name` | `campaign_id` | 
| `traits.keyword`<br/> `context.traits.keyword`<br/> `context.campaign.term` | `keyword` | 
| `traits.timeZone`<br/> `context.traits.timeZone` | `time_zone` | 
| `traits.facebookUserName`<br/> `context.traits.facebookUserName` | `facebook` | 
| `traits.twitterUserName`<br/> `context.traits.twitterUserName` | `twitter` | 
| `traits.linkedinUserName`<br/> `context.traits.linkedinUserName` | `linkedin` | 
| `createdAt` | `created_at` | 
| `timestamp` | `updated_at` | 
| `traits.contactStatusId`<br/> `context.traits.contactStatusId` | `contact_status_id` | 
| `traits.salesAccountId`<br/> `context.traits.salesAccountId` | `sales_account_id` | 
| `traits.lifecycleStageId`<br/> `context.traits.lifecycleStageId` | `lifecycle_stage_id` | 

## Track
  
The [`track`]({{< ref "event-spec/standard-events/track.md" >}}) call can be used to track the user activities in Freshsales.

{{< info >}}
To make a `track` call successfully, you must map the event to be sent in the `track` call in the **Map your events with Freshsales Standard Events** dashboard setting.
{{< /info >}}

RudderStack supports the following `track` events:

### Lifecycle stage

Lifecycle stage events capture the decision journey of a customer. Refer to the [Freshsales documentation](https://support.freshsales.io/en/support/solutions/articles/50000003344-how-to-manage-lifecycle-stages-and-status-for-contacts-) to create lifecycle stages in Freshsales.

RudderStack lets you update the status of a contact in their lifecycle stage by using either the `lifecycleStageId` or `lifecycleStageName`. 

{{< info >}}
`lifecycleStageName` is a case-sensitive field and throws an error if not used in the intended manner.
{{< /info >}}

A sample `track` call for a lifecycle stage event is shown below:

```javascript
rudderanalytics.track("eventName", {
  email: "alex@example.com",
  lifecycleStageId: 71010794467,
  phone: "+1-202-555-0146",
  owner_id: "70000090119",
});
```

The following table lists the property mappings betweeen RudderStack and Freshsales for lifecycle stage events:

| RudderStack property          | Freshsales property|
| :-------------------- | :---------------------- |
| `email` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span>| `email` |
| `lifecycleStageName` <br/> <span style="color: #4D4DFF;font-size:12px;">Required, if lifecycleStageId is absent.</span>  | `lifecycleStageName`  |
| `lifecycleStageId` <br/> <span style="color: #4D4DFF;font-size:12px;">Required, if lifecycleStageName is absent.</span>   | `lifecycle_stage_id`  |

### Sales activities

[Sales activities](https://developers.freshworks.com/crm/api/#sales-activities) events can be used to track any activity related to a contact/deal/account. Refer to the [Freshsales documentation](https://support.freshsales.io/en/support/solutions/articles/230199-how-to-configure-different-sales-activities-in-freshsales-) to create sales activities  in Freshsales.

RudderStack lets you create the status of a contact by using either the `salesActivityTypeId` or `salesActivityName`.

A sample `track` call for a sales activity event is shown below:

```javascript
rudderanalytics.track("eventName", {
  salesActivityTypeId: "70000663932",
  title: "new contact",
  startDate: "2021-05-04T17:00:00+05:30",
  endDate: "2022-06-04T17:30:00+05:30",
  ownerId: "70054866612",
});
```

The following table lists the property mappings betweeen RudderStack and Freshsales for sales activity events:

| RudderStack property          | Freshsales property|
| :-------------------- | :---------------------- |
| `properties.title` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span>   | `title` |
| `properties.salesActivityName` <br/> <span style="color: #4D4DFF;font-size:12px;">Required, if properties.salesActivityTypeId is absent.</span>| `sales_activity_name` |
| `properties.salesActivityTypeId`   <br/> <span style="color: #4D4DFF;font-size:12px;">Required, if properties.salesActivityName is absent.</span> |`sales_activity_type_id` | 
| `properties.startDate` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span>  | `start_date`        |
| `properties.endDate`  <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span>  | `end_date`      | 
| `context.externalId.type` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span>   | `targetable_type` |
| `properties.ownerId` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span>  | `owner_id`| 
| `salesActivityOutcomeId`  | `sales_activity_outcome_id`  |
| `properties.notes`    | `notes`      |
| `context.externalId.id`     | `targetable_id`           |
| `properties.createrId`    | `creater_id`              |
| `originalTimestamp`  | `created_at`                |
| `timestamp`   | `updated_at`      |
|`properties.location` |`location`|
| `latitude`<br/>`context.address.latitude`<br/> `context.location.latitude`   | `latitude`      |
| `longitude`<br/>`context.address.longitude`<br/>`context.location.longitude`   | `longitude`      | 
|`properties.checkedinAt`|`checkedin_at`|

{{< info >}}
The `targetable_type` field denotes the entity for which the sales activity has been created and can take `Contact`/`SalesAccount`/`Deal` as its value. However, if its value is set to `contact`, then either the `targetable_id` or `email` is required.
{{< /info >}}

## Group

The [`group`]({{< ref "event-spec/standard-events/group.md" >}}) call lets you link an identified Freshsales contact with a company, organization, or an account. You can also record any custom group traits like the company name, number of employees, etc.

RudderStack uses the [Upsert an Account](https://developers.freshworks.com/crm/api/#upsert_an_account) API to create or update a [sales account](https://developers.freshworks.com/crm/api/#accounts) via the following parameters:

| Attribute | Type | Description |
| :------| :-----| :-----|
| `unique_identifier` | String | RudderStack passes the account `name`. |
| `sales_account` | Hashed Object |  RudderStack passes the other relevant details associated with the Freshsales account. |

{{< info >}}
Note that:
- If `name` already exists, the Freshsales account details are updated. Otherwise, a new account is created.
- RudderStack also checks if the contact's `email` is present in the `context.traits` object. If yes, RudderStack links the contact to the Freshsales account.
{{< /info >}}

A sample `group` call is shown below:

```javascript
rudderanalytics.group(
  "group01", {
    name: "Alex Keener",
    phone: "1234567890",
    numberOfEmployees: 51,
    annualRevenue: 10000,
    zipcode: 90009,
    street: "6649 N Blue Gum Street",
    city: "New Orleans",
    state: "Louisiana",
    country: "USA"
  }, {
    context: {
      traits: {
        email: "alex@example.com"
      }
    }
  }
);
```
### Supported mappings

The following table lists the mappings between the RudderStack and Freshsales properties:

| RudderStack property | Freshsales property | 
| :--------------| :---------| 
| `name` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | `name` |
| `traits.industryTypeId`<br/>`context.traits.industryTypeId` | `industry_type_id` | 
| `traits.businessTypeId`<br/>`context.traits.businessTypeId`<br/>`traits.business_type_id`<br/>`context.traits.business_type_id` | `business_type_id` | 
| `phone` | `phone` | 
| `traits.numberOfEmployees`<br/>`context.traits.numberOfEmployees` | `number_of_employees` | 
| `traits.annualRevenue`<br/>`context.traits.annualRevenue` | `annual_revenue` | 
| `traits.address`<br/>`context.traits.address` | `address` | 
| `traits.city`<br/>`traits.address.city`<br/>`context.traits.city`<br/>`context.traits.address.city` | `city` | 
| `traits.state`<br/>`traits.address.state`<br/>`context.traits.state`<br/>`context.traits.address.state` | `state` | 
| `traits.country`<br/>`traits.address.country`<br/>`context.traits.country`<br/>`context.traits.address.country` | `country` | 
| `zipcode` | `zipcode` | 
| `traits.website`<br/>`context.traits.website` | `website` | 
| `traits.territoryId`<br/>`context.traits.territoryId` | `territory_id` | 
| `traits.parentSalesAccountid`<br/>`context.traits.parentSalesAccountid` | `parent_sales_account_id` | 
| `traits.ownerId`<br/>`context.traits.ownerId` | `ownerId` | 
| `traits.facebookUserName`<br/>`context.traits.facebookUserName` | `facebook` | 
| `traits.twitterUserName`<br/>`context.traits.twitterUserName` | `twitter` | 
| `traits.linkedinUserName`<br/>`context.traits.linkedinUserName` | `linkedin` | 
| `createdAt` | `created_at` | 
| `timestamp` | `updated_at` | 

## FAQ 

#### Where can I find the Freshsales API key?

To obtain your Freshsales API key, follow these steps:

1. Log into your [Freshsales dashboard](https://www.freshworks.com/crm/login/).
2. Go to **Personal Settings** > **API Settings**.
3. Enable the captcha to complete the authentication process.
4. You will find your Freshsales API key listed under the **API Authentication** section:

{{< image src="images/event-stream-destinations/freshsales-api-key.webp" alt="Freshsales API key" >}}

{{< info >}}
For more information, refer to this [Freshsales support guide](https://crmsupport.freshworks.com/en/support/solutions/articles/50000002503-how-to-find-my-api-key-).
{{< /info >}}

