Integration

Use Speak AI with Salesforce

Auto-log every call as a Salesforce Task, push sentiment and topics to custom Opportunity fields, and surface Speak summaries inside the Lightning record page. Production-ready in an afternoon with the REST API and Connected App OAuth.

Free 7-day trial. No credit card required. Works with Sales Cloud, Service Cloud, and Lightning Experience.
RESTAPI + LWC
17Webhook Events
100+Languages
Freeto Try

Trusted by 250,000+ people and teams

What you can do

Once Speak is wired into Salesforce, every meeting and call becomes a Task or Event on the matching Contact and Opportunity, with AI summary and sentiment ready for native Salesforce reports, dashboards, and Flows.

Auto-log every call as a Salesforce Task

Speak’s media.analyzed webhook fires after every recorded call. A small middleware authenticates with your Connected App, resolves the Contact by attendee email, and POSTs a Task with summary, transcript link, and call duration. No copy-paste, no missed activities.

Push AI insights to custom Opportunity fields

Magic Prompt extracts sentiment, topics, competitors, and risk signals. Values write to custom fields like Speak_Last_Call_Sentiment__c. Salesforce reports and pipeline-velocity dashboards segment on real conversation data, not opp-stage guesswork.

Surface Speak summaries inside the Lightning record page

A Lightning Web Component renders on the Opportunity record page showing the latest Speak calls inline. Sales reps see summary, sentiment, and key moments without leaving Salesforce.

Query Speak from Claude or ChatGPT, scoped to Salesforce

Speak’s MCP server lets sales leadership ask “show me Opportunities in Negotiation where the latest Speak call sentiment dropped below neutral” in plain English. Pair with a Salesforce MCP server and Claude joins across both.

Set up in 3 steps

Set up your Connected App, generate a Speak API key, then pick the integration path that matches your stack.

Sign up for Speak AI

Create a free account at app.speakai.co. You get a 7-day trial with full access. Once you are in, go to Settings > API and copy your API key.

Pick your integration path

Webhook + REST API (canonical)

Forward Speak’s media.analyzed webhook to a small middleware. Middleware exchanges Connected App credentials for an OAuth token, then POSTs to /services/data/v66.0/sobjects/Task/. Production-ready in an afternoon.

Make.com or n8n (low-code)

Visual workflow alternative to writing your own middleware. Both have native Salesforce + Speak modules and handle OAuth refresh automatically.

Lightning Web Component (sidebar UI)

Drop a custom LWC on the Opportunity Lightning record page via App Builder. Calls Speak’s /v1/media/insight through an Apex controller using a Named Credential so the API key stays server-side.

MCP for Claude and ChatGPT

Connect Claude Desktop with npx @speakai/mcp-server init, or add the remote MCP server. Tag Speak media with Salesforce record IDs and Claude can search across the linked call library.

Set up a Salesforce Connected App

In Salesforce, go to Setup > App Manager > New Connected App. Enable OAuth, add the api and refresh_token scopes, and select Client Credentials Flow. Copy the Consumer Key and Secret as SF_CLIENT_ID and SF_CLIENT_SECRET in your middleware environment.

Real workflows, real results

Four production patterns Speak customers ship with Salesforce. Pick the one that fits your team and copy the recipe.







For sales and RevOps teams · Webhook + REST API

Auto-log every call as a Salesforce Task

Speak’s media.analyzed webhook fires after every recorded call. A 40-line middleware exchanges Connected App credentials for an OAuth token, resolves the Contact by attendee email, and creates a completed Task with summary, transcript link, and call duration.

Middleware: webhook receiver to Salesforce Task






# 1. Exchange Connected App credentials for an OAuth token
curl -X POST https://login.salesforce.com/services/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=$SF_CLIENT_ID&client_secret=$SF_CLIENT_SECRET"
# Response: {"access_token":"00D...","instance_url":"https://yourorg.my.salesforce.com",...}

