Skip to content
Back to Blog
Integration

Salesforce API Integration for SaaS Products, From API Choice to Each Customer's Limits

Jul 23, 2025
Aappnigma
Salesforce API Integration for SaaS Products, From API Choice to Each Customer's Limits

A Salesforce API integration for a SaaS product is usually three APIs and one auth setup. Your servers write and read through the REST API, switch to Bulk API 2.0 above 2,000 records, and listen for changes through Pub/Sub API. Each customer authorizes your External Client App with the OAuth web server flow. Every request you send is paid for out of that customer's own daily API allocation, so the API choice is also a cost decision for your buyer.

That last point is what separates a vendor integration from an internal one. Your product has to work inside hundreds of customer orgs you don't control, each with its own edition, admin and API budget, and an enterprise buyer will ask what your sync does to their limits before they sign. Appnigma builds these customer-facing integrations for B2B SaaS companies. Our done for you delivery builds and maintains the integrations your customers ask for, our integration infrastructure lets each customer authorize their own account from your product with their connection managed separately, and our marketplace apps work puts your product inside Salesforce when the integration needs a managed package. If you are comparing architectures rather than APIs, start with our guide to the six Salesforce integration patterns.

Updated October 2026. Checked against Salesforce's Developer Limits and Allocations reference and the ISVforce guide. We also checked the REST API, Bulk API 2.0, Pub/Sub API and Change Data Capture guides (Winter '27, API version 68.0). The earlier version said Appnigma's API use was uncapped, recommended Streaming API for real-time sync and printed a vendor comparison table ten times. This update removes those and adds per-org API arithmetic. It also covers the Spring '26 change to Connected Apps, the OAuth controls Salesforce now requires of partner apps and the API versions retiring in 2027.

Which Salesforce API fits each job

Salesforce publishes many APIs, but a customer-facing data integration uses a small set of them, and each one is metered differently. The table maps the job to the API and to the budget it draws from in the customer's org.

Job in your integrationAPI to useWhat it spends in the customer orgSource
Create or update up to 200 records at onceREST API sObject CollectionsOne API call per requestsObject Collections
Chain dependent writes, such as an Account then its ContactsREST API Composite, up to 25 subrequestsOne API call per requestComposite
Initial load or any job above 2,000 recordsBulk API 2.0Daily API calls plus the 15,000 batch poolBulk API limits
Hear about record changesChange Data Capture through Pub/Sub APIThe event delivery allocation, shared by all subscribersCDC Allocations
Read the customer's custom fields and objectsREST describe, or Tooling API for metadata detailDaily API callsIntroducing Tooling API
Deploy configuration between orgsMetadata APIDaily API callsUnderstanding Metadata API

Two APIs trip teams up. Composite Batch looks like Composite but saves nothing, because with it "each subrequest counts against rate limits," per Composite Batch. And Bulk API 2.0 is not a way around the daily limit. Salesforce lists "Bulk API, Bulk API 2.0, and most Connect REST APIs" among the APIs that count toward it, per API Request Limits and Allocations. Metadata API is "not the data itself," so it has no place in a record sync. Our comparison of the Metadata API and Tooling API covers when a vendor needs either one.

Salesforce's own threshold decides between batched REST calls and Bulk API 2.0. "Any data operation that includes more than 2,000 records is a good candidate for Bulk API 2.0." Smaller jobs "should involve 'bulkified' synchronous calls in REST (for example, Composite) or SOAP," per the Bulk API limits page. Our Bulk API 2.0 guide covers job sizing, and our post on Composite and GraphQL covers the bulkified REST side.

What one sync costs a customer's org

The daily allocation belongs to the org, not to your app. Salesforce sets it at "100,000 + (number of licenses x calls per license type) + purchased API Call Add-Ons" per API Request Limits and Allocations. Enterprise Edition adds 1,000 calls per Salesforce license. Unlimited and Performance add 5,000. The same page states that "API calls made from installed managed packages, count against your org limit," so an AppExchange listing doesn't move your traffic into a separate pool.

Here is arithmetic from those documented figures, not a measured customer. An Enterprise org with 50 Salesforce licenses has 150,000 calls per 24 hours. Suppose your product writes 20,000 changed records a day back to that org.

How you send the 20,000 recordsCalls per dayShare of a 150,000 allocation
One record per REST request20,000About 13 percent
sObject Collections, 200 records per request100Under 0.1 percent
Polling 10 objects every 5 minutes to find changes, added on top2,880About 2 percent

The polling row is the one buyers rarely see coming, because it costs calls even on days nothing changes. Subscribing to Change Data Capture replaces it, and those events draw on a different budget. A default Enterprise org can deliver 25,000 change events per 24 hours to API subscribers. "If you have multiple client subscribers, your usage is added across all subscribers," per Change Data Capture Allocations. Our comparison of platform events and Change Data Capture shows how that pool is shared.

A write through sObject Collections looks like this. The whole request "counts as a single call toward your API limits," per sObject Collections, and for an update "the list can contain up to 200 objects," per Update Records Using sObject Collections.

