If you sell a calling, dialer or contact center product, build new Salesforce CTI work on Salesforce Voice with Partner Telephony when you run the live call, and on plain Task or VoiceCall writes through REST API when you only log calls after they end. Open CTI, the softphone framework most existing integrations use, "is in maintenance mode and is scheduled for retirement in February 2028," per Salesforce's Open CTI migration guide.
For a SaaS company this is a product decision before it is an API choice. The route decides which record your customers report on, which licence they need before your integration works, what ships in your managed package, and how much of each customer's daily API allocation your sync spends. Appnigma works with B2B SaaS teams on these customer-facing integrations. Our done for you delivery builds and maintains them, and our marketplace apps work ships the native app when the integration has to live inside Salesforce. If you are an admin looking for the Log a Call button, Salesforce Help covers that, and this page is about the vendor side.
Updated October 2026. Checked against the Open CTI Developer Guide, the Salesforce Voice with Partner Telephony Developer Guide, the Object Reference and the REST API Developer Guide. The earlier version listed the Streaming API as a current choice, never mentioned Open CTI, Salesforce Voice or the VoiceCall object, and described Appnigma in terms the company no longer uses. This update adds the 2028 timeline, the Task versus VoiceCall decision, the per-org API cost of a call sync, and what goes in your package.
Three ways a calling product connects to Salesforce
Salesforce documents three models, and they differ in who owns the call inside the Salesforce UI.
| Open CTI | Salesforce Voice with Partner Telephony | Data APIs only | |
|---|---|---|---|
| What you build | A softphone adapter in an iframe that calls opencti JavaScript methods | A connector and contact center in a second-generation managed package | A server-side sync from your platform into the customer's org |
| Who owns the rep's call state | Your adapter | Salesforce, through Omni-Channel | Your own app, outside Salesforce |
| Record for each call | Task, usually created with saveLog | VoiceCall, linked to a Task | Task, or VoiceCall where the customer has the permissions |
| Customer licence | None beyond Salesforce CRM Call Center | Salesforce Voice add-on | None beyond API access |
| Status | Maintenance mode, retiring February 2028 | Salesforce's recommended path | Current |
Salesforce's own comparison puts it plainly. "Open CTI is a thin bridge," and with Partner Telephony "Salesforce owns the rep lifecycle through Omni-Channel," per Compare the Conceptual Models of Open CTI and Salesforce Voice with Partner Telephony. Partner Telephony is sold to the customer "as an add-on license," per the Partner Telephony Developer Guide. It runs on Performance, Enterprise, Unlimited and Developer editions. The same guide notes that "Service Cloud Voice is now Salesforce Voice," so older pages and AI answers that say Service Cloud Voice mean the same product.
The data API route is the one most competitor pages skip. A sales dialer that logs activity, a call recording vendor, or a conversation analytics product doesn't need a softphone inside Salesforce at all. It needs a reliable write of each finished call into the right record.
When does Open CTI retire, and what changes if you already ship it?
Open CTI still works in existing orgs, and Salesforce is adding nothing to it. The migration guide says "no new features or enhancements are being added to Open CTI" and that it is "deprecated and unavailable for newly created Agentforce Service orgs." Trailhead gives the exact dates. Open CTI became unavailable for new Agentforce Service orgs on February 16, 2026. "On February 28, 2028, it will retire entirely," per the Prepare for Open CTI Retirement unit.
The sales impact arrives before the technical one. Any prospect that set up a new Agentforce Service org this year can't install an Open CTI softphone, so your existing integration loses those deals now, not in 2028. Customers on older orgs keep working until the retirement date, and their admins will start asking for your migration plan during renewals.
Salesforce publishes a migration path for exactly this case. The guide is written "for partners and independent software vendors migrating an existing Open CTI (Lightning) package" to a Partner Telephony connector, and it recommends starting from the demo connector instead of building from scratch. Expect three pieces of work. You replace adapter logic with connector methods, move call records from Task to VoiceCall, and rebuild screen pops. Open CTI's searchAndScreenPop maps to "Omni-Channel Flow (Get Records + Screen Pop action) or LWC + Navigation API," per the conceptual comparison.
Reporting is the part customers notice. Their call dashboards run on Task today, and after migration the canonical record is VoiceCall. Plan the report and field mapping with them, and keep writing a linked Task if their activity timelines depend on it.
Task or VoiceCall for each call
Task works in every org your product can reach, and VoiceCall carries more call detail but needs permissions many customers don't have.
The Task object has a small set of call fields. CallDurationInSeconds holds the "duration of the call in seconds," per the Task object reference. CallType takes Inbound, Internal or Outbound. CallDisposition holds the result and CallObject names the call center. These fields are "not subject to field-level security, available for any user in an organization with Salesforce CRM Call Center." Set TaskSubtype to Call on insert, because "this field can't be updated" later.
VoiceCall "represents a call in Salesforce Voice, Sales Dialer, or other supported voice connectors," per the VoiceCall object reference. It has start and end times and a VendorCallKey for your call ID. It also links to a recording and, through ActivityId, to a Task, with room for 300 custom fields. The catch is access. "To edit voice call records, Sales Dialer or Salesforce Voice permissions are required." If your customer's integration user doesn't hold those permission sets, a VoiceCall write fails in that org.
For a vendor selling across many customer orgs, that gives a simple rule. Write Task by default, because it works with any licence. Write VoiceCall, linked to the Task, when you ship through Partner Telephony or the customer runs Sales Dialer or Salesforce Voice. Put your own call ID in an indexed custom field on whichever record you write, so a retry finds the existing record instead of creating a second one.
What a call sync costs each customer org in API requests
Every write your sync makes spends the customer's API allocation, the same pool their other tools draw on. An Enterprise org gets 100,000 requests per rolling 24 hours plus 1,000 per Salesforce licence, per API Request Limits and Allocations. Moving the logic into an Apex REST endpoint doesn't avoid this, because "calls to Apex REST classes count against the organization's API governor limits," per Introduction to Apex REST.
Here is a worked example from those documented limits, not a measured customer. An Enterprise org with 50 Salesforce licences has 150,000 requests a day. Its 50 reps each make 80 calls a day, which is 4,000 calls. A sync that looks up the contact by phone, creates a Task when the call starts and updates it at wrap-up spends three requests per call. That is 12,000 requests, 8% of the org's daily allocation. The customer's marketing, billing and support tools still need the rest.
Batching changes the number a lot. sObject Collections can "upsert up to 200 records based on an external ID field" in one request, per Upsert Records Using sObject Collections. Writing finished calls once, in batches of 200, takes the 4,000 Tasks down to 20 requests. A Composite request also "counts as a single call toward your API limits," per Send Multiple Requests Using Composite, while a Composite Batch request is different because "each subrequest counts against rate limits," per Composite Batch.
The trade is latency. A per-call write shows the call on the record within seconds. A batch every minute or two is still real time to a sales manager reading a dashboard, and it costs a fraction of the allocation. Most teams write the in-progress call once for the screen pop, then batch everything that happens after hang-up.
A batch write of finished calls looks like this. CallCenterCallId__c stands for an External ID custom field your package adds to Activity.
PATCH /services/data/v68.0/composite/sobjects/Task/CallCenterCallId__c
Authorization: Bearer <access token for this customer org>
Content-Type: application/json
{
"allOrNone": false,
"records": [
{
"attributes": { "type": "Task" },
"CallCenterCallId__c": "call_8841207",
"Subject": "Outbound call",
"TaskSubtype": "Call",
"CallType": "Outbound",
"CallDurationInSeconds": 312,
"CallDisposition": "Connected, demo booked",
"Status": "Completed",
"WhoId": "003XXXXXXXXXXXXXXX"
}
]
}With allOrNone set to false, one bad row, such as a deleted contact, doesn't roll back the other 199. Your sync reads the per-row results and retries only the failures.
Real time inside Salesforce, from events to recordings
Platform events are useful when Salesforce automation has to react to a call, such as a flow that updates an opportunity when a demo is booked. They don't save API requests on the way in. Salesforce says "daily API request allocations are consumed if you publish events with REST API, SOAP API, or Bulk API," per Default Platform Event Allocations. Delivery is "at-least-once," per the platform event considerations, so the subscriber has to ignore an event it already processed. For which event type fits which job, see our comparison of platform events and Change Data Capture.
The old Streaming API isn't the way to send changes back out to your product. PushTopic events are documented as legacy, per PushTopic Events (Legacy), and Change Data Capture through Pub/Sub API is the documented replacement.
Matching an incoming number to a person is a search problem. SOSL's PHONE FIELDS group searches "only phone number fields," per SOSL IN SearchGroup, which covers formatted numbers better than an exact-match query. Cache the result per number, since the same few numbers call a support line all day.
Recordings are where storage and permissions meet. A file upload to ContentVersion can be up to 2 GB, per Insert or Update Blob Data, and VoiceCallRecording files count "toward your org's file storage quota," per the VoiceCallRecording reference. Partner Telephony lets you keep audio on your side instead. You set a recordingLocation URL on the VoiceCall, "capped at 1,000 characters." The customer adds your domain as a Trusted URL, per Call Recordings. Keeping recordings in your platform also keeps the customer's storage bill out of your sales conversation.
If your customers own Salesforce's Conversation Intelligence (formerly Einstein Conversation Insights), you can make your calls analysable there without Partner Telephony. The Connect REST Voice Calls resource takes a "list of up to 200 voice calls," and the audio upload resource accepts a recordingURL for audio on your system. Trailhead lists a 64 MB recording limit and a 10 second minimum call length in its Conversation Intelligence requirements unit.
What ships in your package and what each customer sets up
A Partner Telephony integration ships as a second-generation managed package. It holds your connector and contact center together with settings metadata, per Create a Salesforce Voice Package. Customers "can install the managed package from the App Exchange or from an external URL provided by the telephony partner," per Set Up Your Service Org. You create the VoiceCall record through the Telephony Integration REST API, authenticated with a JWT. Salesforce says to "only use this API in real time," when the call starts, per Create a Voice Call Record.
A data API integration ships less, but it still benefits from a package. The package holds your External ID field on Activity, any custom fields for recording links or scores, a permission set for the integration user, and the external client app your OAuth flow uses. Without it, each customer's admin creates those fields by hand and names them slightly differently, and your field mapping breaks one org at a time. For the OAuth side of connecting one product to hundreds of orgs, see our guide to the secure connector setup for SaaS apps, and for the user your sync runs as, our post on the Salesforce integration user.
Each customer still has steps only they can take. They buy the Salesforce Voice add-on for Partner Telephony, assign the permission sets, add your domain as a Trusted URL for recordings, and approve your OAuth connection. Put those in your install guide and your sales qualification, because a customer without the Voice licence can only use your data API integration.
Running this across a customer base is mostly an operations job. Appnigma's integration infrastructure is built for that, and lets you "monitor each customer's connections, identify issues, and move fixes through the same review and release process."
Mistakes that show up after customers install
- Building a new Open CTI softphone in 2026, then losing every prospect on a new Agentforce Service org.
- Writing VoiceCall records without checking the integration user's permissions, so calls silently fail to log in orgs without Sales Dialer or Salesforce Voice.
- Creating a Task per call with no call ID field, so a retry after a timeout logs the same call twice.
- Trying to change TaskSubtype after insert, which Salesforce doesn't allow.
- Making three API requests per call in real time and pushing a large customer close to its daily allocation.
- Uploading every recording as a file and growing the customer's storage bill, when a recording URL would do.
- Moving the endpoint to Apex REST to save API requests, which it doesn't.
- Using Composite Batch and expecting it to count as one call.
Frequently Asked Questions
Is Salesforce Open CTI being retired?
Yes. Open CTI is in maintenance mode and retires on February 28, 2028. It has been unavailable for newly created Agentforce Service orgs since February 16, 2026.
What replaces Open CTI?
Salesforce recommends Salesforce Voice with Partner Telephony, formerly Service Cloud Voice. The vendor ships a connector in a managed package, and the customer needs the Salesforce Voice add-on licence.
Should call logs go in Task or VoiceCall?
Task works in every org and has duration, type and result fields. VoiceCall holds more call detail but editing it needs Sales Dialer or Salesforce Voice permissions, so most vendors write Task and add a linked VoiceCall where the customer has them.
Do call logging API calls count against Salesforce limits?
Yes. REST, Apex REST and platform events published over REST all spend the customer's daily API allocation. Batching up to 200 records per sObject Collections request keeps a call sync to a small share of it.
Can Appnigma build our Salesforce CTI integration?
Yes. Appnigma's done for you delivery builds and maintains customer-facing integrations with a named integration engineer, and marketplace apps covers the managed package when your integration has to live inside Salesforce.
Related Articles
- Platform Events vs Change Data Capture in Salesforce
- Salesforce API Rate Limits
- Salesforce Integration Patterns and Best Practices
- Salesforce Native App
Sources
- Salesforce Developers, Open CTI Developer Guide, Migrate Your Open CTI Integration to Salesforce Voice with Partner Telephony
- Salesforce Developers, Open CTI Developer Guide, Compare the Conceptual Models of Open CTI and Salesforce Voice with Partner Telephony
- Trailhead, Prepare for Open CTI Retirement
- Salesforce Developers, Salesforce Voice with Partner Telephony Developer Guide
- Salesforce Developers, Partner Telephony Developer Guide, Create a Salesforce Voice Package
- Salesforce Developers, Partner Telephony Developer Guide, Set Up Your Service Org
- Salesforce Developers, Partner Telephony Developer Guide, Call Recordings
- Salesforce Developers, Salesforce Voice Developer Guide, Create a Voice Call Record
- Salesforce Developers, Object Reference, Task
- Salesforce Developers, Object Reference, VoiceCall
- Salesforce Developers, Object Reference, VoiceCallRecording
- Salesforce Developers, API Request Limits and Allocations
- Salesforce Developers, Apex Developer Guide, Introduction to Apex REST
- Salesforce Developers, REST API Developer Guide, Upsert Records Using sObject Collections
- Salesforce Developers, REST API Developer Guide, Send Multiple Requests Using Composite
- Salesforce Developers, REST API Developer Guide, Composite Batch
- Salesforce Developers, REST API Developer Guide, Insert or Update Blob Data
- Salesforce Developers, Platform Events Developer Guide, Default Platform Event Allocations
- Salesforce Developers, Platform Events Developer Guide, Considerations for Defining and Publishing Platform Events
- Salesforce Developers, Streaming API Developer Guide, PushTopic Events (Legacy)
- Salesforce Developers, SOQL and SOSL Reference, IN SearchGroup
- Salesforce Developers, Connect REST API, Voice Calls
- Salesforce Developers, Connect REST API, Voice Call Audio Upload
- Trailhead, Review Conversation Intelligence Requirements



