---
title: "Salesforce API: A Complete Guide (2026)"
img: https://s3.us-east-2.amazonaws.com/unified-article-images/salesforce_api_a_complete_guide_2026-icon.png
date: 2026-02-20T13:18:00.000Z
tag: Product
description: "The Salesforce API isn't one API — it's a portfolio. REST API for standard CRUD, Bulk API 2.0 for large async loads, Pub/Sub API for change events, Composite..."
url: "https://unified.to/blog/salesforce_api_a_complete_guide_2026"
---

# Salesforce API: A Complete Guide (2026)
------
_February 20, 2026_

The Salesforce API isn't one API — it's a portfolio. REST API for standard CRUD, Bulk API 2.0 for large async loads, Pub/Sub API for change events, Composite for transactional multi-object operations, plus SOAP, GraphQL, Apex REST, Tooling, and Metadata for specific use cases. As of Spring '26, the current API version is v66.0, and Pub/Sub API is the recommended path for new event-driven integrations. 


For a B2B SaaS team integrating Salesforce, the technical work isn't in the endpoint calls — it's in choosing the right API surface, managing [OAuth](/embeddedauth) across production and sandbox environments, and operating at scale across many customer orgs.


This guide covers the Salesforce API surface taxonomy, OAuth setup, SOQL [pagination](/docs/reference/pagination), Bulk API 2.0, Pub/Sub event delivery, governance limits, and what changes when you support Salesforce alongside other CRM integrations.


## Key takeaways

- The Salesforce API is a portfolio of surfaces, not a single API. As of Spring '26, the current version is v66.0. Modern integrations primarily use REST API (standard CRUD), Bulk API 2.0 (high-volume async), Pub/Sub API (events), and Composite (multi-object transactions). SOAP, Streaming API, and Bulk API 1.0 still work but are legacy paths.
- OAuth 2.0 Web Server Flow is the standard pattern for customer-facing SaaS integrations. As of 2026, Salesforce recommends using My Domain–specific OAuth endpoints (`https://<myorg>.my.salesforce.com/services/oauth2/...`) instead of the legacy generic endpoints, and separate Connected Apps per environment.
- Salesforce governance limits include a rolling 24-hour API request pool (100,000 + license allocation), 25 concurrent long-running requests in production, and 15,000 Bulk API batches per 24 hours shared across Bulk 1.0 and 2.0. Monitor allocations via the `/services/data/v66.0/limits` endpoint.
- SOQL pagination uses cursor-based query locators (`nextRecordsUrl`), not LIMIT/OFFSET. The 50,000-row-per-transaction cap and 120-second query timeout are the constraints integrations actually hit.
- Pub/Sub API (gRPC + Apache Avro, pull-based with flow control) is the recommended choice for new event-driven integrations subscribing to Change Data Capture (CDC) or Platform Events. Streaming API (CometD/JSON, server-driven push) remains supported for existing integrations.
- For B2B SaaS teams supporting Salesforce alongside other CRMs (HubSpot, Pipedrive, Microsoft Dynamics, etc.), the per-CRM lifecycle work multiplies. A unified [CRM API](/crm) consolidates this into a single integration surface across 49+ CRM integrations.

## What is the Salesforce API?


The Salesforce API is a portfolio of integration surfaces that B2B SaaS teams use to read, write, query, and subscribe to Salesforce data programmatically. It's not a single endpoint — Salesforce maintains multiple distinct APIs optimized for different use cases, and the right one for your integration depends on whether you're doing CRUD on individual records, processing millions of rows asynchronously, subscribing to record changes, or composing multi-object transactions.


For most customer-facing B2B SaaS integrations in 2026, the relevant Salesforce APIs are:

- **REST API** for day-to-day CRUD on records (the workhorse)
- **Bulk API 2.0** for high-volume async loads
- **Pub/Sub API** for subscribing to record changes (CDC) and custom events (Platform Events)
- **Composite API** for transactional multi-object operations
- **SOQL** (the query language used across REST and Bulk for complex reads)

Other Salesforce APIs (SOAP, Streaming, GraphQL, Apex REST, Tooling, Metadata, UI API, Connect REST) serve more specific use cases covered later in this guide.


