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

# Salesforce integration

> Connect Salesforce to Thoughtly to trigger calls from flows, sync leads and contacts, and write call outcomes, recordings, and activities back to Salesforce.

export const ArcadeEmbed = ({code}) => <div style={{
  position: 'relative',
  paddingBottom: 'calc(54.13424124513618% + 41px)',
  height: 0,
  width: '100%'
}}>
		<iframe src={`https://demo.arcade.software/${code}?embed&embed_mobile=tab&embed_desktop=inline&show_copy_link=true`} frameBorder="0" loading="lazy" allowFullScreen allow="clipboard-write" style={{
  position: 'absolute',
  top: 0,
  left: 0,
  width: '100%',
  height: '100%',
  colorScheme: 'light'
}} />
    </div>;

export const IntegrationPage = ({actions, triggers, name, domain, logoOverride}) => {
  const logoOverrides = {
    acuity: 'https://cdn.thoughtly.com/integrations/acuity_scheduling.svg',
    acuityscheduling: 'https://cdn.thoughtly.com/integrations/acuity_scheduling.svg',
    'cal.com': 'https://cdn.thoughtly.com/integrations/cal.com.svg',
    calcom: 'https://cdn.thoughtly.com/integrations/cal.com.svg',
    cal: 'https://cdn.thoughtly.com/integrations/cal.com.svg',
    'fence flow': 'https://cdn.thought.ly/integrations/fence-flow.png',
    fenceflow: 'https://cdn.thought.ly/integrations/fence-flow.png',
    gohighlevel: 'https://cdn.thought.ly/integrations/highlevel.png',
    highlevel: 'https://cdn.thought.ly/integrations/highlevel.png',
    hubspot: 'https://cdn.thought.ly/integrations/hubspot.png',
    keap: 'https://cdn.thoughtly.com/integrations/keap.svg',
    mindbody: 'https://cdn.thoughtly.com/integrations/mindbody.svg',
    pipedrive: 'https://cdn.thoughtly.com/integrations/pipedrive.svg',
    salesforce: 'https://cdn.thoughtly.com/integrations/salesforce.svg',
    slack: 'https://cdn.thoughtly.com/integrations/slack.svg',
    smartsheet: 'https://cdn.thoughtly.com/integrations/smartsheet.svg',
    trello: 'https://cdn.thoughtly.com/integrations/trello.svg',
    zendesk: 'https://cdn.thoughtly.com/integrations/zendesk.svg',
    zoho: 'https://cdn.thoughtly.com/integrations/zoho.svg',
    zoom: 'https://cdn.thoughtly.com/integrations/zoom.svg',
    gmail: 'https://cdn.thoughtly.com/integrations/google-mail.png'
  };
  const normalizeKey = value => (value || '').toString().trim().toLowerCase();
  const normalizeHost = value => {
    if (!value) {
      return '';
    }
    const cleaned = value.replace(/^https?:\/\//, '').replace(/^[^@]+@/, '');
    return cleaned.split(/[/?#]/)[0];
  };
  const getLogoSrc = ({name: logoName, domain: logoDomain, logoOverride}) => {
    if (logoOverride) {
      return logoOverride;
    }
    const nameKey = normalizeKey(logoName);
    const host = normalizeHost(logoDomain);
    const hostKey = normalizeKey(host);
    const hostBase = hostKey.split('.').slice(-2, -1)[0] || '';
    return logoOverrides[nameKey] || logoOverrides[nameKey.replace(/\s+/g, '')] || logoOverrides[hostKey] || logoOverrides[hostBase] || (logoDomain ? `https://logo.clearbit.com/${logoDomain}` : undefined);
  };
  return <div>
		<div className="flex flex-row items-center h-10 pb-4">
			<img src={getLogoSrc({
    name,
    domain,
    logoOverride
  })} className="w-5 rounded-md mr-2 h-5" />
			<div className="text-xl">
				Integrate with <a href={`https://${domain}`} target={"_blank"}><span className="font-bold">{name}</span></a>
			</div>
		</div>

		By integrating Thoughtly with {name}, you can automate tasks and workflows before, during, and after calls. To integrate with {name}, head to the <a href="https://app.thoughtly.com/integration" target="_blank">Integrations</a> page and follow the instructions.

		{triggers && <div>
				<hr />
				<h3>Triggers</h3>

				Triggers are available via <a href="/automations/triggers">Automations</a>. You can use them to start your Automations, such as for initiating a call or sending an SMS.

				{triggers.map(trigger => <div className="text-sm">
						<h4 className="text-gray-600 text-md">{trigger.name}</h4>

						{trigger.description}
					</div>)}
			</div>}

		{actions && actions.length > 0 && <div>
				<hr />
				<h3>Actions</h3>

				Actions are available both via <a href="/agents/nodes">Mid-Call Actions</a> and <a href="/automations/actions">Automations</a>. You can give your Voice Agents access to these Actions so they can perform tasks in {name} during a call, or use them in Automations to automate tasks before and after calls.

				{actions.map((action, i) => <div key={i} className="text-sm">
						<h4 className={`text-gray-600 ${action.deprecated ? 'line-through text-red-500' : ''}`}>
							<span className="text-gray-600">{action.name}</span>
							{action.deprecated && <span className="ml-3 text-xs">(Deprecated)</span>}
						</h4>
						<p className={action.deprecated ? 'text-gray-400' : ''}>
							{action.description}
						</p>
					</div>)}
			</div>}
	</div>;
};

<ArcadeEmbed code="KmiNZVFi2gBYdjDW0Uko" />

***

<IntegrationPage
  name="Salesforce"
  domain="salesforce.com"
  triggers={[
	{
		"name": "New Contact",
		"description": "Triggered when a new contact is created in Salesforce."
	},
	{
		"name": "New Object",
		"description": "Triggered when a new object is created in Salesforce."
	}
]}
  actions={[
    {
        "name": "Execute SOQL Query",
		"description": "This action executes a SOQL query in Salesforce."
	},
	{
		"name": "Create Object",
		"description": "This action creates a new object record in Salesforce."
	},
	{
		"name": "Update Object",
		"description": "This action updates an existing object record in Salesforce."
	},
	{
		"name": "Delete Object",
		"description": "This action deletes an object record in Salesforce."
	},
	{
		"name": "Add Topic to Object",
		"description": "This action adds a topic to an object record in Salesforce."
	},
	{
		"name": "Get Access Token",
		"description": "This action generates an access token for Salesforce API calls."
	},
]}
/>

## Update Object record ID requirement

When using Salesforce **Update Object**, provide the Salesforce record `Id` for the object you want to update. The action uses this ID to update the existing record rather than creating or searching for one.

If you do not have the record ID yet, add a lookup or sync step earlier in the workflow and map the returned `Id` into the update action.

## API rate limits

Salesforce API limits can affect high-volume workflows. If an action fails because of rate limiting, reduce concurrency, batch updates where possible, or retry after the limit window resets.
