Semarize

Get Your Data

Salesloft - How to Get Your Conversation Data

A practical guide to getting your conversation data out of Salesloft - covering OAuth authentication, conversation listing, sentence-level transcripts, recording downloads, webhook-triggered flows, and how to route structured data into your downstream systems.

What you'll learn

  • What conversation data you can extract from Salesloft - transcripts, sentence-level data, speaker labels, timestamps, and recordings
  • How to access data via the Salesloft API - OAuth authentication, key endpoints, and pagination
  • Two extraction patterns: batch polling and webhook-triggered processing
  • How to connect Salesloft data pipelines to Zapier, n8n, and Make
  • Advanced use cases - cadence compliance, multi-channel scoring, rep benchmarking, and pipeline intelligence

Data

What Data You Can Extract From Salesloft

Salesloft Conversations captures more than just the recording. Every conversation produces a set of structured assets that can be extracted via API - the full transcript, sentence-level utterances with speaker attribution, timing metadata, and the recording file itself.

Common fields teams care about

Full transcript text
Sentence-level utterances with timestamps
Speaker labels (rep vs. prospect)
Conversation owner / rep name
Conversation date, time, and duration
Participant list and roles
Recording file (audio/video)
Associated CRM opportunity data
Cadence and step context
Conversation disposition and outcome

API Access

How to Get Transcripts via the Salesloft API

Salesloft exposes conversations and transcripts through a REST API. The workflow is: authenticate via OAuth, list conversations, then fetch the transcription and sentence-level data for each conversation ID.

1

Authenticate with OAuth 2.0

Salesloft uses OAuth 2.0 for API authentication. Register an application in the Salesloft Developer Portal to get your client_id and client_secret. Complete the authorization flow to obtain an access token and refresh token.

POST https://accounts.salesloft.com/oauth/token

{
  "grant_type": "authorization_code",
  "client_id": "<your_client_id>",
  "client_secret": "<your_client_secret>",
  "code": "<authorization_code>",
  "redirect_uri": "<your_redirect_uri>"
}

// Response includes access_token and refresh_token
Authorization: Bearer <access_token>
Access tokens are short-lived. Your integration must handle automatic token refresh using the refresh_token before the access token expires. Store tokens securely and never expose them client-side.
2

List conversations

Call the GET /v2/conversations endpoint to list recorded conversations. Results are paginated - each response includes pagination metadata to fetch the next page.

GET https://api.salesloft.com/v2/conversations?per_page=25&page=1

// Response:
{
  "data": [
    {
      "id": 12345,
      "title": "Discovery Call - Acme Corp",
      "created_at": "2025-01-15T14:30:00Z",
      "duration": 1847,
      "participants": [...]
    }
  ],
  "metadata": {
    "paging": { "per_page": 25, "current_page": 1, "next_page": 2 }
  }
}

The response returns an array of conversation objects with id, title, created_at, duration, and participant data. Keep paginating until next_page is null.

3

Fetch the transcription

For each conversation ID, fetch the transcript via GET /v2/conversations/:id/transcription. For sentence-level detail with speaker attribution and timestamps, use GET /v2/conversations/:id/transcription/sentences.

// Full transcription
GET https://api.salesloft.com/v2/conversations/12345/transcription

// Sentence-level data
GET https://api.salesloft.com/v2/conversations/12345/transcription/sentences

// Sentence response:
{
  "data": [
    {
      "speaker": "Rep (Jane Smith)",
      "start_time": 0.5,
      "end_time": 4.2,
      "text": "Thanks for joining the call today."
    },
    {
      "speaker": "Prospect (John Doe)",
      "start_time": 4.5,
      "end_time": 9.1,
      "text": "Happy to be here. We've been looking at..."
    }
  ]
}

Each sentence includes speaker, start_time, end_time, and text. Reassemble into plain text by concatenating sentences, or preserve the structured format for per-speaker analysis. Use the GET /v2/conversations/:id/media endpoint to download the actual recording file.

4

Handle rate limits and transcript availability

Rate limits

Salesloft enforces rate limits of approximately 600 requests per minute. When you receive a 429 response, check the X-RateLimit-Reset header for when to retry. For bulk operations, pace requests to stay within limits and persist pagination state between runs.

Transcript timing