# 2. Create the Task on the matching Contact
curl -X POST "$INSTANCE_URL/services/data/v66.0/sobjects/Task/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Subject": "Acme Corp - Discovery call",
    "Description": "Speak AI Summary: Acme is evaluating Speak for sales enablement. Next step: send pricing.\n\nTranscript: https://app.speakai.co/media/med_abc123",
    "WhoId": "003XX000004C0vMQAS",
    "WhatId": "006XX000005Lk0ZQAS",
    "Status": "Completed",
    "ActivityDate": "2026-05-06",
    "Type": "Call",
    "CallDurationInSeconds": 1820,
    "TaskSubtype": "Call"
  }'
import express from "express";
const app = express();
app.use(express.json());

app.post("/speak-webhook", async (req, res) => {
  // Speak fires {eventType, state, mediaId} -- flat.
  const { eventType, state, mediaId } = req.body;
  if (eventType !== "media.analyzed" || state !== "processed") return res.sendStatus(204);
  res.sendStatus(202);

  // 1. Fetch full insight + Magic Prompt summary in parallel.
  const [insightRes, summary] = await Promise.all([
    fetch(`https://api.speakai.co/v1/media/insight/${mediaId}`,
      { headers: { "x-speakai-key": process.env.SPEAK_API_KEY } }).then(r => r.json()),
    runMagicPrompt(mediaId,
      "Summarize this sales call in 2 sentences. End with the next step."),
  ]);
  const media = insightRes.data;

  // 2. Salesforce token (cache; refresh ~15 min before expiry).
  const tokenRes = await fetch("https://login.salesforce.com/services/oauth2/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "client_credentials",
      client_id: process.env.SF_CLIENT_ID,
      client_secret: process.env.SF_CLIENT_SECRET,
    }),
  });
  const { access_token, instance_url } = await tokenRes.json();

  // 3. Resolve Contact by speaker email (insight.speakers carries the
  //    speaker name; pair with your own email lookup, e.g. calendar).
  const email = await emailFromMedia(media);
  const q = `SELECT Id, AccountId FROM Contact WHERE Email = '${email}' LIMIT 1`;
  const contactRes = await fetch(
    `${instance_url}/services/data/v66.0/query/?q=${encodeURIComponent(q)}`,
    { headers: { Authorization: `Bearer ${access_token}` } }
  );
  const contact = (await contactRes.json()).records[0];

  // 4. Create the Task.
  await fetch(`${instance_url}/services/data/v66.0/sobjects/Task/`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${access_token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      Subject: media.name || "Speak AI call",
      Description: `${summary}

Transcript: https://app.speakai.co/media/${mediaId}`,
      WhoId: contact?.Id,
      Status: "Completed",
      ActivityDate: media.createdAt.slice(0, 10),
      Type: "Call",
      CallDurationInSeconds: media.duration?.inSecond,
      TaskSubtype: "Call",
    }),
  });
});

// Helper: fire Magic Prompt + poll until completed (~2-3s typical).
async function runMagicPrompt(mediaId, prompt) {
  await fetch("https://api.speakai.co/v1/prompt/", {
    method: "POST",
    headers: {
      "x-speakai-key": process.env.SPEAK_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      mediaIds: [mediaId], prompt,
      isStream: false, isIndividualPrompt: true,
    }),
  });
  for (let i = 0; i < 20; i++) {
    await new Promise(r => setTimeout(r, 1000));
    const r = await fetch(
      `https://api.speakai.co/v1/prompt/messages?mediaIds=${mediaId}&pageSize=1`,
      { headers: { "x-speakai-key": process.env.SPEAK_API_KEY } }
    );
    const j = await r.json();
    const msg = j?.data?.history?.[0]?.messages?.[0];
    if (msg && msg.state === "completed") return msg.answer;
  }
  return ""; // Magic Prompt timed out -- skip the summary field.
}

app.listen(3000);
import asyncio, os
from fastapi import FastAPI, Request
import httpx

