> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Salesforce

## Overzicht

Koppel je ElevenLabs AI-agents aan Salesforce CRM om klantgegevens te raadplegen, leads te beheren en kansen te maken. Met deze integratie kunnen je agents bestaande klantrecords ophalen, nieuwe leads en contacten maken en Salesforce-objecten tijdens gesprekken opvragen.

## Mogelijkheden

| Mogelijkheid              | Ondersteuning                                                                                              |
| ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Zero retention mode (ZRM) | Niet ondersteund                                                                                           |
| Bijlagen in triggers      | Niet ondersteund — bijlagen in inkomende caseopmerkingen en e-mails worden niet doorgestuurd naar de agent |
| Bijlagen in tools         | Niet ondersteund — tools werken alleen met tekst                                                           |

## Instellen

Deze integratie gebruikt **Salesforce OAuth 2.0 Client Credentials** voor authenticatie. Je moet een External Client App maken in Salesforce.

#### Een External Client App maken

1. Log als beheerder in bij je Salesforce-org
2. Ga naar **Setup** > **External Client App Manager**
3. Klik op **New External Client App**
4. Vul de **External Client App Name** (bijvoorbeeld `ElevenLabs Agents`), **API Name** en **Contact Email** in
5. Onder **API (Enable OAuth Settings)**:
   * Selecteer **Enable OAuth** en **Enable Client Credentials Flow**
   * **Callback URL**: `https://api.elevenlabs.io/oauth/callback`
   * **OAuth Start URL**: `https://api.elevenlabs.io/oauth/start`
   * **Selected OAuth Scopes**: voeg deze scopes toe:
     * **Full access (full)**
     * **Perform requests on your behalf at any time (refresh\_token, offline\_access)**
     * **Manage user data via api**
6. Klik op **Create**
7. Open op de app-pagina het tabblad **Settings**, ga naar **OAuth Settings** en klik op **Consumer Key and Secret**
8. Kopieer de **Consumer Key** en **Consumer Secret** — je hebt deze nodig voor authenticatie

#### OAuth Client Credentials-flow configureren

> **Warning**
>
> De Client Credentials Flow wordt aanbevolen voor server-naar-serverintegraties waarvoor geen
> gebruikersinteractie nodig is. Zorg dat je Salesforce-beheerder deze flow heeft ingeschakeld.

1. Klik in je External Client App op **Edit**
2. Selecteer **Enable Client Credentials Flow** — er verschijnt een veld **Run As**
3. Stel **Run As** in op je beheerder of een speciaal serviceaccount — dit bepaalt de rechten voor alle API-aanroepen
4. Stel **Permitted Users** in op **Admin approved users are pre-authorized**
5. Klik op **Save**

De gebruiker bij **Run As** bepaalt de rechten voor alle API-aanroepen. Kies een gebruiker met een System Administrator-profiel of een aangepast profiel met API-toegang en rechten voor de objecten die je agent nodig heeft (Contact, Lead, Account enzovoort). De toestemming **API Enabled** moet zijn geselecteerd in het gebruikersrecord.

#### Je Salesforce-domein vinden

Je Salesforce-domein is vereist voor API-aanroepen.

**Methode 1: Controleer je huidige URL**

Kijk in de adresbalk van je browser wanneer je bent ingelogd bij Salesforce:

* **Lightning Experience**: `https://acme.lightning.force.com/`
* **My Domain**: `https://acme.my.salesforce.com/`

**Methode 2: Setup > Company Information**

Ga naar **Setup** > **Company Information** en zoek je URL voor **My Domain** of de organisatiegegevens.

**Methode 3: Setup > Domain Management**

Ga naar **Setup** > **Domain Management** > **My Domain**. Je domein staat bovenaan de pagina.

**Veelvoorkomende domeinindelingen:**

* `https://acme.my.salesforce.com` (My Domain)
* `https://acme.lightning.force.com` (Lightning)
* `https://acme.develop.my.salesforce.com` (Sandbox)

> **Note**
>
> Gebruik het volledige domein zonder slash aan het einde.

#### Verbinden in ElevenLabs

