Salesforce
Overview
Section titled “Overview”Connect your ElevenLabs AI agents with Salesforce CRM to access customer data, manage leads, and create opportunities. This integration enables your agents to retrieve existing customer records, create new leads and contacts, and query Salesforce objects during conversations.
Capabilities
Section titled “Capabilities”| Capability | Support |
|---|---|
| Zero retention mode (ZRM) | Not supported |
| Attachments in triggers | Not supported — attachments on incoming case comments and emails are not forwarded to the agent |
| Attachments in tools | Not supported — tools operate on text only |
This integration uses Salesforce OAuth 2.0 Client Credentials for authentication. You will need to create an External Client App in Salesforce.
Create an External Client App
Section titled “Create an External Client App”- Log into your Salesforce org as an administrator
- Go to Setup > External Client App Manager
- Click New External Client App
- Fill in the External Client App Name (e.g.,
ElevenLabs Agents), API Name, and Contact Email - Under API (Enable OAuth Settings):
- Check Enable OAuth and Enable Client Credentials Flow
- Callback URL:
https://api.elevenlabs.io/oauth/callback - OAuth Start URL:
https://api.elevenlabs.io/oauth/start - Selected OAuth Scopes: add these scopes:
- Full access (full)
- Perform requests on your behalf at any time (refresh_token, offline_access)
- Manage user data via api
- Click Create
- On the app page, open the Settings tab, go to OAuth Settings, and click Consumer Key and Secret
- Copy the Consumer Key and Consumer Secret — you will need these for authentication
Configure OAuth Client Credentials flow
Section titled “Configure OAuth Client Credentials flow”- In your External Client App, click Edit
- Check Enable Client Credentials Flow — a Run As field will appear
- Set Run As to your admin user or a dedicated service account — this determines the permissions for all API calls
- Set Permitted Users to Admin approved users are pre-authorized
- Click Save
The Run As user determines the permissions for all API calls. Choose a user with a System Administrator profile or a custom profile that has API access and permission to the objects your agent needs (Contact, Lead, Account, etc.). The API Enabled permission must be checked on the user record.
Find your Salesforce domain
Section titled “Find your Salesforce domain”Your Salesforce domain is required for API calls.
Method 1: Check your current URL
When logged into Salesforce, look at your browser's address bar:
- Lightning Experience:
https://acme.lightning.force.com/ - My Domain:
https://acme.my.salesforce.com/
Method 2: Setup > Company Information
Go to Setup > Company Information and look for your My Domain URL or Organization information.
Method 3: Setup > Domain Management
Go to Setup > Domain Management > My Domain. Your domain will be shown at the top of the page.
Common domain formats:
https://acme.my.salesforce.com(My Domain)https://acme.lightning.force.com(Lightning)https://acme.develop.my.salesforce.com(Sandbox)
Connect in ElevenLabs
Section titled “Connect in ElevenLabs”In the ElevenLabs integration setup, enter your Salesforce instance hostname (e.g., acme.my.salesforce.com), Client ID (Consumer Key), and Client Secret (Consumer Secret).
Demo video
Section titled “Demo video”How it works
Section titled “How it works”High-level overview
Section titled “High-level overview”Initial customer inquiry
Section titled “Initial customer inquiry”The agent gathers customer information and asks relevant questions to identify their business requirements and current challenges.
Customer data lookup
Section titled “Customer data lookup”The agent checks for existing records using salesforce_search_records to find contacts, accounts, or leads. It retrieves full details with salesforce_get_record and uses this information to personalize the conversation.
Lead qualification
Section titled “Lead qualification”If the customer is new, the agent collects contact information, assesses their business needs, and determines the appropriate sales process or routing.
Record creation
Section titled “Record creation”The agent creates the appropriate record (lead, contact, or opportunity) using salesforce_create_record, confirms creation with the customer, and explains next steps.
Detailed system prompt
Section titled “Detailed system prompt”# Personality
You are a helpful sales assistant responsible for managing customer relationships and creating records in Salesforce using the available tools. Be friendly, professional, and consultative in your approach.
# Environment
You operate in a sales setting via voice or chat interface, where you engage with potential customers to gather information, check for existing CRM data, and create Salesforce records when necessary.
# Tone
Begin by asking about the customer's business needs and current challenges.
Then, ask relevant qualification questions to understand their requirements, one question at a time, and wait for their response before proceeding.
Once you have basic information about the customer, say you will check for any existing records in the system.
Use any existing information to personalize the conversation and avoid asking for data you already have.
When discussing opportunities, always reference them by name (e.g., "Q1 Enterprise Deal") rather than by ID.
# Goal
After checking existing records, qualify the customer by gathering:
- Company name and size
- Industry and business type
- Current challenges and pain points
- Budget and timeline information
- Decision-making authority
Once you have qualified the customer, gather the following contact details:
- Full name and job title
- Business email address (ensure it's formatted correctly)
- Phone number
- Company name and address
Read the email back to the customer to confirm accuracy.
Once all information is confirmed, explain that you will create a record in our system.
Create the appropriate record (Lead, Contact, or Opportunity) using the `salesforce_create_record` tool.
Thank the customer and explain the next steps in the sales process.
# Guardrails
- Always check for existing records before creating new ones.
- If the customer asks to proceed, do so with the existing information.
- Qualify leads appropriately based on their responses.
- Do not discuss topics outside of business solutions and sales.
- Always maintain professional communication.
- Protect customer privacy and handle data securely.
# Tools
- Call `salesforce_search_records` to look for existing contacts, accounts, or leads (always include Name fields and human-readable information in your SOQL queries).
- If found, call `salesforce_get_record` to get detailed information about the existing record.
- Use `salesforce_create_record` to generate Leads, Contacts, or Opportunities after qualification.Tool configurations
Section titled “Tool configurations”Three webhook tools are available: salesforce_search_records, salesforce_get_record, and salesforce_create_record. Configure authorization for each using a Workplace Auth Connection.
Authorization - Workplace OAuth2 connection
Section titled “Authorization - Workplace OAuth2 connection”Navigate to Workplace Auth Connections
Section titled “Navigate to Workplace Auth Connections”In your ElevenLabs dashboard, go to Agents > Workplace Auth Connections and click Add Auth.
Configure Salesforce connection
Section titled “Configure Salesforce connection”Fill in the following fields for your Salesforce integration:
Connection Name: Salesforce CRM
Client ID
- Your Consumer Key from the External Client App
- Example:
3MVG9JJlvRU3L4pRiOu8pQt5xXB4xGZGm0yW...
Client Secret
- Your Consumer Secret from the External Client App
- Example:
1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF...
Token URL
- Your Salesforce domain's OAuth token endpoint
- Format:
https://{domain}.my.salesforce.com/services/oauth2/token - Example:
https://acme.my.salesforce.com/services/oauth2/token
Scopes (optional)
- OAuth scopes for Salesforce API access
- Recommended:
full, api, refresh_token - Leave blank to use default scopes from your External Client App
Extra Parameters (JSON)
- Additional OAuth parameters specific to your setup
- Example for Client Credentials flow:
{
"grant_type": "client_credentials"
}Create auth connection
Section titled “Create auth connection”Click Create auth connection to add your configuration.
Use in tool configurations
Section titled “Use in tool configurations”Once the connection is successful, save it and reference it in your webhook tool configurations in the Authentication section.
Webhook tool configurations
Section titled “Webhook tool configurations”Add a Workplace Auth Connection (OAuth2) to each tool in the Authentication section. Use the tabs below to review each tool's configuration.
salesforce_search_records
Section titled “salesforce_search_records”Name: salesforce_search_records
Description: Searches for existing records in Salesforce using SOQL queries. Always returns human-readable information including Names, not just IDs.
Method: GET
URL: https://acme.my.salesforce.com/services/data/v58.0/query/?q={soql_query}
Headers:
- Content-Type:
application/json
Query Parameters:
- q: SOQL query string (e.g., "SELECT Id, Name, Email FROM Contact WHERE Email = 'example@email.com'")
Tool JSON:
{
"type": "webhook",
"name": "salesforce_search_records",
"description": "Searches for existing records in Salesforce using SOQL queries. Always returns human-readable names and details, not just IDs.",
"api_schema": {
"url": "https://acme.my.salesforce.com/services/data/v58.0/query/",
"method": "GET",
"path_params_schema": [],
"query_params_schema": [
{
"id": "q",
"type": "string",
"description": "SOQL query string to search for records. Always include Name fields and other human-readable information. Example: SELECT Id, Name, Email, Phone, Company FROM Contact WHERE Email = 'customer@example.com'. For Opportunities, include: SELECT Id, Name, StageName, Amount, CloseDate, Account.Name FROM Opportunity",
"dynamic_variable": "",
"constant_value": "",
"required": true,
"value_type": "llm_prompt"
}
],
"request_body_schema": null,
"request_headers": [
{
"type": "value",
"name": "Content-Type",
"value": "application/json"
}
]
},
"response_timeout_secs": 30,
"dynamic_variables": {
"dynamic_variable_placeholders": {}
}
}salesforce_get_record
Section titled “salesforce_get_record”Name: salesforce_get_record
Description: Retrieves detailed information about a specific Salesforce record.
Method: GET
URL: https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/{record_id}
Headers:
- Content-Type:
application/json
Path Parameters:
- object_type: The Salesforce object type (Contact, Lead, Account, etc.)
- record_id: The unique Salesforce record ID
Tool JSON:
{
"type": "webhook",
"name": "salesforce_get_record",
"description": "Retrieves detailed information about a specific Salesforce record.",
"api_schema": {
"url": "https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/{record_id}",
"method": "GET",
"path_params_schema": [
{
"id": "object_type",
"type": "string",
"description": "The Salesforce object type (Contact, Lead, Account, Opportunity, etc.)",
"dynamic_variable": "",
"constant_value": "",
"required": true,
"value_type": "llm_prompt"
},
{
"id": "record_id",
"type": "string",
"description": "The unique Salesforce record ID obtained from search results",
"dynamic_variable": "",
"constant_value": "",
"required": true,
"value_type": "llm_prompt"
}
],
"query_params_schema": [],
"request_body_schema": null,
"request_headers": [
{
"type": "value",
"name": "Content-Type",
"value": "application/json"
}
]
},
"response_timeout_secs": 30,
"dynamic_variables": {
"dynamic_variable_placeholders": {}
}
}salesforce_create_record
Section titled “salesforce_create_record”Name: salesforce_create_record
Description: Creates a new record in Salesforce.
Method: POST
URL: https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/
Headers:
- Content-Type:
application/json
Path Parameters:
- object_type: The Salesforce object type to create (Lead, Contact, Account, etc.)
Body Parameters:
- Dynamic JSON object containing the record fields and values
Tool JSON:
{
"type": "webhook",
"name": "salesforce_create_record",
"description": "Creates a new record in Salesforce (Lead, Contact, Account, Opportunity, etc.)",
"api_schema": {
"url": "https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/",
"method": "POST",
"path_params_schema": [
{
"id": "object_type",
"type": "string",
"description": "The Salesforce object type to create (Lead, Contact, Account, Opportunity, etc.)",
"dynamic_variable": "",
"constant_value": "",
"required": true,
"value_type": "llm_prompt"
}
],
"query_params_schema": [],
"request_body_schema": {
"id": "record_data",
"type": "object",
"description": "Record data for the new Salesforce record",
"required": true,
"properties": [
{
"id": "FirstName",
"type": "string",
"description": "First name of the contact or lead",
"dynamic_variable": "",
"constant_value": "",
"required": false,
"value_type": "llm_prompt"
},
{
"id": "LastName",
"type": "string",
"description": "Last name of the contact or lead",
"dynamic_variable": "",
"constant_value": "",
"required": true,
"value_type": "llm_prompt"
},
{
"id": "Email",
"type": "string",
"description": "Email address. Must be properly formatted: user@domain.com",
"dynamic_variable": "",
"constant_value": "",
"required": true,
"value_type": "llm_prompt"
},
{
"id": "Phone",
"type": "string",
"description": "Phone number of the contact or lead",
"dynamic_variable": "",
"constant_value": "",
"required": false,
"value_type": "llm_prompt"
},
{
"id": "Company",
"type": "string",
"description": "Company name (required for Lead object)",
"dynamic_variable": "",
"constant_value": "",
"required": false,
"value_type": "llm_prompt"
},
{
"id": "Title",
"type": "string",
"description": "Job title of the contact or lead",
"dynamic_variable": "",
"constant_value": "",
"required": false,
"value_type": "llm_prompt"
},
{
"id": "Industry",
"type": "string",
"description": "Industry of the lead's company",
"dynamic_variable": "",
"constant_value": "",
"required": false,
"value_type": "llm_prompt"
},
{
"id": "Description",
"type": "string",
"description": "Additional notes or description about the lead/contact",
"dynamic_variable": "",
"constant_value": "",
"required": false,
"value_type": "llm_prompt"
}
]
},
"request_headers": [
{
"type": "value",
"name": "Content-Type",
"value": "application/json"
}
]
},
"response_timeout_secs": 30,
"dynamic_variables": {
"dynamic_variable_placeholders": {}
}
}Common Salesforce objects
Section titled “Common Salesforce objects”| Object | Purpose | Common fields |
|---|---|---|
| Lead | Potential customers not yet qualified | FirstName, LastName, Email, Phone, Company, Industry, Status |
| Contact | Qualified individuals associated with accounts | FirstName, LastName, Email, Phone, AccountId, Title |
| Account | Organizations or companies | Name, Type, Industry, Phone, BillingAddress |
| Opportunity | Sales deals in progress | Name, StageName, Amount, CloseDate, AccountId |
| Case | Customer service requests | Subject, Description, Status, Priority, ContactId |
Common SOQL queries
Section titled “Common SOQL queries”Use these SOQL queries as starting points when customizing your agent's system prompt. All queries return human-readable information rather than technical IDs:
Search for contacts by email
Section titled “Search for contacts by email”SELECT Id, Name, Email, Phone, Title, Account.Name, Account.Type FROM Contact WHERE Email = 'customer@example.com'Search for leads by email or phone
Section titled “Search for leads by email or phone”SELECT Id, Name, Email, Phone, Company, Industry, Status, LeadSource, Title FROM Lead WHERE Email = 'customer@example.com' OR Phone = '+1234567890'Search for accounts by name
Section titled “Search for accounts by name”SELECT Id, Name, Type, Industry, Phone, BillingCity, BillingState, Website FROM Account WHERE Name LIKE '%Company Name%'Search for recent opportunities
Section titled “Search for recent opportunities”SELECT Id, Name, StageName, Amount, CloseDate, Account.Name, Account.Type, Owner.Name, Description FROM Opportunity WHERE CreatedDate = THIS_MONTHSearch for opportunities by account
Section titled “Search for opportunities by account”SELECT Id, Name, StageName, Amount, CloseDate, Probability, NextStep, Owner.Name FROM Opportunity WHERE Account.Name LIKE '%Company Name%'Integration testing
Section titled “Integration testing”After setting up your External Client App and connecting the integration, test it before deploying to production:
- Search functionality: Ask your agent to search for existing contacts.
- Record creation: Have your agent create a new lead or contact.
- Data retrieval: Verify your agent can retrieve detailed customer information.
Case comment trigger: email replies for Email-to-Case
Section titled “Case comment trigger: email replies for Email-to-Case”If you've enabled the Salesforce Case Comment trigger (agent auto-response to Service Cloud Cases), replies to Cases with at least one inbound email are sent back to the customer as a real, threaded email — not just an internal Case Comment. This is based on whether the Case has an inbound email, not on the Case's Origin picklist value, so it still works correctly if your org uses a customized Origin value like "Email - Returns" rather than the literal "Email". Cases with no inbound email continue to be posted as a public Case Comment, unchanged. Any addresses CC'd on the customer's original email are automatically CC'd on the reply as well, matching how a human agent's "Reply All" would behave — except for your org's Email-to-Case routing address(es), which are deliberately excluded from CC so the reply doesn't get re-ingested by Email-to-Case and re-trigger the agent on its own message.
Sending email replies requires some additional setup beyond what's needed for Case Comments alone:
- The Run As user's Profile or Permission Set must have the Send Email system permission enabled (
Setup>Users>Profiles, under System Permissions), in addition to the API Enabled permission already required for the integration. - Your org's Email Deliverability setting (
Setup>Email>Deliverability) must allow external email — Sandboxes default this to a restricted setting, which silently blocks outbound email. - If you want replies to come from a support alias rather than the Run As user's own mailbox, set the Org-Wide Email Address Id field on the trigger to the Id of an Organization-Wide Email Address (
Setup>Organization-Wide Addresses> click the address > copy the Id from the URL). Leave it blank to send from the Run As user's own address. - Set the Email-to-Case Routing Address(es) field on the trigger to your org's Email-to-Case address(es) (comma separated if more than one,
Setup>Email-to-Case). Without this, the integration falls back to guessing the routing address from the customer's email (itsToaddress), which misses cases where your routing address was only CC'd rather than the primary recipient — CC'ing it back on a reply in that situation would re-trigger the agent on its own message.
If a customer's org doesn't have these configured, an email send failure falls back to posting a public Case Comment, so a reply is never silently dropped — but the customer won't receive it by email until the above is set up.
Security considerations
Section titled “Security considerations”- Use HTTPS endpoints for all API calls.
- Ensure proper field-level security is configured in Salesforce.
- The Run As user's permissions determine what data the integration can access — scope them appropriately.
- Regularly audit API access and usage.