app = FastAPI()
SF_CLIENT_ID = os.environ["SF_CLIENT_ID"]
SF_CLIENT_SECRET = os.environ["SF_CLIENT_SECRET"]

async def sf_token():
    async with httpx.AsyncClient() as c:
        r = await c.post(
            "https://login.salesforce.com/services/oauth2/token",
            data={
                "grant_type": "client_credentials",
                "client_id": SF_CLIENT_ID,
                "client_secret": SF_CLIENT_SECRET,
            },
        )
        return r.json()

@app.post("/speak-webhook")
async def speak_webhook(req: Request):
    # Speak fires {eventType, state, mediaId} -- flat.
    body = await req.json()
    if body.get("eventType") != "media.analyzed" or body.get("state") != "processed":
        return {"ok": True}
    media_id = body["mediaId"]

    # 1. Fetch insight + Magic Prompt summary in parallel.
    headers = {"x-speakai-key": os.environ["SPEAK_API_KEY"]}
    async with httpx.AsyncClient(timeout=30) as c:
        ir = await c.get(f"https://api.speakai.co/v1/media/insight/{media_id}", headers=headers)
        media = ir.json()["data"]
    summary = await run_magic_prompt(media_id,
        "Summarize this sales call in 2 sentences. End with the next step.")

    tok = await sf_token()
    sf_headers = {"Authorization": f"Bearer {tok['access_token']}"}
    inst = tok["instance_url"]

    email = await email_from_media(media)
    q = f"SELECT Id, AccountId FROM Contact WHERE Email = '{email}' LIMIT 1"
    async with httpx.AsyncClient() as c:
        cr = await c.get(f"{inst}/services/data/v66.0/query/", params={"q": q}, headers=sf_headers)
        records = cr.json().get("records", [])
        contact = records[0] if records else None

        await c.post(
            f"{inst}/services/data/v66.0/sobjects/Task/",
            headers={**sf_headers, "Content-Type": "application/json"},
            json={
                "Subject": media.get("name") or "Speak AI call",
                "Description": f"{summary}

Transcript: https://app.speakai.co/media/{media_id}",
                "WhoId": contact["Id"] if contact else None,
                "Status": "Completed",
                "ActivityDate": media["createdAt"][:10],
                "Type": "Call",
                "CallDurationInSeconds": (media.get("duration") or {}).get("inSecond"),
                "TaskSubtype": "Call",
            },
        )
    return {"ok": True}

async def run_magic_prompt(media_id: str, prompt: str) -> str:
    """Fire Magic Prompt + poll until completed (~2-3s typical)."""
    headers = {"x-speakai-key": os.environ["SPEAK_API_KEY"], "Content-Type": "application/json"}
    async with httpx.AsyncClient(timeout=30) as c:
        await c.post("https://api.speakai.co/v1/prompt/", headers=headers, json={
            "mediaIds": [media_id], "prompt": prompt,
            "isStream": False, "isIndividualPrompt": True,
        })
        for _ in range(20):
            await asyncio.sleep(1)
            r = await c.get(
                "https://api.speakai.co/v1/prompt/messages",
                params={"mediaIds": media_id, "pageSize": 1},
                headers={"x-speakai-key": os.environ["SPEAK_API_KEY"]},
            )
            history = r.json().get("data", {}).get("history", [])
            msg = history[0]["messages"][0] if history and history[0].get("messages") else None
            if msg and msg.get("state") == "completed":
                return msg.get("answer", "")
    return ""  # timed out

For Events instead of Tasks, POST to /sobjects/Event/ and include StartDateTime and EndDateTime. Same OAuth flow either way.

Verified against production 2026-05-07. Speak fires a thin notification (eventType, state, mediaId only). Your middleware fetches full insights via GET /v1/media/insight/:mediaId, then posts to the destination CRM.

For RevOps and analytics teams · Salesforce REST PATCH

Push Speak insights to custom Opportunity fields