Voer in de integratie-instellingen van ElevenLabs je Salesforce-**instance-hostnaam** in (bijvoorbeeld `acme.my.salesforce.com`), samen met de **Client ID** (Consumer Key) en **Client Secret** (Consumer Secret).

## Demovideo

> **Note**
>
> Deze demo gebruikt verouderde webhooktools. Als je de native Salesforce-integratie gebruikt, worden de tools
> automatisch geconfigureerd — je hoeft geen webhooks handmatig in te stellen.

## Zo werkt het

#### Overzicht op hoofdlijnen

#### Eerste klantvraag

De agent verzamelt klantinformatie en stelt relevante vragen om de zakelijke behoeften en huidige uitdagingen te achterhalen.

#### Klantgegevens opzoeken

De agent controleert met `salesforce_search_records` op bestaande records om contacten, accounts of leads te vinden. Met `salesforce_get_record` haalt de agent alle gegevens op en gebruikt deze informatie om het gesprek te personaliseren.

#### Leadkwalificatie

Als de klant nieuw is, verzamelt de agent contactgegevens, beoordeelt de zakelijke behoeften en bepaalt de juiste salesprocedure of routering.

#### Record maken

De agent maakt met `salesforce_create_record` het juiste record (lead, contact of opportunity), bevestigt dit aan de klant en licht de volgende stappen toe.

#### Gedetailleerde system prompt

```text
# 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.
```

> **Tip**
>
> Toolautorisatie kun je beheren met Workplace Auth Connections, dat tokenvernieuwing
> automatisch afhandelt. De tools geven leesbare namen en beschrijvingen terug in plaats van technische ID's,
> voor betere gesprekskwaliteit.

## Toolconfiguraties

Er zijn drie webhooktools beschikbaar: `salesforce_search_records`, `salesforce_get_record` en `salesforce_create_record`. Configureer voor elk de autorisatie met een Workplace Auth Connection.

### Autorisatie - Workplace OAuth2-verbinding

#### Naar Workplace Auth Connections gaan

Ga in je ElevenLabs-dashboard naar **Agents** > **Workplace Auth Connections** en klik op **Add Auth**.

#### Salesforce-verbinding configureren

Vul voor je Salesforce-integratie de volgende velden in:

**Connection Name**: `Salesforce CRM`

**Client ID**

* Je Consumer Key uit de External Client App
* Voorbeeld: `3MVG9JJlvRU3L4pRiOu8pQt5xXB4xGZGm0yW...`

**Client Secret**

* Je Consumer Secret uit de External Client App
* Voorbeeld: `1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF...`

**Token URL**

* Het OAuth-tokenendpoint van je Salesforce-domein
* Indeling: `https://{domain}.my.salesforce.com/services/oauth2/token`
* Voorbeeld: `https://acme.my.salesforce.com/services/oauth2/token`

**Scopes (optioneel)**

* OAuth-scopes voor toegang tot de Salesforce API
* Aanbevolen: `full, api, refresh_token`
* Laat leeg om de standaardscopes van je External Client App te gebruiken

**Extra Parameters (JSON)**

* Aanvullende OAuth-parameters die specifiek zijn voor je configuratie
* Voorbeeld voor de Client Credentials-flow:

```json
{
  "grant_type": "client_credentials"
}
```

#### Authenticatieverbinding maken

Klik op **Create auth connection** om je configuratie toe te voegen.

#### Gebruiken in toolconfiguraties

Sla de verbinding op zodra deze tot stand is gebracht en verwijs ernaar in de sectie **Authentication** van je webhooktoolconfiguraties.

> **Tip**
>
> Workplace Auth Connections handelt tokenvernieuwing automatisch af, dus je hoeft
> tokens niet handmatig te beheren.

### Webhooktoolconfiguraties

Voeg in de sectie **Authentication** een Workplace Auth Connection (OAuth2) toe aan elke tool. Gebruik de onderstaande tabbladen om de configuratie van elke tool te bekijken.

#### salesforce\_search\_records