Transcripts are not available the instant a conversation ends. Salesloft processes recordings asynchronously - typical lag ranges from minutes to an hour depending on call length and system load. Use webhooks to be notified when transcription is complete, or build a retry with exponential backoff for recently completed conversations.

Patterns

Key Extraction Flows

There are two practical patterns for getting transcripts out of Salesloft. The right choice depends on whether you're doing a batch export or need near real-time processing as conversations complete.

Batch Polling (Historical + Incremental)

Scheduled extraction of past and new conversations

1

Set a cron job or scheduled trigger (hourly, daily, etc.) that runs your extraction script. For a one-off backfill, run it once across your full conversation history

2

Call GET /v2/conversations with pagination parameters. Filter by date range or paginate through the full result set to collect all conversation IDs

3

For each conversation ID, fetch the transcription via GET /v2/conversations/:id/transcription/sentences for sentence-level data with speaker attribution

4

Store each transcript with its conversation metadata (conversation ID, date, participants, duration) in your data warehouse or object store

5

Route the stored data to your analysis pipeline - Semarize for structured scoring, your CRM for enrichment, or your BI tool for reporting

6

Update your stored cursor / last-processed timestamp for the next polling cycle. Use conversation IDs as deduplication keys to avoid reprocessing

Tip: Persist your pagination page number or last-processed conversation ID between runs. If the process is interrupted, you can resume from where you left off instead of re-scanning from the start.

Webhook-Triggered

Near real-time on conversation completion

1

Register a webhook subscription in Salesloft for conversation and transcription events. Salesloft fires events when a recording is processed and the transcript becomes available

2

When the webhook fires, parse the event payload to extract the conversation ID and metadata

3

Fetch the sentence-level transcription via GET /v2/conversations/:id/transcription/sentences using the conversation ID from the event

4

Route the transcript and metadata downstream - to Semarize for structured analysis, your CRM for enrichment, or your automation platform for further processing

Note: Salesloft webhooks support events for recordings and transcripts. Run a periodic polling job alongside webhooks as a safety net - webhook delivery is not guaranteed, and a missed event means a missed conversation.

Automation

Send Salesloft Transcripts to Automation Tools

Once you can extract transcripts from Salesloft, the next step is routing them through Semarize for structured analysis and into your downstream systems. Below are end-to-end example flows - each showing the full pipeline from Salesloft trigger through Semarize evaluation to CRM, Slack, or database output.

ZapierNo-code automation

Salesloft → Zapier → Semarize → CRM

Detect new Salesloft conversations on a schedule, fetch the transcript, send it to Semarize for structured analysis, then write the scored output - signals, flags, and evidence - directly to your CRM.

Example Zap
Trigger: Schedule
Polls for new conversations every hour
App: Schedule by Zapier
Event: Every Hour
Output: triggers workflow
Webhooks by Zapier
List new conversations from Salesloft
Method: GET
URL: https://api.salesloft.com/v2/conversations
Auth: Bearer (OAuth token)
Params: per_page=25&page=1
For each conversation
Webhooks by Zapier
Fetch sentence-level transcript
Method: GET
URL: .../conversations/{{id}}/transcription/sentences
Auth: Bearer (OAuth token)
Transcript returned
Webhooks by Zapier
POST /v1/runs (sync) to Semarize
Method: POST
URL: https://api.semarize.com/v1/runs
Auth: Bearer smz_live_...
Body: { kit_code, mode: "sync", input: { transcript } }
Structured output returned
Formatter by Zapier
Extract brick values from Semarize response
Extract: bricks.overall_score.value
Extract: bricks.risk_flag.value
Extract: bricks.talk_ratio.value
Salesforce - Update Record
Write scored signals to Opportunity
Object: Opportunity
AI Score: {{overall_score}}
Risk Flag: {{risk_flag}}
Talk Ratio: {{talk_ratio}}

Setup steps

1

Create a new Zap. Choose "Schedule by Zapier" as the trigger and set it to run every hour. This will poll for new conversations on each run.

2

Add a "Webhooks by Zapier" Action (Custom Request) to list conversations from Salesloft. Set method to GET, URL to https://api.salesloft.com/v2/conversations, and add your OAuth Bearer token in the Authorization header.

3

Add a Looping by Zapier step to iterate through each conversation. For each, add another Webhooks action to fetch the transcript via GET /v2/conversations/:id/transcription/sentences.

4

