Salesforce offers a powerful Standard REST API to interact with core objects and actions, including system-level operations such as:
- Canceling approval submissions
- Invoking orchestration or flow actions
- Managing metadata or data externally
But here’s the catch:
Even though you’re calling the API from Salesforce itself, you can’t always reuse the existing Apex session ID for authentication.
If you try to directly use the current Apex session with a REST API callout to your own org, Salesforce will reject it with an error like:
INVALID_SESSION_ID: This session is not valid for use with the API.
Let’s understand why this happens — and the two reliable authentication methods available to handle it.
Why You Can’t Use UserInfo.getSessionId() in Apex
At first glance, it seems logical: since you’re already logged into Salesforce, the current session should authorize API requests to the same org.
However, this session ID is scoped for the UI (Lightning, Flow, or Platform Context) and not valid for API callouts made from Apex.
Salesforce treats callouts — even to itself — as external API requests, requiring a valid OAuth 2.0 token or session from an API-authorized context.
Hence, if you use:
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
You’ll encounter:
INVALID_SESSION_ID: This session is not valid for use with the API.
This is a security restriction to prevent Apex code from misusing UI sessions for backend API access.
Solution 1: Connected App + Auth Provider + Named Credential
This is the recommended, secure, and maintainable approach to call Salesforce’s own Standard APIs from Apex or Flow.
Step 1: Create a Connected App
- Navigate to Setup → App Manager → New Connected App
- Fill in details:
- Name: SelfSalesforceConnectedApp
- Callback URL: https://login.salesforce.com/services/oauth2/callback
- Enable OAuth Settings:
- Select “Enable OAuth Settings”
- Choose OAuth Scopes:
- Full access (full)
- Perform requests on your behalf at any time (refresh_token, offline_access)
- Save and note the Consumer Key and Consumer Secret.
Step 2: Create an Auth Provider
- Navigate to Setup → Auth. Providers → New
- Choose Provider Type: Salesforce
- Enter details:
- Name: SelfSalesforce_AuthProvider
- Consumer Key/Secret: From your Connected App
- Save and copy the Callback URL into your Connected App’s callback URL (loopback).
Step 3: Create a Named Credential
- Go to Setup → Named Credentials → New Named Credential
- Details:
- Label: SelfSalesforce_NC
- URL: https://yourInstance.salesforce.com
- Authentication Protocol: OAuth 2.0
- Auth Provider: SelfSalesforce_AuthProvider
- Scope: full refresh_token offline_access
- Save.
Step 4: Use It in Apex
Now you can securely make REST calls to Salesforce’s own APIs, with no manual token handling:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:SelfSalesforce_NC/services/data/v65.0/actions/standard/cancelApprovalSubmission');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody('{"inputs":[{"approvalSubmissionId":"9iPxx00000001lhEBA","comments":"Canceled via API"}]}');
Http http = new Http();
HttpResponse res = http.send(req);
System.debug('Response: ' + res.getBody());
The OAuth token is managed automatically via the Named Credential.
Solution 2: Visualforce Page Session Approach
You can generate a valid session ID usable for API calls via a Visualforce page.
Step 1: Create a Visualforce Page
<apex:page id="ApiSessionId>
{!$Api.Session_ID}
</apex:page>
This $Api.Session_ID value is a UI context session that’s valid for REST API use, unlike UserInfo.getSessionId() in Apex.
Step 2: Access It from Apex
Call it to retrieve the session ID dynamically, then reuse it in a REST callout from Apex:
public class SessionUtil
{
public static String getSessionFromVF()
{
String pageContent = Page.ApiSessionId.getContent().toString();
return pageContent;
}
}
Key Takeaways
- UserInfo.getSessionId() cannot be used for REST API callouts → it’s UI scoped.
- Use Named Credentials with Auth Provider for secure OAuth authentication.
- If you call Salesforce APIs from Salesforce itself, it’s still an external API call from Apex’s perspective.
- Connected App authentication provides refresh tokens, token renewal, and audit tracking automatically.