**Naam:** salesforce\_search\_records
**Beschrijving:** Zoekt met SOQL-query's naar bestaande records in Salesforce. Geeft altijd leesbare informatie terug, waaronder namen, niet alleen ID's.
**Methode:** GET
**URL:** `https://acme.my.salesforce.com/services/data/v58.0/query/?q={soql_query}`

**Headers:**

* **Content-Type:** `application/json`

**Queryparameters:**

* **q:** SOQL-querytekenreeks (bijvoorbeeld "SELECT Id, Name, Email FROM Contact WHERE Email = '[example@email.com](mailto:example@email.com)'")

**Tool-JSON:**

```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

**Naam:** salesforce\_get\_record
**Beschrijving:** Haalt gedetailleerde informatie op over een specifiek Salesforce-record.
**Methode:** GET
**URL:** `https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/{record_id}`

**Headers:**

* **Content-Type:** `application/json`

**Padparameters:**

* **object\_type:** Het Salesforce-objecttype (Contact, Lead, Account enzovoort)
* **record\_id:** De unieke Salesforce-record-ID

**Tool-JSON:**

```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

**Naam:** salesforce\_create\_record
**Beschrijving:** Maakt een nieuw record in Salesforce.
**Methode:** POST
**URL:** `https://acme.my.salesforce.com/services/data/v58.0/sobjects/{object_type}/`

**Headers:**

* **Content-Type:** `application/json`

**Padparameters:**

* **object\_type:** Het Salesforce-objecttype dat je wilt maken (Lead, Contact, Account enzovoort)

**Bodyparameters:**

* **Dynamisch JSON-object** met de recordvelden en -waarden

**Tool-JSON:**

```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": {}
  }
}
```

## Veelvoorkomende Salesforce-objecten

| Object          | Doel                                                | Veelvoorkomende velden                                       |
| --------------- | --------------------------------------------------- | ------------------------------------------------------------ |
| **Lead**        | Potentiële klanten die nog niet gekwalificeerd zijn | FirstName, LastName, Email, Phone, Company, Industry, Status |
| **Contact**     | Gekwalificeerde personen gekoppeld aan accounts     | FirstName, LastName, Email, Phone, AccountId, Title          |
| **Account**     | Organisaties of bedrijven                           | Name, Type, Industry, Phone, BillingAddress                  |
| **Opportunity** | Lopende verkoopkansen                               | Name, StageName, Amount, CloseDate, AccountId                |
| **Case**        | Verzoeken aan de klantenservice                     | Subject, Description, Status, Priority, ContactId            |

## Veelvoorkomende SOQL-query's

Gebruik deze SOQL-query's als uitgangspunt wanneer je de system prompt van je agent aanpast. Alle query's geven leesbare informatie terug in plaats van technische ID's:

### Contacten zoeken op e-mailadres

```sql
SELECT Id, Name, Email, Phone, Title, Account.Name, Account.Type FROM Contact WHERE Email = 'customer@example.com'
```

### Leads zoeken op e-mailadres of telefoonnummer

```sql
SELECT Id, Name, Email, Phone, Company, Industry, Status, LeadSource, Title FROM Lead WHERE Email = 'customer@example.com' OR Phone = '+1234567890'
```

### Accounts zoeken op naam

```sql
SELECT Id, Name, Type, Industry, Phone, BillingCity, BillingState, Website FROM Account WHERE Name LIKE '%Company Name%'
```

### Recente opportunities zoeken

```sql
SELECT Id, Name, StageName, Amount, CloseDate, Account.Name, Account.Type, Owner.Name, Description FROM Opportunity WHERE CreatedDate = THIS_MONTH
```

### Opportunities zoeken op account

```sql
SELECT Id, Name, StageName, Amount, CloseDate, Probability, NextStep, Owner.Name FROM Opportunity WHERE Account.Name LIKE '%Company Name%'
```

## Integratie testen

Test de integratie nadat je je External Client App hebt ingesteld en de integratie hebt verbonden, voordat je deze in productie neemt:

1. **Zoekfunctionaliteit**: Laat je agent zoeken naar bestaande contacten.
2. **Record maken**: Laat je agent een nieuwe lead of contact maken.
3. **Gegevens ophalen**: Controleer of je agent gedetailleerde klantinformatie kan ophalen.