Add a "Webhooks by Zapier" Action to send the transcript to Semarize. Set method to POST, URL to https://api.semarize.com/v1/runs. Add your Semarize API key as a Bearer token. In the body, set kit_code to your Kit, mode to "sync", and map the reassembled transcript text into input.transcript.

5

Add a Formatter step to extract individual brick values from the Semarize JSON response - overall_score, risk_flag, talk_ratio, etc.

6

Add a Salesforce (or HubSpot, Sheets, etc.) Action to write the extracted scores and signals to your CRM record. Test each step end-to-end, then turn on the Zap.

Watch out for: Zapier has step data size limits that can truncate very long transcripts. For calls over 60 minutes, consider storing the transcript in cloud storage and passing a reference URL instead of inline text. Use mode: "sync" so Semarize returns results inline - Zapier doesn't natively support polling loops.
Learn more about Zapier automation
n8nSelf-hosted workflows

Salesloft → n8n → Semarize → Database

Poll Salesloft for new conversations on a schedule, fetch sentence-level transcripts, send each one to Semarize for analysis, then write the structured scores and signals to your database. n8n's native loop support handles pagination and batch processing.

Example Workflow
Cron - Every Hour
Triggers the workflow on schedule
Mode: Every Hour
Timezone: UTC
HTTP Request - List Conversations
GET /v2/conversations (Salesloft)
Method: GET
URL: https://api.salesloft.com/v2/conversations
Auth: Bearer (OAuth token)
Params: per_page=25
For each conversation
HTTP Request - Fetch Sentences
GET .../transcription/sentences
URL: .../conversations/{{$json.id}}/transcription/sentences
Code - Reassemble Transcript
Concatenate sentences into plain text
Join: sentences by speaker + text
HTTP Request - Semarize
POST /v1/runs (sync)
URL: https://api.semarize.com/v1/runs
Auth: Bearer smz_live_...
Body: { kit_code, mode: "sync", input: { transcript } }
Scores & signals returned
Postgres - Insert Row
Write structured output to database
Table: call_evaluations
Columns: conversation_id, score, risk_flag, talk_ratio

Setup steps

1

Add a Cron node as the workflow trigger. Set the interval to your desired polling frequency (hourly works well for most teams).

2

Add an HTTP Request node to list new conversations from Salesloft. Set method to GET, URL to https://api.salesloft.com/v2/conversations, configure OAuth Bearer auth, and paginate through results.

3

Add a Split In Batches node to iterate over the returned conversation IDs. Inside the loop, add an HTTP Request node to fetch each transcript via GET /v2/conversations/:id/transcription/sentences.

4

Add a Code node (JavaScript) to reassemble the sentences array into a single transcript string. Join each sentence's text, prefixed by speaker name.

5

Add another HTTP Request node to send the transcript to Semarize. Set method to POST, URL to https://api.semarize.com/v1/runs. Add your API key as a Bearer token. Set kit_code, mode to "sync", and map the transcript into input.transcript.

6

Add a Code node to extract the brick values from the Semarize response - overall_score, risk_flag, talk_ratio, evidence, confidence.

7

Add a Postgres (or MySQL / HTTP Request) node to write the structured output. Use conversation_id as the primary key for upserts.

8

Activate the workflow. Monitor the first few runs to verify Semarize responses are arriving and writing correctly.

Watch out for: Use conversation IDs as deduplication keys to prevent reprocessing. You can also use async mode with n8n's native loop - POST /v1/runs (default async), then poll GET /v1/runs/:runId with a Wait + IF loop until status is "succeeded".
Learn more about n8n automation
MakeVisual automation with branching

Salesloft → Make → Semarize → CRM + Slack

Fetch new Salesloft conversation transcripts on a schedule, send each to Semarize for structured analysis, then use a Router to branch the scored output - alert on risk flags via Slack and write all signals to your CRM.