curl -X PATCH "https://customer-domain.my.salesforce.com/services/data/v67.0/composite/sobjects" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "allOrNone": false,
    "records": [
      {"attributes": {"type": "Account"}, "id": "001XXXXXXXXXXXXXXX", "Usage_Score__c": 82},
      {"attributes": {"type": "Account"}, "id": "001YYYYYYYYYYYYYYY", "Usage_Score__c": 47}
    ]
  }'

Set allOrNone to false for a sync so one bad record doesn't roll back the other 199. The response returns a result per record, which is where your retry logic should look. The request above has not been run against a live org for this article, so check field names against your own test org.

How customers authorize your app in their org

Each customer connects through an OAuth app that you own. New ones are External Client Apps. "Starting in the Spring '26 release, you can't create new Connected Apps. Use ECAs instead," per Salesforce's ISVforce guide. Existing connected apps keep working, and the REST guide says "you can continue to use existing connected apps during and after Spring '26," per Authorization Through External Client Apps or Connected Apps. If you also ship a package, External Client Apps "can be packaged in first-generation managed packages or second-generation managed packages," per the 2GP packaging guide.

For a vendor, the web server flow is the one that scales across customers, because an admin in each org can approve your app from your product without building anything in their own org. Salesforce added rules for exactly this case. Its security requirements apply to an app "in use by more than two customer production orgs," and they cover four controls with a deadline of May 11, 2026, per the ISVforce guide.

PKCE has to be on "regardless of whether the client is public or confidential." Refresh token rotation is required too, so your token store must save the new refresh token on every refresh and handle two workers refreshing at once. After 30 idle days "Salesforce invalidates the idle refresh token," which means a customer whose sync pauses for a month has to reconnect unless you refresh before then. Token requests must also come from an IP allowlist, with "a total of 256 IP addresses" across all ranges.

The client credentials flow is the other option people reach for. Salesforce describes it as "intended for server-to-server connections," and it issues the token for a "Run As" user configured in the org, per the Salesforce Developers blog. That setup happens inside each customer org, so it fits a single org or a packaged install better than onboarding from your own sign-up screen. Our guides to External Client App OAuth for SaaS products and Connected Apps versus External Client Apps walk through the settings.

Two edition checks belong in your onboarding. Enterprise, Performance, Unlimited and Developer Edition orgs have API access by default. "Professional Edition orgs can add API access as an add-on," per Supported Editions and Required Permissions. A Professional org without it returns API_DISABLED_FOR_ORG, so test for that error and tell the customer what to buy rather than showing a generic failure. The same page describes the Salesforce Integration user license, which limits a system user "to API-only operations." Our post on the integration user license and setup covers who should own that user.

Is the Salesforce Streaming API deprecated?

Not in those words, but Salesforce has moved new work away from it. "PushTopic and generic events are legacy products," and Salesforce suggests Change Data Capture instead of PushTopic events and Platform Events instead of generic events, per Streaming Event Features. For a new subscriber, "we recommend you use Pub/Sub API instead of Streaming API," per Getting Started with Streaming API. Pub/Sub API runs over gRPC and is available in Enterprise, Performance, Unlimited and Developer editions, per Get Started with Pub/Sub API. Professional is not on that list, which matters if your customers include smaller orgs.

Change Data Capture has a selection limit a vendor runs into early. An org can "select up to five entities, including standard and custom objects," per Select Objects for Change Notifications. If your integration asks the customer to select three objects, it uses most of an allowance their other tools need too. A packaged custom channel avoids that. "If you install an AppExchange released managed package, the selections made by the AppExchange package in a custom channel don't count against your org's allocation," and that "holds true for first- and second-generation packages," per Change Data Capture Allocations. Events stay available "for the retention period of 72 hours," so a subscriber that is down longer than that has to resync from the REST API.

When the integration needs a managed package

An API-only integration runs from your servers calling into Salesforce, which Salesforce's integration guide calls Remote Call-In and rates REST and SOAP API "Best" for, per Remote Call-In. You need code installed in the customer's org when Salesforce has to start the conversation. That covers a button on a record page that calls your product, a trigger that pushes data out the moment it changes, a component that shows your data inside Salesforce, or a packaged Change Data Capture channel that keeps your object selections out of the customer's five.

That code ships as a managed package, and packaged Apex has its own limits. "A single Apex transaction can make a maximum of 100 callouts," with a cumulative maximum of 120 seconds, per Callout Limits and Limitations. Before you list it on AppExchange, the package goes through Salesforce's security review, and our breakdown of governor limits for managed packages covers which limits are shared with the customer's own code. Many vendors start with API-only Remote Call-In, then add a package when buyers ask to see the product inside Salesforce. Our marketplace apps work covers that second step, from the package to listing preparation and review support.

Reading the limit before the customer notices

Your integration can see the customer's remaining budget on every response. REST responses carry a Sforce-Limit-Info header in the form api-usage=10018/100000, where "the first number is the number of API calls used," per Limit Info Header. The /limits resource returns the maximum and remaining allocation for each limit, and its figures "are accurate within five minutes of resource consumption," per Limits. A sensible design reads the header, slows its own sync once the org passes a threshold you agree with the customer, and alerts their admin before anything fails.

