Overview
This guide walks you through setting up OAuth with refresh tokens to query Salesforce records via the REST API. This approach allows your application to maintain long-term API access without requiring users to re-authenticate frequently.
Prerequisites
Salesforce org (Production or Sandbox)
System Administrator access
Basic understanding of HTTP requests and OAuth 2.0
Part 1: Connected App Setup
Step 1: Create Connected App
Go to Setup → Apps → App Manager
Click New External Client App
-
Fill in basic information:
External Client App Name: Your app name
API Name: Auto-generated
Contact Email: Your email
Step 2: Enable OAuth Settings
Check Enable OAuth Settings
Set Callback URL:
https://login.salesforce.com/services/(or your custom URL)-
Selected OAuth Scopes - Add these scopes:
Full access (full)
Manage user data via APIs (api)
Perform requests at any time (refresh_token, offline_access)
Access unique user identifiers (openid)
Click Create
Step 3: Configure OAuth Policies
After clicking 'Create,' make sure you are on the Policies page, then click 'Edit' to modify the OAuth policies.
-
Set these policies:
Permitted Users: "All users may self-authorize"
IP Relaxation: "Relaxed IP restrictions"
Refresh Token Policy: "Refresh token is valid until revoked"
Session Timeout: Set to desired duration (e.g., 1440 minutes for 24 hours)
Step 4: Enable Authorization Code Flow
Next, navigate from the Policies page to the Settings page for your External Client App, then click 'Edit.'
-
Locate the Flow Enablement section, check:
Enable Authorization Code and Credentials Flow
Step 6: OAuth Security
Make sure that only 'Require secret for Refresh Token Flow' is selected.
Step 5: Get Client Credentials
In the OAuth Settings section, click on 'Consumer Key and Secret.'
Note down your Consumer Key (Client ID) and Consumer Secret (Client Secret)
Part 2: OAuth Flow Implementation
Step 1: Get Authorization Code
Direct users to this URL (replace placeholders):
Replace the following placeholders:
YOUR_BASE_URL_HERE, if necessary
YOUR_CLIENT_ID with your Client ID that you noted earlier
YOUR_REDIRECT_URI with the Callback URL you previously set under OAuth Settings
For Production:
https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=full+api+refresh_token+openidFor Sandbox:
https://YOUR_BASE_URL_HERE/services/oauth2/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=full+api+refresh_token+openidNote: Some production or sandboxes environments may require using your instance base URL instead of http://test.salesforce.com
Example:
https://YOUR_BASE_URL_HERE/services/oauth2/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=full+api+refresh_token+openidStep 2: Retrieve Authorization Code
-
Copy the URL you formatted in Step 1 and paste it into your browser. You will then be redirected to a page stating that the URL no longer exists. However, notice that the URL in your browser has changed to something similar to the following:
https://usa930.sfdc-6sgtt3.salesforce.com/services/?code=YOUR_ACCESS_CODE_HERE&InstHostname=login.salesforce.com
The authorization code is generated by Salesforce using Base64 encoding. As a result, your code may include %3D%3D at the end, which represents ==. For Step 3, ensure your authorization code is properly formatted, for example:
a23dfkljsdafsdfklgnjalk32n25assfdalhgsfkhlgnadlkmfasg==
Step 3: Exchange Authorization Code for Tokens
After the user authorizes access, exchange the authorization code for tokens using a tool such as Postman or, in this example, Logic+.
Copy the JSON file named
getRefreshTokeninto Logic+, then save and publish it.In the Request Body section of the Logic+ integration panel, replace the placeholders with the values you obtained during this process.
From the Integration section of the panel, confirm that the correct base URL is selected.
You must already have your integration base URL configured for this API call. If it is not yet set up, review the Initial Salesforce Integration Configuration documentation before proceeding.
Click Test. If successful, you will receive a 200 response.
-
Select Click to View Response, then copy the payload and save it in a secure location. You will need the Refresh Token later when storing it in a SharpenDB table (see Storing the Salesforce Token in SharpenDB).
-
Example Response:
{ "access_token": "00D...", "refresh_token": "5Aep...", "instance_url": "https://yourinstance.salesforce.com", "id": "https://login.salesforce.com/id/00D.../005...", "token_type": "Bearer", "issued_at": "1625097600000", "signature": "...", "scope": "full api refresh_token openid" }
-
getRefreshToken JSON
{
"panels":[
{
"type": "integration",
"initiator": true,
"name": "getRefreshToken",
"coordinates": {
"x": -1167.0243766237752,
"y": -143.42998785101025
},
"fields": {
"integrationId": "004hq3tmn7b4pyfv84",
"path": "/services/oauth2/token",
"method": "POST",
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"requestBody": {
"grant_type": "authorization_code",
"code": "YOUR_AUTHORIZATION_CODE",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "YOUR_OAUTH_CALLBACK_URL"
},
"contentType": "Form Data",
"timeout": 3,
"variables": [],
"fireAndForget": false
},
"exits": {
"default": "",
"timeout": "",
"error": ""
},
"version": "2.2.0",
"description": "API call to retrieve Salesforce Refresh Token"
}
]
}Part 3: Production Considerations
Security Best Practices
Store tokens securely
Implement proper token rotation
Set appropriate session timeouts
Monitor for suspicious activity
Token Management
Access Token Lifespan: Based on your Connected App's session timeout setting
Refresh Token Lifespan: Until revoked or user changes password
Rate Limiting
Salesforce has API request limits
Monitor your API usage in Setup → System Overview
Implement retry logic and failsafes
Troubleshooting Common Issues
Issue: "INVALID_SESSION_ID" Error
Causes:
Wrong authorization header format (use "Bearer" not "OAuth")
Access token expired
Missing required OAuth scopes
Different Connected Apps with different configurations
Solutions:
Verify header:
Authorization: Bearer YOUR_TOKENRefresh your access token
Ensure Connected App has "Full access (full)" scope
Use consistent Connected App for all flows
Issue: Scope Only Shows "refresh_token"
Cause: Authorization URL missing explicit scope parameter Solution: Include &scope=full+api+refresh_token+openid in authorization URL
Issue: Getting Same Access Token on Refresh
Cause: Current token hasn't expired yet Solution: This is normal behavior - Salesforce returns cached valid tokens
Conclusion
This OAuth refresh token implementation provides:
Long-term API access without frequent re-authentication
Automatic token refresh capabilities
Secure access to Salesforce data
Remember to monitor your API usage, implement proper error handling, and follow Salesforce security best practices for production deployments.
For additional details, refer to Salesforce OAuth Documentation.
For token management, refer to Managing SFDC Token