Example Scenario
Schedule - Every 30 min
Triggers the scenario on interval
Interval: 30 minutes
HTTP - List Conversations
GET /v2/conversations (Salesloft)
Method: GET
Auth: Bearer (OAuth token)
URL: https://api.salesloft.com/v2/conversations
HTTP - Fetch Sentences
GET .../transcription/sentences (per conversation)
Iterator: for each conversation in response
URL: .../conversations/{{item.id}}/transcription/sentences
HTTP - Semarize
POST /v1/runs (sync)
URL: https://api.semarize.com/v1/runs
Auth: Bearer smz_live_...
Body: { kit_code, mode: "sync", input: { transcript } }
Structured output
Router - Branch on Risk Flag
Route by Semarize output
Branch 1: IF risk_flag.value = true
Branch 2: ALL (fallthrough)
Branch 1 - Risk detected
Slack - Alert Channel
Notify team about flagged conversation
Channel: #deal-alerts
Message: Risk on {{conversation_id}}, score: {{score}}
Branch 2 - All conversations
Salesforce - Update Record
Write all scored signals to Opportunity
AI Score: {{overall_score}}
Risk Flag: {{risk_flag}}
Talk Ratio: {{talk_ratio}}

Setup steps

1

Create a new Scenario. Add a Schedule module as the trigger, set to your desired interval (15-60 minutes is typical).

2

Add an HTTP module to list new conversations from Salesloft. Set method to GET, URL to https://api.salesloft.com/v2/conversations, configure OAuth Bearer auth, and paginate through results.

3

Add an Iterator module to loop through each conversation. For each, add an HTTP module to fetch the transcript via GET /v2/conversations/:id/transcription/sentences.

4

Add a Text Aggregator or JSON module to reassemble the sentence array into a single transcript string, joining speaker names with their text.

5

Add another HTTP module to send the transcript to Semarize. Set URL to https://api.semarize.com/v1/runs, add your Bearer token, and set kit_code, mode to "sync", and input.transcript from the previous step. Parse the response as JSON.

6

Add a Router module. Define Branch 1 with a filter: bricks.risk_flag.value equals true. Leave Branch 2 as a fallthrough (no filter).

7

On Branch 1, add a Slack module to alert your team when risk is detected. Map the score, risk flag, and conversation ID into the message.

8

On Branch 2, add a Salesforce module to write all brick values (score, risk_flag, talk_ratio) to the Opportunity record. Set the scenario schedule and activate.

Watch out for: Each API call counts as an operation. A scenario processing 50 conversations uses ~150 operations (list + transcript + Semarize per conversation). Use mode: "sync" to avoid needing a polling loop for each run.
Learn more about Make automation

What you can build

What You Can Do With Salesloft Data in Semarize

Semarize powers cadence compliance auditing, multi-channel scoring, rep benchmarking with custom frameworks, and the ability to build your own tools on structured conversation signals from Salesloft.

Knowledge-Grounded Feature Claim Verification

Product Accuracy Scoring

What Semarize generates

feature_claim_accurate = falsepricing_reference_correct = trueintegration_overstated = trueknowledge_gap_area = "api_limits"

Your sales pitch deck changed last quarter, but are reps saying the right things on calls? Run a knowledge-grounded kit against your product documentation on every Conversations recording. Semarize verifies each feature claim, integration capability statement, and pricing reference against the source of truth. After 200 calls, the data shows reps consistently overstate API rate limits and misquote the enterprise tier’s SSO configuration. Product marketing gets a weekly accuracy report — messaging corrections happen within days, not after the next QBR.

Learn more about QA & Compliance
Cadence Step Quality AuditCadence: Enterprise Outbound v3
Step 1Intro Email
Quality:81
Clean
Step 2Discovery Call
Quality:74
1 violations
Step 3Value Email
Quality:69
Clean
Step 4Pricing Call
Quality:42
7 violations
Step 5Follow-up
Quality:77
Clean
Step 4 (Pricing Call): 38% violation rate on competitor pricing leaks — talk track rewrite recommended

Structured Qualification Signal Pipeline

Typed Conversation Data for BI

What Semarize generates

budget_confirmed = truedecision_maker_present = truepain_severity = 0.82output_format = "typed_sql_row"

Every call produces insights, but those insights are locked in recordings and summaries. Run every Conversations transcript through Semarize and land typed rows in your warehouse: budget_confirmed (bool), decision_maker_present (bool), pain_severity (float), competitive_pressure (float), timeline_urgency (varchar). Your BI team joins conversation signals with CRM pipeline data in dbt. For the first time, you can answer “which qualification signals predict won deals from which sequences?” with a SQL query instead of watching 50 recordings.

Learn more about Data Science
Cadence Quality Comparison377 calls scored
CadenceCallsBuying Sig.Pain Spec.Discovery
Enterprise Outbound1420.510.7264
Mid-Market980.630.5859
Inbound Follow-up760.690.4755
Event Follow-up610.780.5471
Event Follow-up produces 2.3x stronger buying signals than cold outbound
Cold outbound has 40% higher pain specificity — adjust event messaging