## Trigger voor caseopmerkingen: e-mailantwoorden voor Email-to-Case

Als je de trigger **Salesforce Case Comment** hebt ingeschakeld (automatisch antwoord van de agent op Service Cloud Cases), worden antwoorden op Cases met minstens één inkomende e-mail als een echte e-mail in dezelfde thread teruggestuurd naar de klant — niet alleen als interne Case Comment. Dit is gebaseerd op de vraag of de Case een inkomende e-mail heeft, niet op de waarde van de keuzelijst **Origin** van de Case. Daarom werkt dit ook goed als je org een aangepaste Origin-waarde gebruikt, zoals "Email - Returns", in plaats van de letterlijke waarde "Email". Cases zonder inkomende e-mail worden ongewijzigd als openbare Case Comment geplaatst. Alle adressen die in de oorspronkelijke e-mail van de klant in de CC staan, worden ook automatisch in de CC van het antwoord gezet, net zoals bij "Reply All" van een menselijke agent — met uitzondering van de Email-to-Case-routeringsadressen van je org. Die worden bewust niet in de CC gezet, zodat het antwoord niet opnieuw door Email-to-Case wordt verwerkt en de agent niet op zijn eigen bericht reageert.

Voor het versturen van e-mailantwoorden is extra configuratie nodig boven op wat alleen voor Case Comments vereist is:

* Het Profile of de Permission Set van de gebruiker bij **Run As** moet de systeemtoestemming **Send Email** hebben ingeschakeld (`Setup` > `Users` > `Profiles`, onder System Permissions), naast de toestemming **API Enabled** die al vereist is voor de integratie.
* De instelling **Email Deliverability** van je org (`Setup` > `Email` > `Deliverability`) moet externe e-mail toestaan — Sandboxes gebruiken standaard een beperkte instelling, die uitgaande e-mail stilzwijgend blokkeert.
* Als je wilt dat antwoorden vanaf een supportalias komen in plaats van vanuit de eigen mailbox van de gebruiker bij Run As, stel je het veld **Org-Wide Email Address Id** op de trigger in op de Id van een **Organization-Wide Email Address** (`Setup` > `Organization-Wide Addresses` > klik op het adres > kopieer de Id uit de URL). Laat dit leeg om vanaf het eigen adres van de gebruiker bij Run As te verzenden.
* Stel het veld **Email-to-Case Routing Address(es)** op de trigger in op de Email-to-Case-adressen van je org (door komma's gescheiden als er meer dan één is, `Setup` > `Email-to-Case`). Zonder dit probeert de integratie het routeringsadres af te leiden uit de e-mail van de klant (het `To`-adres). Daardoor worden gevallen gemist waarin je routeringsadres alleen in de CC stond in plaats van de primaire ontvanger te zijn — het terug in de CC zetten bij een antwoord zou de agent in die situatie opnieuw op zijn eigen bericht laten reageren.

Als de org van een klant dit niet heeft geconfigureerd, wordt bij een fout tijdens het versturen van een e-mail teruggevallen op het plaatsen van een openbare Case Comment. Zo gaat een antwoord nooit stilzwijgend verloren — maar de klant ontvangt het pas per e-mail nadat je het bovenstaande hebt ingesteld.

## Veiligheidsoverwegingen

* Gebruik HTTPS-endpoints voor alle API-aanroepen.
* Zorg dat de juiste beveiliging op veldniveau is geconfigureerd in Salesforce.
* De rechten van de gebruiker bij Run As bepalen tot welke gegevens de integratie toegang heeft — beperk deze passend.
* Controleer API-toegang en -gebruik regelmatig.

## Handige links

* [Salesforce REST API-documentatie](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/)
* [Referentie voor de SOQL-querytaal](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/)
* [External Client Apps en OAuth 2.0](https://help.salesforce.com/s/articleView?id=sf.connected_app_overview.htm)
* [Best practices voor Salesforce-beveiliging](https://help.salesforce.com/s/articleView?id=sf.security_overview.htm)