Magic Prompt extracts sentiment, intent, competitors, and topics. PATCH the matching Opportunity to write those values into custom fields. Salesforce reports and pipeline-velocity dashboards segment on real conversation data – no extra BI tooling.

PATCH the Opportunity with Speak-derived fields




# Custom fields created in Setup > Object Manager > Opportunity > Fields
# Speak_Last_Call_Sentiment__c (Picklist: Positive/Neutral/Negative)
# Speak_Last_Call_Topics__c (Long Text)
# Speak_Competitors_Mentioned__c (Long Text)

curl -X PATCH \
  "$INSTANCE_URL/services/data/v66.0/sobjects/Opportunity/006XX000005Lk0ZQAS" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Speak_Last_Call_Sentiment__c": "Positive",
    "Speak_Last_Call_Topics__c": "pricing, integrations, security",
    "Speak_Competitors_Mentioned__c": "Gong, Chorus"
  }'
async function pushInsightsToOpportunity(oppId, magicPrompt) {
  const { access_token, instance_url } = await getSalesforceToken();
  const r = await fetch(
    `${instance_url}/services/data/v66.0/sobjects/Opportunity/${oppId}`,
    {
      method: "PATCH",
      headers: {
        Authorization: `Bearer ${access_token}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        Speak_Last_Call_Sentiment__c: magicPrompt.sentiment,
        Speak_Last_Call_Topics__c: magicPrompt.topics.join(", "),
        Speak_Competitors_Mentioned__c: magicPrompt.competitors.join(", "),
      }),
    }
  );
  if (!r.ok && r.status !== 204) throw new Error(`SF PATCH failed: ${r.status}`);
}

Salesforce PATCH responds with 204 No Content on success. Pair this with a Salesforce Flow that auto-tasks the AE if Speak_Last_Call_Sentiment__c = 'Negative'.

For sales enablement and CS teams · Lightning Web Components

Show Speak summaries on the Opportunity record page

A Lightning Web Component renders on the Opportunity Lightning record page showing the latest Speak calls inline. Apex controller uses a Named Credential (callout:Speak_AI) so the API key never lives client-side. Drop the component on the page via App Builder.

Apex controller (server-side fetch)
// SpeakInsightsController.cls
public with sharing class SpeakInsightsController {
    @AuraEnabled(cacheable=true)
    public static String getInsights(String mediaId) {
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:Speak_AI/v1/media/insight/' + mediaId);
        req.setMethod('GET');
        HttpResponse res = http.send(req);
        return res.getBody();
    }
}
Lightning Web Component (front-end)
// speakInsightsPanel.js
import { LightningElement, api, wire } from 'lwc';
import getInsights from '@salesforce/apex/SpeakInsightsController.getInsights';

export default class SpeakInsightsPanel extends LightningElement {
    @api recordId;          // Opportunity Id passed by App Builder
    @api speakMediaId;      // resolved via custom field on Opportunity

    @wire(getInsights, { mediaId: '$speakMediaId' })
    insights;

    get summary() { return JSON.parse(this.insights?.data || '{}').summary; }
    get sentiment() { return JSON.parse(this.insights?.data || '{}').sentiment; }
    get topics() { return JSON.parse(this.insights?.data || '{}').topics; }
}

One-time admin setup: create the Speak_AI Named Credential pointing at https://api.speakai.co, add the x-speakai-key header, register api.speakai.co as a CSP Trusted Site.

For sales leaders and analysts · Natural language

Query Speak from Claude or ChatGPT, scoped to Salesforce

Connect Speak’s official MCP server to Claude or ChatGPT, tag Speak media with Salesforce record IDs (use case 1 already does this), and your team queries the entire Salesforce-linked call library through conversation.

1. Install the MCP server




# Claude Desktop / Claude Code (auto-detects your installation)
npx @speakai/mcp-server init

# Paste your Speak API key when prompted. Setup takes about 2 minutes.
# Claude.ai (web) and ChatGPT MCP connector
# Settings > Integrations > Add MCP Server
# Remote URL:    https://api.speakai.co/v1/mcp
# Auth header:   x-speakai-key: YOUR_SPEAK_API_KEY

# Verify the connection responds:
curl -s https://api.speakai.co/v1/mcp \
  -H "x-speakai-key: $SPEAK_API_KEY" \
  -H "Accept: application/json"

2. Example prompts your team can use today:

  • “Show me Salesforce Opportunities in Negotiation stage where the most recent Speak call sentiment dropped below neutral.”
  • “Which deals closed-lost this quarter had pricing as a top Speak topic on their last 2 calls?”
  • “Draft a follow-up email for Opportunity 006XX000005Lk0Z using the Magic Prompt summary from the last Speak recording.”
  • “Summarize the last 5 Speak calls tagged to Account Acme Corp and write the summary into the Account notes field.”
  • “Compare discovery completeness across our top 3 SDRs using Speak calls linked to closed-won Salesforce Opportunities from Q1.”

Pair Speak’s MCP server with a Salesforce MCP server (Salesforce announced an official one in 2026; community options exist now) and Claude joins across both. View MCP server →

Why Speak AI + Salesforce

Salesforce is your system of record. Speak is your conversation of record. The combination turns every call into native Salesforce data that Reports, Dashboards, and Flows act on without extra tooling.

Multi-source ingest, not just Salesforce calls

The same Speak workspace ingests Zoom, Teams, Meet, Webex, Twilio, file uploads, and embedded recorder submissions. Pipe everything into the matching Salesforce record so reps see one timeline, not five.

Custom Magic Prompts, not fixed Einstein reports

Score discovery completeness, extract competitor mentions, detect MEDDIC stage, surface objection patterns. Save prompts once and they run on every Salesforce-linked Speak call. Einstein Conversation Insights can coexist; Speak is the deeper layer.

MCP-native for Claude and ChatGPT

Speak’s official MCP server exposes 83 tools to AI assistants. Sales leaders query the Salesforce-linked call library in plain English instead of building dashboards or running SOQL.

Lower price floor than Sales Cloud add-ons

Einstein Conversation Insights and other Sales Cloud add-ons run thousands per seat per year. Speak ships with the same call analysis surface, plus multi-source ingest and shareable embeds, on Speak’s standard plans.

Teams trust Speak AI for their most important calls

★★★★★
4.9 on G2

“Speak AI has been instrumental in transforming how we handle qualitative data. The transcription accuracy is impressive, and the NLP insights save us hours of manual analysis.”

Research Director | Consulting Firm

“We switched from Otter.ai and the depth of analysis is on another level. Sentiment scoring, keyword extraction, and theme detection all happen automatically.”

Product Manager | SaaS Company

“The ability to search across all our customer calls and pull specific moments is a game-changer for our enterprise sales team.”

VP of Sales | Enterprise Tech

How to use Speak AI with Salesforce for call analysis and CRM intelligence

Salesforce is the system of record for sales, service, and account management at scale. Reps log activities. Sales leaders run forecasts from pipeline data. Service teams resolve cases against contact history. Every motion is sharper when the underlying calls are transcribed, analyzed, and structured into Salesforce-shaped data. Speak AI is the layer that does that.

Where Speak fits in the Salesforce activity lifecycle

Speak runs after the call ends. The Speak Meeting Assistant joins Zoom, Teams, Meet, and Webex calls, records the audio, transcribes in 100+ languages, and runs AI analysis. When analysis completes, Speak fires a media.analyzed webhook with the full payload. That webhook is the integration point for Salesforce – your middleware turns it into a Task, an Event, a custom field write, or all three.

Speak vs Einstein Conversation Insights

Einstein Conversation Insights ships fixed report templates and lives inside Sales Cloud at an enterprise price point. Speak ingests Salesforce-linked calls alongside Zoom, Teams, Meet, file uploads, podcasts, and embed recorder submissions, then runs custom analysis (your Magic Prompts, your tags, your team’s vocabulary), exposes everything via MCP for Claude and ChatGPT, and ships shareable embeds. Many customers run both: Einstein for native call control, Speak for the deeper analysis layer and multi-source ingest.

How do I push call transcripts to Salesforce?

Three production paths, ranked by lift:

  • Webhook + REST API. 40-line middleware. Speak fires media.analyzed, your middleware exchanges Connected App credentials for a token and POSTs to the Task or Event endpoint. Highest control, lowest cost.
  • Make.com or n8n. Visual workflow builder with native Salesforce + Speak modules. Handles OAuth refresh automatically. No infrastructure to host.
  • Lightning Web Component. React-style component on the Opportunity record page. Higher implementation cost, highest agent productivity payoff.

Note on Zapier and Salesforce

Speak’s Zapier app does not currently list Salesforce as a paired app. The supported low-code paths for Speak + Salesforce are Make.com and n8n, both of which have native modules for Speak and for Salesforce. You can also use Zapier’s HTTP Request action against Speak’s REST API, but it requires more configuration than the paired pattern.

Use cases by role

Sales and RevOps teams use Speak AI with Salesforce to auto-log every meeting and call as a Salesforce Task or Event on the matching Contact and Opportunity. Magic Prompts score discovery completeness, extract objections, and surface competitor mentions. See Speak AI for sales teams.

Sales enablement and training teams turn the Lightning record page into a coaching loop. Speak’s analysis surfaces missed discovery questions, scripted-line drift, and sentiment dips inline on the Opportunity. See Speak AI for training and development.

Consulting firms log every client meeting into Salesforce as a structured engagement with summary, sentiment, and the Speak deep link. See Speak AI for consulting firms.

Frequently asked questions

Does Speak AI’s Zapier app integrate with Salesforce?

Speak’s Zapier app does not currently list Salesforce as a paired app. The supported low-code paths are Make.com and n8n, both with native Speak and Salesforce modules. For pure REST integration, the Webhook + REST API recipe above ships in an afternoon and is the canonical production path.

Which Salesforce edition do I need?

The REST API integration requires Enterprise Edition or higher. Professional Edition needs a paid API add-on. Lightning Web Components require any edition that supports Lightning Experience. Setting up a Connected App for OAuth is admin-only across all editions.

How do I match a Speak call to the right Salesforce Contact?

The cleanest path is to resolve by attendee email. Speak’s Meeting Assistant captures attendee emails on join, which your middleware can match to Salesforce Contacts via SOQL. Alternative: tag the Speak media with a Salesforce record ID upfront via your Calendar integration.

Can Speak update custom fields on Opportunity?

Yes. Create custom fields like Speak_Last_Call_Sentiment__c in Setup > Object Manager > Opportunity > Fields, then PATCH the Opportunity record with the Speak Magic Prompt response. Once data lives in custom fields, Salesforce Reports, Dashboards, and Flows can act on it natively.

What languages are supported?

Speak supports transcription in 100+ languages including English, Spanish, French, German, Portuguese, Italian, Dutch, Hebrew, Norwegian, Japanese, Arabic, Hindi, and dozens more. Set the source language with the sourceLanguage field on upload, or let Speak detect it automatically.

Can I try Speak AI for free with my Salesforce account?

Yes. The 7-day trial includes 30 minutes of transcription, full API access, and the MCP server. No credit card required. Set up the recording webhook against a Salesforce sandbox org and validate the full pipeline before committing.

Start using Speak AI with Salesforce today

83 analysis tools. 100+ languages. Production webhook + REST API. Lightning Web Component. MCP-native for Claude and ChatGPT.

Try Speak AI free

Create your account, grab your API key, and wire up your Salesforce Connected App. Full access for 7 days. No credit card required.

View the API docs

Full reference for the upload endpoint, webhook event types, and Magic Prompt API. Plus the official Speak MCP server on NPM.