Custom Methodology A/B Testing

Data-Driven Framework Selection

What Semarize generates

framework_a_score = 71framework_b_score = 64win_correlation_a = 0.73segment_winner = "custom_midmarket"

Your team is debating whether MEDDICC or your custom qualification framework better predicts closed-won outcomes. Instead of arguing, run both as separate Semarize kits against the same 400 calls. Every call gets scored twice — once with each framework. After correlating scores against actual outcomes in your warehouse, the data shows your custom framework correlates 35% more strongly with wins in mid-market — but MEDDICC scores better on enterprise deals. You deploy both: custom for mid-market, MEDDICC for enterprise. The methodology debate is resolved with data, not opinions.

Learn more about Sales Coaching
New Rep Ramp Tracker - Week 1–12Benchmark: objection_handling ≥ 65 by week 6
Rep AON TRACK
Wk 6: 65
Wk 1Wk 6Wk 12
Rep BNEEDS INTERVENTION
Wk 6: 53
Wk 1Wk 6Wk 12
Rep CNEEDS INTERVENTION
Wk 6: 56
Wk 1Wk 6Wk 12
2 reps below curve at week 5 — pair with senior mentors before week 6 checkpoint

Conversation-Powered Territory Planning

Regional Intelligence from Call Signals

Vibe-coded

What Semarize generates

territory_discovery_avg = 68competitive_mention_rate = 3.1xpricing_hesitation_rate = 0.22territory = "northeast"

A revenue strategist vibe-codes a Streamlit app that pulls Semarize scores from every Salesloft Conversations call and joins them with territory data from the CRM. The app shows conversation quality by territory: which regions produce the highest discovery_depth scores, where competitive mentions spike, and which territories have the most pricing_hesitation. It surfaces that the Northeast territory has 3x the competitive mention rate of the West — suggesting a regional competitor is more active there. Territory plans get adjusted: reps in the Northeast get competitive battle cards, and the win rate in that territory improves 14% the next quarter.

Learn more about RevOps
Territory Intelligence DashboardVibe-coded with Streamlit
TerritoryDiscoveryComp. RatePrice Hes.Risk
Northeast723.1x0.34HIGH
Southeast681.4x0.18MEDIUM
West741.0x0.12LOW
Central611.8x0.22MEDIUM
Recommendation: Northeast Territory
Competitive mention rate is 3.1x higher than West. Deploy competitive battle cards to reps — projected +14% win rate improvement.

Watch out for

Common Challenges & Gotchas

These are the issues that come up most often when teams start extracting transcripts from Salesloft at scale.

OAuth token refresh management

Salesloft uses OAuth 2.0 with short-lived access tokens. Your integration must handle token refresh automatically - if your refresh token expires or is revoked, the entire pipeline stops. Store tokens securely and implement automatic refresh logic before tokens expire.

Transcript processing delay

Salesloft processes recordings asynchronously after a call ends. Attempting to fetch a transcription too soon will return empty or incomplete data. Build in a retry mechanism with exponential backoff, or rely on webhooks to know when transcription is ready.

Sentence-level vs. full transcript endpoints

Salesloft separates transcription data across two endpoints: Fetch Transcription (full text) and Fetch Transcription Sentences (sentence-level with speakers and timestamps). Depending on your use case, you may need to call both or choose carefully - the sentence endpoint gives richer data but requires reassembly for full-text analysis.

API rate limits during backfills

At 600 requests per minute, a historical backfill of thousands of conversations can take considerable time. Each conversation requires at least two API calls (list + transcription). Implement pacing, respect rate limit headers, and persist your pagination cursor between batches.

Conversation vs. recording vs. transcription IDs

Salesloft uses separate IDs for conversations, recordings, and transcriptions. Mapping between them requires careful ID tracking. A conversation may not always have a transcription (if processing failed or the feature is disabled), so validate each step before proceeding.

Webhook delivery reliability

Salesloft webhooks can occasionally miss deliveries or deliver duplicates. Implement idempotency checks using conversation IDs as deduplication keys, and consider running a periodic polling job as a safety net alongside webhook-triggered processing.

FAQ

Frequently Asked Questions

Explore

Explore Semarize