Salesforce doesn't stop calls at exactly 100 percent. "Salesforce still lets the operations proceed by a certain amount, if possible," and then "a hard cap is in place," per API Request Limits and Allocations. That margin "doesn't apply to trial orgs, Developer Edition, or sandboxes." Most vendors test in exactly those orgs, so an integration can behave differently in testing than in a customer's production org. The page also caps "concurrent inbound requests (calls) with a duration of 20 seconds or longer" at 25 in production, which a vendor running many workers against one large customer can reach.

Two retirement dates belong on your roadmap. REST API versions 31.0 through 40.0 are "deprecated and unsupported from Summer '27" and retired from Summer '28, and a retired version returns 410:GONE, per the API End-of-Life Policy. Separately, "the SOAP API login() call is scheduled for retirement in Summer '27," per the SOAP API End-of-Life Policy. An older integration that signs in with a username and password through SOAP needs to move to OAuth before then. If you would rather not track these across every customer connection yourself, our integration infrastructure monitors each customer's connections and moves fixes through one review and release process.

Mistakes that show up after customers install

  • Writing one record per request. Above 2,000 records Salesforce points to Bulk API 2.0, and below it to bulkified calls such as sObject Collections.
  • Assuming Bulk API 2.0 or an AppExchange listing is exempt from the daily limit. Both count against the customer's org.
  • Using Composite Batch to save calls. Each subrequest is still counted.
  • Polling for changes on a timer when Change Data Capture can tell you.
  • Asking each customer to select objects for Change Data Capture without checking how many of their five selections are already used.
  • Storing refresh tokens without rotation handling, so the second worker to refresh logs the customer out.
  • Testing limit behavior only in a sandbox, where the overage margin doesn't apply.
  • Building new subscribers on PushTopic events, which Salesforce now calls legacy.

Frequently Asked Questions

Which Salesforce API should a SaaS integration use?

REST API for everyday reads and writes, batched through sObject Collections or Composite. Bulk API 2.0 for anything over 2,000 records, and Change Data Capture through Pub/Sub API to hear about changes.

Do API calls from a managed package count against the customer's limits?

Yes. Salesforce states that API calls made from installed managed packages count against the org's limit, and that includes Bulk API 2.0 jobs.

Can I still create a Connected App for a new integration?

Not by default. Since Spring '26 Salesforce directs new integrations to External Client Apps, and existing connected apps keep working.

How many API calls does a Salesforce Enterprise org get?

100,000 per 24 hours plus 1,000 per Salesforce license, plus any purchased add-ons. A 50-license Enterprise org gets 150,000, shared by every integration and package in that org.

Can Appnigma build our Salesforce API integration?

Yes. Appnigma's done for you delivery builds and maintains the integration with OAuth per customer, and marketplace apps covers the managed package and AppExchange listing when the integration needs code in the customer's org.

Sources

  1. Salesforce Developers, Salesforce Developer Limits and Allocations, API Request Limits and Allocations
  2. Salesforce Developers, Salesforce Developer Limits and Allocations, Bulk API and Bulk API 2.0 Limits and Allocations
  3. Salesforce Developers, REST API Developer Guide, sObject Collections
  4. Salesforce Developers, REST API Developer Guide, Update Records Using sObject Collections
  5. Salesforce Developers, REST API Developer Guide, Composite
  6. Salesforce Developers, REST API Developer Guide, Composite Batch
  7. Salesforce Developers, REST API Developer Guide, Limit Info Header
  8. Salesforce Developers, REST API Developer Guide, Limits
  9. Salesforce Developers, REST API Developer Guide, API End-of-Life Policy
  10. Salesforce Developers, REST API Developer Guide, Supported Editions and Required Permissions
  11. Salesforce Developers, REST API Developer Guide, Authorization Through External Client Apps or Connected Apps and OAuth 2.0
  12. Salesforce Developers, ISVforce Guide, Secure Your Connected Apps and External Client Apps
  13. Salesforce Developers, Second-Generation Managed Packaging, Package Connected Apps
  14. Salesforce Developers Blog, Using the Client Credentials Flow for Easier API Authentication
  15. Salesforce Developers, Streaming API Developer Guide, Streaming Event Features
  16. Salesforce Developers, Streaming API Developer Guide, Getting Started with Streaming API
  17. Salesforce Developers, Pub/Sub API Developer Guide, Get Started with Pub/Sub API
  18. Salesforce Developers, Change Data Capture Developer Guide, Change Data Capture Allocations
  19. Salesforce Developers, Change Data Capture Developer Guide, Select Objects for Change Notifications
  20. Salesforce Developers, Integration Patterns and Practices, Remote Call-In
  21. Salesforce Developers, Apex Developer Guide, Callout Limits and Limitations
  22. Salesforce Developers, Tooling API Developer Guide, Introducing Tooling API
  23. Salesforce Developers, Metadata API Developer Guide, Understanding Metadata API
  24. Salesforce Developers, SOAP API Developer Guide, SOAP API End-of-Life Policy

All Blogs

Bring the customer requirements and your current setup. Get a clear scope and delivery timeline to take back to them.