## What APIs does Salesforce provide and when should I use each?


| API surface              | Use case in 2026                                          | Status                                                   |
| ------------------------ | --------------------------------------------------------- | -------------------------------------------------------- |
| REST API                 | Day-to-day CRUD, mobile/web backends, microservices       | Primary data API; use current version (v66.0)            |
| Bulk API 2.0             | High-volume async data loads, ETL, migrations             | Recommended for bulk; CSV-based, simpler than 1.0        |
| Pub/Sub API              | New event-driven integrations (CDC, Platform Events)      | Recommended for new work; gRPC + Apache Avro             |
| Composite / Batch / Tree | Reducing REST chattiness, transactional multi-object ops  | Recommended for chatty/mobile scenarios                  |
| Apex REST                | Custom business APIs encapsulating Apex logic             | Use when you need process-oriented endpoints             |
| GraphQL API              | Complex nested queries from modern clients                | First-class; recommended for GraphQL-centric apps        |
| SOAP API                 | Legacy/enterprise ESB integrations needing WSDL contracts | Fully supported; older versions 21-30 retired Summer '25 |
| Streaming API            | Existing CometD/JSON subscribers to PE/CDC                | Still supported; legacy path for events                  |
| Bulk API 1.0             | Existing bulk job code                                    | Legacy; don't start greenfield projects on it            |
| Connect REST             | Chatter feeds, files, collaboration features              | Niche; supported                                         |
| Tooling API              | IDEs, tests, devops tooling                               | Actively extended (e.g., Test Discovery in Spring '26)   |
| Metadata API             | Deploy/retrieve config and code (CI/CD)                   | Core devops; fully current                               |
| UI API                   | Custom UIs mirroring Salesforce record layouts            | Recommended for Salesforce-like UX externally            |
For a typical B2B SaaS integration that reads customer records, writes deal updates, and reacts to record changes in near-real-time, the path is **REST API + Pub/Sub API + Bulk 2.0 (if doing migrations)**. Composite is a useful add-on when you find yourself making chained REST calls.


**Retired or legacy:** API versions 21.0-30.0 were retired Summer '25 — calls to those versions return HTTP 410 (REST), 500 UNSUPPORTED_API_VERSION (SOAP), or 400 InvalidVersion (Bulk). Salesforce Functions was retired in 2025; for async workloads, use Platform Events, Pub/Sub, external serverless, or Apex async patterns instead.


## Step 1 — How do I create an OAuth Connected App or External Client App?


Salesforce uses OAuth 2.0 for authentication. Before your application can call Salesforce APIs, you need a registered application in the customer's Salesforce org.


As of Spring '26, Salesforce is shifting from classic **Connected Apps** to **External Client Apps (ECA)** as the standard integration construct:

- **External Client Apps** are the recommended path for new integrations. They're "closed by default" (must be explicitly installed and authorized in each org), they separate developer settings from admin policies, and they support 10+ OAuth flows. ECAs do not support the Username-Password flow.
- **Connected Apps** keep working for existing integrations, but creating new ones is largely blocked in modern orgs without Salesforce intervention. ISVs shipping Connected Apps in managed packages should plan a migration to ECAs.

If you have an existing Connected App that's working, leave it in place. For new integrations, build with an External Client App.


In Salesforce Setup:

1. Navigate to **App Manager**
2. Create a new External Client App (or, for existing orgs only, a Connected App)
3. Enable OAuth settings
4. Provide a Callback URL — for example: `https://yourapp.com/oauth/salesforce/callback`
5. Select required OAuth scopes such as `api` and `refresh_token` (the latter required if you need offline access)

After saving, Salesforce provides:

- **Consumer Key** (`client_id`)
- **Consumer Secret** (`client_secret`)

These credentials are used in the OAuth flow.


**Best practice:** maintain separate apps per environment (one for production, one per sandbox you support). Different `client_id`/`client_secret` per environment makes it impossible to accidentally use production credentials against a sandbox or vice versa.


## Step 2 — How does Salesforce OAuth 2.0 actually work?


Salesforce supports several OAuth 2.0 grant types. The right one depends on whether a human user is involved in the flow and how you manage credentials.


| Grant type                      | When to use                                                                                                                                          |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Web Server (Authorization Code) | User-interactive web apps and backends needing refresh tokens, SSO/MFA compatibility — the primary flow for customer-facing B2B SaaS                 |
| JWT Bearer                      | Server-to-server with certificate management; recommended where strong security matters (signed JWT, no client secret in play)                       |
| Client Credentials              | Modern server-to-server option using a configured execution user; Salesforce positions it as a more secure alternative to Username-Password          |
| Device Flow                     | Limited-input devices and CLIs where the client can't host a browser but a user can complete auth on a secondary device                              |
| Username-Password               | Discouraged for new integrations; supported only on Connected Apps (not External Client Apps) for legacy or tightly controlled first-party use cases |
For most customer-facing B2B SaaS products integrating Salesforce, **Web Server Flow (Authorization Code grant)** is the right choice. The high-level flow:

1. Redirect the user to Salesforce's authorization endpoint
2. The user logs in and grants consent
3. Salesforce redirects back to your callback URL with an authorization code
4. Your backend exchanges that code for an access token at Salesforce's token endpoint

For server-to-server integrations where no user is involved (e.g., scheduled batch syncs to/from your application), **Client Credentials Flow** or **JWT Bearer Flow** are the recommended choices. JWT Bearer offers stronger security via signed assertions; Client Credentials is simpler operationally with a managed execution user.


### Which OAuth endpoint should I use?


Salesforce historically used generic global login domains:

- **Production:** `https://login.salesforce.com/services/oauth2/{authorize,token}`
- **Sandbox:** `https://test.salesforce.com/services/oauth2/{authorize,token}`

These still work, but as of 2026 Salesforce strongly prefers **My Domain–specific endpoints**:

- **Production:** `https://<myorg>.my.salesforce.com/services/oauth2/{authorize,token}`
- **Sandbox (e.g., a UAT sandbox of** **`myorg`****):** `https://<myorg>--uat.sandbox.my.salesforce.com/services/oauth2/{authorize,token}`

My Domain endpoints are recommended because they:

- Guarantee the user lands in the correct org (no ambiguity if they belong to multiple orgs)
- Survive org instance moves (NA-, EU- prefixes change; My Domain is stable)
- Align with Salesforce's security guidance around login policies and SSO

For B2B SaaS integrations supporting many customer orgs, treat the OAuth base URL as configuration — store it per customer connection and build endpoints as `${SF_AUTH_BASE_URL}/services/oauth2/authorize`.


### Token response


The token response from Salesforce includes:

- `access_token` — used in `Authorization: Bearer ...` headers
- `instance_url` — the org-specific URL you'll use as the base for all subsequent API calls
- `refresh_token` — present only if `refresh_token` scope was requested
- `id_token` — present if OpenID Connect scopes were requested

Your application is responsible for storing tokens securely and refreshing access tokens before they expire. For deeper coverage of OAuth lifecycle handling across many integrations, see [how to handle OAuth across many integrations](https://unified.to/blog/how_to_handle_oauth_across_many_integrations), [understanding OAuth2 authorization flows](https://unified.to/blog/understanding_oauth2_authorization_flows), and [how to check if an OAuth token is expired](https://unified.to/blog/how_to_check_if_an_oauth_token_is_expired).


## Step 3 — How do I make REST API calls?


Use the `instance_url` returned from the token exchange as the base for all REST API calls. The current Salesforce API version as of Spring '26 is **v66.0**. Salesforce documents the REST API resources comprehensively in their [REST API Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_what_is_rest_api.htm).


Example SOQL query via the REST API:


```bash
GET https://yourorg.my.salesforce.com/services/data/v66.0/query?q=SELECT+Id,Name+FROM+Account+WHERE+Industry='Media'
Authorization: Bearer ACCESS_TOKEN
```


Inspecting object metadata (custom fields, relationships, required fields):


```bash
GET https://yourorg.my.salesforce.com/services/data/v66.0/sobjects/Account/describe
Authorization: Bearer ACCESS_TOKEN
```


Creating a record:


```bash
POST https://yourorg.my.salesforce.com/services/data/v66.0/sobjects/Account
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
  "Name": "Acme Corp",
  "Industry": "Technology"
}
```


### Salesforce versioning policy


Salesforce releases three API versions per year, named after seasonal releases (Spring, Summer, Winter). Recent history:

- Spring '26 — v66.0 (current as of April 2026)
- Winter '26 — v65.0
- Summer '25 — v64.0
- Spring '25 — v63.0

API versions 21.0-30.0 were retired in Summer '25. For new integrations, target the current version. For existing integrations, plan a migration cadence — Salesforce typically provides multi-year deprecation windows but the older the version, the higher the risk.


## How does SOQL work?


SOQL (Salesforce Object Query Language) is the query language used across REST API, Bulk API, SOAP API, and Apex. SQL-like, but with constraints specific to Salesforce's data model.


A simple query with filter, sort, and limit:


```sql
SELECT Id, Name, BillingCity, Industry
FROM Account
WHERE Industry = 'Media'
  AND BillingCountry = 'Canada'
ORDER BY Name ASC NULLS LAST
LIMIT 100
```


A relationship query with a subselect (parent-child traversal):


```sql
SELECT Name,
       (SELECT LastName
        FROM Contacts
        WHERE CreatedBy.Alias = 'x')
FROM Account
WHERE Industry = 'Media'
```


### Pagination uses query locators, not LIMIT/OFFSET


For large result sets, Salesforce returns a cursor (`queryLocator`) representing the remaining records. The pattern:

1. Issue initial query (`/services/data/v66.0/query?q=...`)
2. Process returned records
3. If `done` is `false`, the response includes a `nextRecordsUrl`
4. `GET nextRecordsUrl` to fetch the next chunk
5. Repeat until `done` is `true`

```bash
# Initial query
GET /services/data/v66.0/query?q=SELECT+Id,Name+FROM+Account
# Response contains records + nextRecordsUrl + done: false

# Next page
GET /services/data/v66.0/query/01gXX0000004CkSIAU-2000
# Continues until done: true
```


LIMIT/OFFSET exists in SOQL but is capped (OFFSET supports skipping up to 2,000 rows, and the query re-executes each time). For integration pagination, treat `nextRecordsUrl` as the canonical model. For broader coverage of pagination patterns across SaaS APIs, see our guide on [API pagination: why it breaks multi-integration systems](https://unified.to/blog/api_pagination_why_it_breaks_multi_integration_systems_and_how_to_handle_it).


### SOQL constraints worth designing around

- **50,000 rows per transaction** — including aggregate query result rows
- **100 SOQL queries per synchronous Apex transaction**, 200 async
- **120-second query timeout** for execution; 30 minutes allowed for streaming results
- **Aggregate queries** (`COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `GROUP BY`, `HAVING`) can `ORDER BY` only the grouping fields or aggregate expressions, not arbitrary fields
- **External objects** (Data Cloud, integrated objects) have additional aggregate restrictions

For high-volume reads, prefer Bulk API 2.0 query jobs over many REST queries.


## How does Bulk API 2.0 work for large data loads?


Bulk API 2.0 is the recommended path for high-volume async work — initial backfills, nightly ETL, large updates, migrations. It's CSV-based and simpler than the legacy Bulk 1.0 (which is still supported for existing integrations but treated as legacy).


Bulk API 2.0 uses a job-based async lifecycle:

1. Create a job (specify object, operation: insert/update/upsert/delete, line ending)
2. Upload CSV data to the job
3. Close the job to start processing
4. Poll job status until complete
5. Retrieve results (success/failure CSV files)

Salesforce automatically splits ingest data into batches of up to 10,000 records. For query jobs, results stream as CSV.


### Bulk API governance limits


Both Bulk 1.0 and Bulk 2.0 share a unified daily allocation:

- **15,000 batches per 24-hour rolling window** (each 10,000-record chunk = 1 batch)
- **150,000,000 records per 24-hour rolling window** (15,000 × 10,000)
- **10,000 Bulk API 2.0 query jobs per 24-hour rolling window**
- **1 TB of query results storage per 24-hour rolling window**

Monitor via the `/services/data/v66.0/limits` endpoint:

- `DailyBulkApiBatches`
- `DailyBulkV2QueryJobs`
- `DailyBulkV2QueryFileStorageMB`

## How does real-time event delivery work in Salesforce?


Salesforce doesn't use traditional HTTP webhooks. Event delivery happens through the platform event bus, accessed via Pub/Sub API (recommended) or Streaming API (legacy). For a broader treatment of how event delivery patterns differ across integration architectures, see our guide on [what are virtual webhooks? how they differ from sync-based webhooks](https://unified.to/blog/what_are_virtual_webhooks_how_they_differ_from_sync_based_webhooks).


### Pub/Sub API (recommended for new integrations)


Pub/Sub API uses gRPC over HTTP/2 with Apache Avro binary encoding, supporting multiple languages with pull-based flow control. Subscribers explicitly request N events at a time, providing back-pressure handling. Salesforce documents Pub/Sub API setup, gRPC client requirements, and Avro schema handling in their [Pub/Sub API Developer Guide](https://developer.salesforce.com/docs/platform/pub-sub-api/overview).


Per-request limits:

- **3 MB recommended batch size** for publish (4 MB hard limit; if exceeded, the publish fails and the gRPC stream closes)
- **200 events recommended per** **`PublishRequest`** for best performance
- **100 events maximum per fetch** in subscribe/managed subscribe calls (excess silently treated as 100)
- **200 unique managed subscriptions per org** maximum

### Streaming API (legacy — supported but not recommended for new work)


Streaming API uses CometD (Bayeux protocol) with JSON over HTTP, server-driven push. Less control over flow, less efficient at scale, but simpler client implementation. Salesforce hasn't deprecated Streaming API and continues to update it, but new event-driven integrations should target Pub/Sub.


## When should I use Change Data Capture vs Platform Events?


Both Change Data Capture (CDC) and Platform Events flow through the same Pub/Sub or Streaming infrastructure. The difference is in what they represent and when to use each.


### Change Data Capture — passive data sync


CDC publishes change events when tracked records are created, updated, deleted, or undeleted.

- **Schema-driven payload:** object name, record ID, change type, changed field values (with old/new where relevant), transaction key, change origin
- **Admin-level configuration:** enable CDC on objects in Salesforce Setup; no custom event schema required
- **Replayable, ordered stream:** events have replay IDs; subscribers can catch up from a specific point within the retention window

**Use CDC for:**

- Keeping an external database, data warehouse, or search index in sync with Salesforce records
- "Listen to everything" patterns where any DML on an object should be visible downstream
- Low-code event subscription — toggle CDC on, subscribe via Pub/Sub, done

**Trade-offs:** Bulk updates and ETL jobs can spike CDC volume, exhausting platform event allocations. Payload shape is determined by the underlying record schema.


### Platform Events — intentional business events


Platform Events are custom event types with schemas you define (similar to custom objects but with `__e` suffix).

- **Custom event schema:** model events like `OrderSubmitted__e` or `PaymentFailed__e` with the fields they need to carry
- **Explicit publishing:** events are only published when your code (Apex, Flow, REST API) chooses to publish
- **Business-centric payload:** carry record IDs, summary values, correlation IDs, contextual metadata — whatever your downstream process needs

**Use Platform Events for:**

- Triggering external applications on intentional business events (`OrderConfirmed`, `InvoiceGenerated`, `SubscriptionRenewalDue`)
- Aggregating or pre-filtering activity before emitting an event (only fire when a deal crosses certain criteria, not on every field change)
- Inbound events from external applications into Salesforce, with Apex or Flow consuming them
- Custom payload control where you don't want to surface full record contents

**Use both** when your architecture needs both passive sync and intentional business events. CDC feeds the warehouse, Platform Events orchestrate downstream business logic.


## What are the Salesforce API governance limits?


Salesforce enforces governance limits at multiple levels. The ones B2B SaaS integrations actually hit:


### 24-hour rolling API request pool


Core platform APIs (REST, SOAP, Bulk, Tooling) share a 24-hour rolling window:

- **Enterprise Edition:** 100,000 + (license count × per-license allocation). Salesforce and Salesforce Platform licenses typically contribute 1,000 calls each. Example: 20 Salesforce licenses → 100,000 + (20 × 1,000) = 120,000 API calls per 24-hour window
- **Unlimited / Performance Edition:** Same formula, but Salesforce/Salesforce Platform/Lightning Platform Plus licenses contribute 5,000 calls each
- **Developer Edition:** Fixed 15,000 calls per 24-hour window

The daily limit is described as a "soft limit" that can be briefly exceeded when safe; a hard cap protects the platform.


For a customer-specific number, query the `/limits` endpoint:


```bash
GET https://yourorg.my.salesforce.com/services/data/v66.0/limits
Authorization: Bearer ACCESS_TOKEN
```


The response includes `DailyApiRequests` (max + remaining), `DailyBulkApiBatches`, `DailyBulkV2QueryJobs`, and many other allocations.


### Concurrent long-running request limit


Long-running requests (those exceeding 20 seconds in execution) have a separate concurrent cap:

- **Production orgs:** 25 concurrent long-running requests
- **Sandbox / Developer orgs:** 5 concurrent long-running requests

When the cap is hit, additional long-running requests return `REQUEST_LIMIT_EXCEEDED`. Once active long-running requests fall below the cap, new ones can be processed.


### Bulk API limits


Bulk 1.0 and 2.0 share allocations: 15,000 batches per 24-hour rolling window (1 batch ≈ 10,000 records), 150M records total per 24-hour window, 10,000 Bulk 2.0 query jobs per 24 hours, 1 TB query result storage per 24 hours.


### Pub/Sub limits


Per-request: 3 MB recommended (4 MB hard) batch size, 200 events recommended per publish, 100 events maximum per fetch. Per-org: 200 managed subscriptions maximum.


### Designing around limits

- Treat 429 / `REQUEST_LIMIT_EXCEEDED` as normal failure modes
- Implement exponential backoff with jitter
- Monitor allocations actively via `/limits` rather than reactively
- For high-volume reads, prefer Bulk API 2.0 query jobs over individual REST queries
- For event delivery at scale, prefer Pub/Sub API over Streaming API

## How does sandbox vs production differ?


Sandbox orgs are separate Salesforce environments mirroring production for testing, staging, and integration development. From an OAuth and API perspective, sandboxes work the same as production with three differences:

- **Login domains differ.** Production uses `login.salesforce.com` (or production My Domain); sandbox uses `test.salesforce.com` (or sandbox My Domain like `<myorg>--uat.sandbox.my.salesforce.com`)
- **Usernames append the sandbox name.** A user `user@example.com` in production becomes `user@example.com.uat` in the UAT sandbox
- **Concurrent long-running limits are lower** in sandbox (5 vs 25 in production)

For B2B SaaS integrations supporting both production and sandbox connections per customer, build OAuth base URLs as per-connection configuration. Don't hard-code `login.salesforce.com` — store the customer-specific OAuth endpoint and use it at request time.


## Where do Salesforce integrations become operationally complex?


A direct Salesforce integration in production requires owning:

- **OAuth lifecycle and refresh logic per customer org**
- **Per-tenant token storage and rotation**
- **API limit monitoring and alerting** (rolling 24-hour windows, concurrent caps, Bulk allocations)
- **SOQL pagination and** **`nextRecordsUrl`** **handling**
- **Object-level required fields that vary across customer orgs** (custom validation rules, required fields per record type)
- **CDC or Platform Events subscription infrastructure** (gRPC client for Pub/Sub or CometD client for Streaming)
- **Sandbox vs production environment routing**
- **My Domain vs generic login endpoint handling**
- **Connected App vs External Client App migration** for ISVs shipping integration packages (ECAs are the new standard as of Spring '26)
- **API version migration** (Salesforce ships 3 versions per year; integrations need a strategy for keeping current)

For one Salesforce-only integration, this is manageable. For a multi-CRM B2B SaaS product supporting many Salesforce customer orgs alongside HubSpot, Pipedrive, Microsoft Dynamics, and others, this becomes long-term integration infrastructure work. For broader context on integration architecture choices, see our breakdown of [ETL vs. iPaaS vs. unified API](https://unified.to/blog/etl_vs_ipaas_vs_unified_api_which_integration_platform_requires_the_least_maintenance).


## Integrating Salesforce via Unified's CRM API


Unified's CRM API normalizes Salesforce alongside 48 other CRM integrations through a single integration surface. The same code works against Salesforce, HubSpot, Pipedrive, Microsoft Dynamics 365, Zoho CRM, and others — only the `connection_id` changes. For the full list of CRM integrations available, see [unified.to/integrations/crm](https://unified.to/integrations/crm).


### Setup


When integrating Salesforce through Unified, your Salesforce External Client App's (or Connected App's) callback URL is set to:


```plain text
https://api.unified.to/oauth/code
```


After activating Salesforce in your Unified workspace and entering your app's `client_id` and `client_secret`, you authorize a customer's Salesforce account once. Unified produces a `connection_id` that your application uses for every subsequent call. For full setup details, see the [Salesforce integration guide](https://docs.unified.to/integrations/salesforce).


### Calling the API


Example calls:


```bash
GET https://api.unified.to/crm/contact/{connection_id}?limit=50
Authorization: Bearer YOUR_API_KEY

POST https://api.unified.to/crm/deal/{connection_id}
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

GET https://api.unified.to/crm/event/{connection_id}?limit=100&updated_gte=2026-01-01T00:00:00Z
Authorization: Bearer YOUR_API_KEY
```


The same endpoints work for all 49 CRM integrations Unified supports.


### What Unified handles

- **OAuth lifecycle** including refresh token management and per-tenant token storage
- **Endpoint routing** between My Domain, generic login, sandbox, and production
- **SOQL pagination** abstracted as `limit`/`offset`/`updated_gte` standard parameters
- **Webhook delivery** with full normalized records in the `data` array (no follow-up `GET` required) — including Salesforce CDC and Platform Events when the customer enables them
- **Custom field access** via `?fields=raw,raw.fieldName` syntax on standard endpoints
- **Raw passthrough** for completely custom Salesforce objects or endpoints not in the normalized schema
- **Rate limit handling** for webhooks (coordinated across integrations); direct API calls return 429 errors that the application is responsible for backoff on

## Direct vs. Unified — when to choose each


| Consideration                           | Direct Salesforce integration   | Unified CRM API                      |
| --------------------------------------- | ------------------------------- | ------------------------------------ |
| Setup time per customer                 | Hours to days                   | Minutes                              |
| OAuth lifecycle per customer            | You implement                   | Handled                              |
| API surface routing (REST/Bulk/Pub-Sub) | You implement                   | Handled                              |
| SOQL pagination                         | You implement                   | Abstracted                           |
| Custom field handling                   | You implement per customer      | Via `raw` field syntax               |
| CDC / Platform Events subscription      | You build gRPC or CometD client | Handled                              |
| API version migration                   | You manage                      | Handled                              |
| Multi-CRM support                       | Separate code per CRM           | Same code, different `connection_id` |
| Vendor-specific feature depth           | Full Salesforce platform access | Normalized + raw passthrough         |
| Pricing                                 | Free (engineering cost only)    | Usage-based per API call             |
### Build directly with Salesforce if

- Salesforce is your only CRM integration target
- You need deep Salesforce-specific platform capabilities (custom Apex APIs, complex Composite transactions, Tooling/Metadata API for devops)
- You have engineering capacity to operate OAuth, governance limit monitoring, and event-bus subscription infrastructure
- You want full control over which Salesforce API surfaces you call and how

### Use Unified if

- You support (or plan to support) multiple CRMs across customers
- You want time-to-first-customer measured in minutes, not days
- You'd rather not build OAuth refresh, governance limit monitoring, or Pub/Sub subscription infrastructure per CRM
- You want consistent webhook semantics across Salesforce, HubSpot, Pipedrive, and others
- You're building AI features where real-time CRM state matters across whichever CRM the customer uses

For a deeper architectural breakdown, see our [CRM API integration guide](https://unified.to/blog/crm_api_integration_real_time_customer_data_across_sales_pipelines).


## Frequently asked questions


### What is the Salesforce API?


The Salesforce API is a portfolio of integration surfaces — REST API, SOAP API, Bulk API 2.0, Pub/Sub API, Composite, GraphQL, Apex REST, Tooling, Metadata, UI API, Connect REST, and Streaming API. Each is optimized for different use cases. For most B2B SaaS integrations in 2026, the relevant ones are REST API for CRUD, Bulk API 2.0 for high-volume async, Pub/Sub API for events, and Composite for transactional multi-object operations.


### Should I use a Connected App or an External Client App in 2026?


For new integrations, use an **External Client App (ECA)**. As of Spring '26, Salesforce has shifted ECAs to the standard integration construct — they're "closed by default," separate developer settings from admin policies, and support 10+ OAuth flows. New Connected Apps are largely blocked in modern orgs. ECAs do not support the Username-Password flow (Connected Apps still do). Existing Connected Apps continue to work, but ISVs shipping Connected Apps in managed packages should plan a migration to ECAs.


### What's the current Salesforce API version?


As of Spring '26 (April 2026), the current Salesforce API version is **v66.0**. Salesforce releases three API versions per year, named after seasonal releases (Spring, Summer, Winter). API versions 21.0-30.0 were retired in Summer '25.


### Should I use Pub/Sub API or Streaming API?


For new event-driven integrations, use **Pub/Sub API**. It uses gRPC over HTTP/2 with Apache Avro binary encoding, supports multiple languages, and provides pull-based flow control. Streaming API (CometD/JSON, server-driven push) remains supported for existing integrations but isn't where Salesforce is investing for new work.


### What's the difference between CDC and Platform Events?


**Change Data Capture (CDC)** publishes events automatically when tracked records change — use it for passive data sync (warehouse, search index, identity store). **Platform Events** are custom event types you define and publish explicitly — use them for intentional business events (`OrderSubmitted__e`, `PaymentFailed__e`). Both flow through the same Pub/Sub or Streaming infrastructure.


### How does Salesforce SOQL pagination work?


SOQL uses cursor-based pagination via query locators, not LIMIT/OFFSET. The initial query response includes `nextRecordsUrl`; calling that URL returns the next page until `done: true`. LIMIT/OFFSET exists in SOQL but caps OFFSET at 2,000 rows and re-executes the full query each time, making it unsuitable for integration pagination.


### What are Salesforce's API governance limits?


For Enterprise Edition, the 24-hour rolling API request pool is `100,000 + (license count × per-license allocation)` (typically 1,000 per Salesforce license). Unlimited Edition gets 5,000 per license instead. Concurrent long-running requests are capped at 25 in production, 5 in sandbox/developer orgs. Bulk API allocations are 15,000 batches per 24 hours shared across Bulk 1.0 and 2.0. Monitor via `/services/data/v66.0/limits`.


### What's the difference between sandbox and production OAuth domains?


Production OAuth uses `login.salesforce.com` or production My Domain (e.g., `myorg.my.salesforce.com`). Sandbox uses `test.salesforce.com` or sandbox My Domain (e.g., `myorg--uat.sandbox.my.salesforce.com`). As of 2026, Salesforce recommends My Domain–specific endpoints over the generic `login`/`test` domains. Maintain separate Connected Apps per environment with distinct `client_id`/`client_secret` to prevent cross-environment credential leakage.


### How does Unified handle Salesforce custom fields?


Custom fields appear inside the `raw` object on each normalized CRM record. Access them with `?fields=raw` (returns full Salesforce payload) or `?fields=raw,raw.Custom_Field__c` (specific custom fields by name). For completely custom Salesforce objects not in the normalized schema, the Passthrough API supports direct CRUD against any Salesforce REST endpoint while keeping the unified authentication and connection management.


## Final thoughts


Integrating with the Salesforce API is straightforward at the endpoint level — make a REST call, parse the JSON response. Operating a production-grade Salesforce integration across many customer orgs is where complexity appears: OAuth lifecycle per tenant, governance limit monitoring, SOQL pagination patterns, Pub/Sub or Streaming subscription infrastructure, sandbox vs production routing, and API version migration.


For B2B SaaS teams supporting Salesforce as one of multiple CRM integrations, the per-CRM lifecycle work multiplies. Unified.to consolidates Salesforce alongside 48 other CRM integrations into a single normalized API with consistent webhook semantics, custom field access via `raw`, and full support for raw passthrough where vendor-specific features are needed.


[→ Start your 30-day free trial](https://app.unified.to/login)


[→ Book a demo](https://calendly.com/d/cph9-g8n-jzg/connect-with-unified)