This card covers the Salesforce Platform API versioning and deprecation lifecycle across all API surfaces — REST, SOAP, Bulk v1, Bulk 2.0, Metadata, Tooling, Connect, Streaming, and Pub/Sub. The policy applies uniformly to all Salesforce editions (Developer, Professional, Enterprise, Unlimited, Performance) though API call limits vary by edition. All Salesforce instances are cloud-hosted. [src1]
| Property | Value |
|---|---|
| Vendor | Salesforce |
| System | Salesforce Platform (all cloud editions) |
| API Surface | REST, SOAP, Bulk v1, Bulk 2.0, Metadata, Tooling, Connect, Streaming, Pub/Sub |
| Current API Version | v66.0 (Spring '26) |
| Editions Covered | Developer, Professional, Enterprise, Unlimited, Performance |
| Deployment | Cloud |
| API Docs | Salesforce REST API Developer Guide |
| Status | GA — versioning policy active and enforced |
All Salesforce API surfaces share the same version numbering scheme and deprecation policy. Each new platform release increments the version number by 1.0 across all surfaces simultaneously. [src1]
| API Surface | Protocol | Version in URL? | Retirement Error Code | Bulk? | Notes |
|---|---|---|---|---|---|
| REST API | HTTPS/JSON | Yes (/services/data/v66.0/) | 410 GONE | No | Primary integration surface |
| SOAP API | HTTPS/XML | Yes (WSDL version) | 500 UNSUPPORTED_API_VERSION | No | Legacy; requires new WSDL per version |
| Bulk API v1 | HTTPS/CSV/XML | Yes | 400 InvalidVersion | Yes | Being superseded by Bulk 2.0 |
| Bulk API 2.0 | HTTPS/CSV | Yes | 400 InvalidVersion | Yes | Recommended for bulk operations |
| Metadata API | HTTPS/XML | Yes (WSDL version) | 500 UNSUPPORTED_API_VERSION | No | Deploy/retrieve metadata |
| Tooling API | HTTPS/JSON | Yes | 410 GONE | No | Development tools and debugging |
| Connect API | HTTPS/JSON | Yes | 410 GONE | No | Chatter, Communities, CMS |
| Streaming API | Bayeux/CometD | Yes | Connection refused | No | Legacy; consider Pub/Sub API |
| Pub/Sub API | gRPC | No (config) | UNSUPPORTED_API_VERSION | No | Modern event streaming |
Salesforce releases 3 major platform updates per year, each incrementing the API version by 1.0. [src5]
| Season | Typical Release Month | Sandbox Preview | Year Convention |
|---|---|---|---|
| Spring | January-February | Previous December | Same calendar year (Spring '26 = early 2026) |
| Summer | May-June | Previous April | Same calendar year (Summer '26 = mid 2026) |
| Winter | September-October | Previous August | Next calendar year (Winter '26 = late 2025) |
Important: The Winter release carries the year of the upcoming year. Winter '26 was released in September-October 2025, not 2026. [src5]
| Release | API Version | Release | API Version | Release | API Version |
|---|---|---|---|---|---|
| Summer '17 | v40.0 | Summer '20 | v49.0 | Summer '23 | v58.0 |
| Winter '18 | v41.0 | Winter '21 | v50.0 | Winter '24 | v59.0 |
| Spring '18 | v42.0 | Spring '21 | v51.0 | Spring '24 | v60.0 |
| Summer '18 | v43.0 | Summer '21 | v52.0 | Summer '24 | v61.0 |
| Winter '19 | v44.0 | Winter '22 | v53.0 | Winter '25 | v62.0 |
| Spring '19 | v45.0 | Spring '22 | v54.0 | Spring '25 | v63.0 |
| Summer '19 | v46.0 | Summer '22 | v55.0 | Summer '25 | v64.0 |
| Winter '20 | v47.0 | Winter '23 | v56.0 | Winter '26 | v65.0 |
| Spring '20 | v48.0 | Spring '23 | v57.0 | Spring '26 | v66.0 |
Salesforce's API End-of-Life policy has two core guarantees: [src1]
| Wave | Versions Retired | Enforcement Date | Notice Given | Affected APIs |
|---|---|---|---|---|
| Wave 1 | v7.0-v20.0 | Summer '22 (June 2022) | ~1 year | REST, SOAP, Bulk v1 |
| Wave 2 | v21.0-v30.0 | Summer '25 (June 2025) | ~1 year | REST, SOAP, Bulk v1, Metadata, Tooling, Connect, Tableau CRM |
| Wave 3 (projected) | v31.0-v39.0 | Not yet announced | TBD | Expected to follow same pattern |
Pattern observation: Waves retire ~10 versions at a time, spaced approximately 3 years apart. If the pattern holds, v31.0-v39.0 retirement could be announced around 2027-2028 — but this is not confirmed by Salesforce. [src2]
| API Surface | HTTP Status | Error Code | Response |
|---|---|---|---|
| REST API | 410 | GONE | [{"errorCode":"GONE","message":"This API version has been decommissioned..."}] |
| SOAP API | 500 | UNSUPPORTED_API_VERSION | SOAP fault with UNSUPPORTED_API_VERSION faultcode |
| Bulk API v1 | 400 | InvalidVersion | InvalidVersion error in XML response |
| Login API (SOAP) | 500 | UNSUPPORTED_API_VERSION | Cannot authenticate — breaks entire integration |
[src3]
Rate limits are not version-specific — they are org-wide and edition-dependent. However, version retirement effectively sets a rate limit of zero for retired versions. [src1]
| Limit Type | Value | Notes |
|---|---|---|
| Minimum supported version | v31.0 | As of Summer '25; calls below this return errors |
| Versions available simultaneously | ~35 | v31.0-v66.0 as of Spring '26 |
| New versions per year | 3 | Aligned with seasonal releases |
| Minimum support window | 3 years | Per official policy |
| Deprecation notice period | 1 year | For versions actively in use |
Authentication is version-aware — SOAP login uses versioned endpoints, while OAuth 2.0 token endpoints are version-independent. [src2]
| Flow | Version Impact | Notes |
|---|---|---|
| OAuth 2.0 JWT Bearer | Version-independent (/services/oauth2/token) | Version only matters for subsequent API calls |
| OAuth 2.0 Web Server | Version-independent | Pin API version in resource requests, not auth |
| SOAP Login | Version-dependent (/services/Soap/u/{version}/) | Retired version = cannot authenticate at all |
| Username-Password OAuth | Version-independent | Legacy; not recommended |
START — User has a Salesforce integration and needs version guidance
|-- What is your current API version?
| |-- v30.0 or below
| | |-- URGENT: Already retired as of Summer '25
| | |-- Action: Upgrade immediately to v59.0+
| | +-- Generate new WSDL if SOAP; update URL paths if REST
| |-- v31.0-v39.0
| | |-- SAFE for now, but at risk in next retirement wave
| | |-- Action: Plan upgrade within 12 months
| | +-- Target: Latest GA version (v66.0 as of Spring '26)
| |-- v40.0-v55.0
| | |-- Within support window but aging
| | |-- Action: Upgrade during next quarterly maintenance window
| | +-- Focus: Test for breaking changes in release notes
| +-- v56.0+
| |-- Current and fully supported
| +-- Action: Monitor release notes for deprecation announcements
|
|-- How to manage versions going forward?
| |-- Pin to specific version (recommended for stability)
| |-- Always use latest (max feature access, 3x/year testing)
| +-- Stay N versions behind (balanced approach)
|
+-- What API type?
|-- REST/Bulk 2.0 -> Change version number in URL path
|-- SOAP/Metadata -> Regenerate WSDL from current version
|-- Bulk v1 -> Consider migrating to Bulk 2.0 (v41.0+)
+-- Streaming -> Consider migrating to Pub/Sub API (v53.0+)
| Version Range | Status | Retirement Date | Action Required |
|---|---|---|---|
| v7.0-v20.0 | Retired | Summer '22 (June 2022) | Upgrade immediately — calls fail with errors |
| v21.0-v30.0 | Retired | Summer '25 (June 2025) | Upgrade immediately — calls fail with errors |
| v31.0-v39.0 | Supported (aging) | Not yet announced | Plan upgrade within 12 months |
| v40.0-v55.0 | Supported | Not yet announced | Monitor deprecation notices |
| v56.0-v66.0 | Supported (current) | 3+ years from now | No action needed |
| API Version | Release | Milestone Feature |
|---|---|---|
| v34.0 | Summer '15 | Composite API introduced |
| v41.0 | Winter '18 | Bulk API 2.0 introduced |
| v43.0 | Summer '18 | Change Data Capture (CDC) |
| v45.0 | Spring '19 | Lightning Web Components (LWC) GA |
| v47.0 | Winter '20 | Einstein Prediction Builder API |
| v53.0 | Winter '22 | Pub/Sub API introduced |
| v55.0 | Summer '22 | Wave 1 retirement enforced (v7.0-v20.0) |
| v59.0 | Winter '24 | Recommended minimum for new integrations |
| v62.0 | Winter '25 | Retirement enforcement toggle GA |
| v64.0 | Summer '25 | Wave 2 retirement enforced (v21.0-v30.0) |
| v66.0 | Spring '26 | Current latest version |
Query your Salesforce org to see all available API versions. [src1]
# List all supported API versions for your org
curl https://YOUR_INSTANCE.salesforce.com/services/data/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Verify: Response contains an array of version objects with version, label, and url fields.
Use Event Log File Browser or API Total Usage to find integrations on old versions. [src3]
# Query API Total Usage event logs via REST
curl "https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/query?q=SELECT+LogFile+FROM+EventLogFile+WHERE+EventType='ApiTotalUsage'+AND+CreatedDate=TODAY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Verify: CSV file downloaded. Filter API_VERSION column for versions <= 30.0.
Enable voluntary retirement enforcement to identify affected integrations before production. [src3]
Setup > Search "API Version" > Enable "Retirement Enforcement"
This makes deprecated API calls fail immediately in sandbox.
Verify: API calls to retired versions return 410 GONE in sandbox.
For each identified integration, update the version reference. [src4]
# REST API: Change version in URL path
# OLD: /services/data/v28.0/sobjects/Account
# NEW: /services/data/v66.0/sobjects/Account
# SOAP API: Regenerate WSDL from Setup > API > Generate WSDL
# Bulk API: Update version in job creation endpoint
# Recommend migrating to Bulk 2.0:
# NEW: /services/data/v66.0/jobs/ingest
Verify: Integration requests return 200 OK with expected data.
Check release notes for behavioral changes between your old and new version. [src7]
# Test key operations against new version in sandbox
# 1. Authentication
curl -X POST https://YOUR_INSTANCE.salesforce.com/services/oauth2/token \
-d "grant_type=password&client_id=...&client_secret=...&username=...&password=..."
# 2. Query a known record
curl "https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/query?q=SELECT+Id,Name+FROM+Account+LIMIT+1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 3. Create a test record
curl -X POST "https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/sobjects/Account" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"Name":"API Version Test"}'
Verify: All operations return expected results. Compare response schemas between old and new versions.
# Input: Salesforce access token and instance URL
# Output: List of supported API versions and deprecated version usage
import requests
def check_api_versions(instance_url, access_token):
"""List all supported API versions for the org."""
headers = {"Authorization": f"Bearer {access_token}"}
resp = requests.get(f"{instance_url}/services/data/", headers=headers)
resp.raise_for_status()
versions = resp.json()
min_version = float(versions[0]["version"])
max_version = float(versions[-1]["version"])
print(f"Supported range: v{min_version} - v{max_version}")
print(f"Total supported versions: {len(versions)}")
return versions
def find_deprecated_usage(instance_url, access_token, min_safe="31.0"):
"""Query event logs for API calls using deprecated versions."""
headers = {"Authorization": f"Bearer {access_token}"}
soql = (
"SELECT LogFile FROM EventLogFile "
"WHERE EventType='ApiTotalUsage' "
"AND CreatedDate=LAST_N_DAYS:7"
)
resp = requests.get(
f"{instance_url}/services/data/v66.0/query",
params={"q": soql},
headers=headers
)
resp.raise_for_status()
for record in resp.json().get("records", []):
log_url = f"{instance_url}{record['LogFile']}"
log_resp = requests.get(log_url, headers=headers)
print(f"Log file: {log_url}")
// Input: Salesforce credentials, target API version
// Output: API client that validates version before making calls
// npm install [email protected]
const jsforce = require('jsforce');
const MINIMUM_SAFE_VERSION = 31;
const RECOMMENDED_VERSION = 66;
async function createVersionAwareClient(loginUrl, username, password) {
const conn = new jsforce.Connection({
loginUrl,
version: `${RECOMMENDED_VERSION}.0`
});
await conn.login(username, password);
// Verify the version is supported
const versions = await conn.request('/services/data/');
const supported = versions.map(v => parseFloat(v.version));
const min = Math.min(...supported);
const max = Math.max(...supported);
console.log(`Org supports: v${min} - v${max}`);
console.log(`Client using: v${RECOMMENDED_VERSION}.0`);
if (RECOMMENDED_VERSION < min || RECOMMENDED_VERSION > max) {
throw new Error(`Version ${RECOMMENDED_VERSION}.0 not supported`);
}
return conn;
}
# Input: Instance URL and access token
# Output: List of all supported API versions
# Check supported versions (no version number needed in URL)
curl -s https://YOUR_INSTANCE.salesforce.com/services/data/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" | python3 -m json.tool
# Test if a specific version is still supported
curl -s -o /dev/null -w "%{http_code}" \
"https://YOUR_INSTANCE.salesforce.com/services/data/v31.0/sobjects/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 200 = supported, 410 = retired
# Check API usage limits (version-independent)
curl -s https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/limits/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" | python3 -m json.tool
| Code | API | Meaning | Cause | Resolution |
|---|---|---|---|---|
| 410 GONE | REST, Tooling, Connect | Version retired | API version below minimum | Upgrade to v31.0+ (recommended: v59.0+) |
| 500 UNSUPPORTED_API_VERSION | SOAP, Metadata | Version retired | WSDL from retired version | Regenerate WSDL from current version |
| 400 InvalidVersion | Bulk v1, Bulk 2.0 | Version retired or invalid | Retired version in job URL | Update version in job creation endpoint |
| 400 Bad Request | REST | Invalid version format | Malformed version string | Always use vNN.0 format with decimal |
Enable alerting on zero-record API responses and 4xx/5xx status codes. [src3]Separate login WSDL version from data API WSDL version. Update login WSDL first. [src2]Contact ISV for updated package version. Check package API version in Setup > Installed Packages. [src3]Include API version validation in CI/CD pipeline. [src4]Maintain version-flexible integrations or branch per environment. [src3]# BAD -- version will eventually be retired, breaking the integration
SALESFORCE_API_VERSION = "v55.0" # Set once in 2022, never updated
BASE_URL = f"https://myorg.salesforce.com/services/data/{SALESFORCE_API_VERSION}"
# GOOD -- single config point, easy to update, with deprecation checking
import os
SALESFORCE_API_VERSION = os.environ.get("SF_API_VERSION", "v66.0")
BASE_URL = f"https://myorg.salesforce.com/services/data/{SALESFORCE_API_VERSION}"
def check_version_health(instance_url, token):
"""Run at startup to warn about approaching deprecation."""
versions = requests.get(f"{instance_url}/services/data/",
headers={"Authorization": f"Bearer {token}"}).json()
supported = [v["version"] for v in versions]
current = SALESFORCE_API_VERSION.replace("v", "")
if current not in supported:
raise RuntimeError(f"API version {current} is no longer supported!")
idx = supported.index(current)
if idx < len(supported) * 0.2: # Bottom 20% of supported range
print(f"WARNING: Version {current} is aging. Consider upgrading.")
// BAD -- mixing versions causes inconsistent behavior
const accountUrl = '/services/data/v50.0/sobjects/Account';
const contactUrl = '/services/data/v55.0/sobjects/Contact';
const queryUrl = '/services/data/v62.0/query';
// GOOD -- one version, one upgrade path, consistent behavior
const SF_API_VERSION = 'v66.0';
const accountUrl = `/services/data/${SF_API_VERSION}/sobjects/Account`;
const contactUrl = `/services/data/${SF_API_VERSION}/sobjects/Contact`;
const queryUrl = `/services/data/${SF_API_VERSION}/query`;
# BAD -- blindly changing version number without testing
sed -i 's/v50.0/v66.0/g' src/salesforce-client.js
git commit -m "Upgrade SF API version"
git push origin main # Deploy to production untested
# GOOD -- test in sandbox with retirement enforcement enabled
# 1. Update version in feature branch
sed -i 's/v50.0/v66.0/g' src/salesforce-client.js
# 2. Deploy to sandbox
npm run deploy:sandbox
# 3. Run integration test suite
SF_INSTANCE=sandbox npm run test:integration
# 4. Enable retirement enforcement in sandbox
# 5. Run tests again with enforcement enabled
# 6. Review release notes for behavioral changes
# 7. Only then merge and deploy to production
Externalize SF_API_VERSION as an environment variable. [src4]Review release notes for each version between current and target. [src7]Map release names to calendar dates. [src5]Download fresh WSDL from Setup > API > Generate Enterprise/Partner WSDL. [src4]Add Sforce-Call-Options: client=MyApp header to all API calls. [src3]Audit installed packages quarterly. Contact ISVs before retirement deadlines. [src3]# Check all supported API versions for your org
curl -s https://YOUR_INSTANCE.salesforce.com/services/data/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Test if a specific version is supported (200 = yes, 410 = retired)
curl -s -o /dev/null -w "%{http_code}" \
"https://YOUR_INSTANCE.salesforce.com/services/data/v31.0/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Check current API limits (use latest version)
curl -s "https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/limits/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Query event logs for deprecated version usage (last 7 days)
curl -s "https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/query?q=SELECT+LogFile,EventType+FROM+EventLogFile+WHERE+EventType='ApiTotalUsage'+AND+CreatedDate=LAST_N_DAYS:7" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# Check Apex classes for hardcoded API versions
# SOQL: SELECT Name, ApiVersion FROM ApexClass WHERE ApiVersion < 31
# Check installed package API versions
curl -s "https://YOUR_INSTANCE.salesforce.com/services/data/v66.0/tooling/query?q=SELECT+Name,ApiVersion+FROM+ApexClass+WHERE+NamespacePrefix!=null+AND+ApiVersion<31" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
| API Version | Release | Status (Mar 2026) | Breaking Changes | Migration Notes |
|---|---|---|---|---|
| v66.0 | Spring '26 | Current | None yet | Latest recommended version |
| v65.0 | Winter '26 | Supported | SOAP login() removed for some contexts | Check login endpoint |
| v64.0 | Summer '25 | Supported | v21.0-v30.0 retired | Wave 2 retirement enforced |
| v62.0 | Winter '25 | Supported | Retirement enforcement toggle GA | Use for testing deprecation |
| v59.0 | Winter '24 | Supported | None significant | Recommended minimum for new integrations |
| v55.0 | Summer '22 | Supported | v7.0-v20.0 retired | Wave 1 retirement enforced |
| v41.0 | Winter '18 | Supported (aging) | Bulk API 2.0 introduced | Consider Bulk 2.0 migration |
| v31.0 | Spring '14 | Supported (oldest) | None | Current minimum — next wave candidate |
| v30.0 | Spring '14 | Retired | - | Retired Summer '25 — upgrade to v31.0+ |
| v20.0 | Winter '11 | Retired | - | Retired Summer '22 — upgrade to v31.0+ |
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Planning an API version upgrade or migration | Need rate limits or integration patterns for a specific API | Salesforce REST API capabilities card |
| Checking if your current API version is still supported | Need authentication flow details | Salesforce authentication card |
| Understanding the retirement timeline | Need help with a non-Salesforce ERP's versioning | That ERP's versioning card |
| Auditing AppExchange packages for deprecated versions | Need Bulk API migration guidance | Salesforce Bulk API card |
| Setting up CI/CD pipeline version validation | Need Salesforce licensing/edition comparison | Salesforce edition comparison card |