This guide walks a Salesforce admin through everything needed to connect a Bullhorn for Salesforce (BH4SF) org to the integration end-to-end: creating a dedicated integration user, granting the right permissions, creating an External Client App for OAuth, and retrieving the credentials the integration needs.
Estimated time: 30 minutes.
What you'll do
- Create a dedicated integration user in Salesforce.
- Create and assign a Permission Set that gives the integration exactly the access it needs.
- Create an External Client App with the correct OAuth settings.
- Configure the app's policies so it runs as your integration user.
- Retrieve the Consumer Key and Consumer Secret and share them with our team.
- Verify the connection in the integration dashboard.
Before you start
You will need:
- The System Administrator role (or equivalent) in Salesforce so you can create users, Permission Sets, and External Client Apps.
Part 1 — Create a dedicated integration user
1.1 Open the Users page and start a new user
- From Setup, type
Usersinto the Quick Find box and click Users under Users. Click New User.
- Fill in the basics:
- First Name:
API - Last Name:
Integration - Alias:
apiint(auto-fills, adjust if needed) - Email: a real inbox you control (e.g.
ops@yourcompany.com). Verification and password-reset links go here. - Username: must be globally unique across all Salesforce orgs and follow email format, e.g.
integration@yourcompany.com.api. It does not need to be a real inbox — Salesforce just enforces the format. - Nickname: auto-fills from the username.
- First Name:
1.2 Pick a license and profile
In the same form:
- User License: select Salesforce Integration — purpose-built for system-to-system integrations and restricted to API-only flows (which is exactly how this integration connects).
- Profile: select Minimum Access — API Only Integrations. You'll layer the integration's Permission Set on top in Part 2.
- Leave Active ticked and click Save.
1.3 Activate the user
- Salesforce sends a verification email to the address from step 1.1. Open it, click the link, and set a strong password.
- Store the password in your password vault — you may need it for initial login, debugging, or recovery. (Day-to-day, the integration connects via the Client Credentials flow and doesn't reuse this password.)
- Write down the Username (e.g.
integration@yourcompany.com.api). You'll enter it as Run As (Username) when configuring the External Client App policies in Part 3
1.4 Assign the Salesforce API Integration Permission Set License
- From the integration user's detail page.
- Scroll to the Permission Set License Assignments related list and click Edit Assignments.
- Tick Salesforce API Integration and click Save.
- Back on the user page, confirm the Permission Set License Assignments list now shows a row with Permission Set License Label =
Salesforce API Integrationand today's Date Assigned.
Part 2 — Grant the integration the right permissions
The integration's access is scoped through a single Permission Set assigned to the integration user. This keeps that access explicit, auditable, and easy to revoke without touching the user's base Profile.
2.1 Identify your ATS version (v1 vs v2)
Before you set Application permissions, confirm which Bullhorn for Salesforce ATS version your org uses. You'll need System Administrator access to check this.
- From Salesforce, click the gear icon (top-right) → Setup.
In the Quick Find box, search for and select Custom Settings.
Locate TalentRover Properties and click Manage.
Look for the checkbox labeled
Enable New ATS Data Model:- Checked: your org is on ATS v2.
- Unchecked: your org is on ATS v1.
2.2 Clone the TR1 “API User” Permission Set
Bullhorn for Salesforce ships a packaged Permission Set called API User with the namespace prefix TR1. Cloning it — rather than starting from scratch — gives you a baseline that already lines up with the managed package, which you'll then trim and extend in the next sections.
- Click the gear icon (⚙️, top-right) → Setup.
- In the Quick Find box, type
Permission Setsand click Permission Sets under Users. - In the list, find the row where Permission Set Label = API User and Namespace Prefix =
TR1. Click the label to open it. At the top of the Permission Set detail page, click Clone.
On the Clone: API User form, fill in:
- Label:
Integration - API Name:
Integration(auto-fills from the label) - Description: optional, e.g. Permission set for the BH4SF integration user.
- Session Activation Required: leave unchecked.
- Label:
- Click Save.
- Salesforce returns you to the Permission Sets list. Find the row for your newly cloned Integration Permission Set and click its label to open it — this is the detail page where you'll review and adjust Object Settings and System Permissions in the next sections.
2.3 Object Permissions
From the Permission Set page, click Object Settings, then configure each object below.
2.3 Jobs (TR1__Job__c)
- Record Type Assignments
- All
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ❌
- Edit: ✅ (includes Modify All Records)
- Field Permissions
Id,CreatedDate,LastModifiedDate,RecordTypeId,TR1__External_Job_Title__c,TR1__Job_Number__c,TR1__Client_Description__c,TR1__Is_Confidential__c,TR1__Status__c,TR1__Post_Externally__c,TR1__Division__c,TR1__Primary_Background__c,TR1__Level__c,TR1__Street__c,TR1__City__c,TR1__State_Area__c,TR1__Postal_Code__c,TR1__Country__c,TR1__Salary_Low__c,TR1__Salary_High__c,TR1__Open_Date__c,TR1__Closed_Date__c,TR1__LinkedInJobPost_URL__c.
2.4 Contacts (Contact)
- Record Type Assignments
- Candidate
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ❌
- Edit: ❌
- Field Permissions
Id,FirstName,LastName,Email,TR1__Secondary_Email__c,TR1__Work_Email__c,Phone,MobilePhone,HomePhone,Title,TR1__LinkedIn_ProfileUrl__c,TR1__Source__c,TR1__Is_Candidate_Contact__c,CreatedDate,LastModifiedDate,MailingStreet,MailingCity,MailingState,MailingPostalCode,MailingCountry.
2.5 Job Board Applications (TR1__Job_Board_Application__c)
- Record Type Assignments
- None required.
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ❌
- Edit: ✅
Field Permissions
- Ensure
TR1__Status__cis editable (Job Board → Application conversion).
- Ensure
2.6 Tasks (Task)
- Record Type Assignments
- Task
2.7 Application objects — configure ONLY the variant your org uses
2.7.1 Application v1 only (skip if you're on v2)
Short lists (TR1__Application__c)
- Record Type Assignments
- Not applicable.
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ✅
- Edit: ✅
- Field Permissions: read & edit access
Id,CreatedDate,LastModifiedDate,TR1__Job__c,TR1__Applicant__c,TR1__Stage__c,TR1__Status__c,TR1__Rejection_Notes__c,TR1__Job_Reporting__c
Job Reporting (TR1__Job_Reporting__c)
- Record Type Assignments
- Not applicable.
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ✅
- Edit: ✅
Field Permissions
2.7.2 Application v2 only (skip if you're on v1)
Application V2 (TR1__Application_V2__c)
- Record Type Assignments
- All
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ✅
- Edit: ✅
- Field Permissions: read & edit access
Id,CreatedDate,LastModifiedDate,TR1__Job__c,TR1__Applicant__c,TR1__Stage__c,TR1__Reject__c,TR1__Rejection_Reason__c,TR1__Closing_Report__c
Placements (TR1__Placement__c)
- Record Type Assignments
- Placement
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ❌
- Edit: ❌
Application History
- Record Type Assignments
- Not applicable.
- Object Permissions
- Read: ✅ (includes View All Records)
- Create: ✅
- Edit: ✅
Field Permissions
2.5 Custom Setting Definitions
Two of the required entitlements are Custom Settings, not standard or custom objects. Custom Settings live on a separate page from Object Settings — granting them via the Object Settings flow won't work.
| Name | API Name | Required? | Why |
|---|---|---|---|
| TalentRover Properties | TR1__TalentRoverProperties__c | Always | Detect v1 vs. v2 ATS data model at connect time. |
| ATS Job AppV2 Picklist Mapping | TR1__ATS_Job_AppV2_Picklist_Mapping__c | v2 only | Resolve which application stages are valid per Job Record Type. |
To enable them:
From the Integration Permission Set overview, click Custom Setting Definitions.
On the Custom Setting Definitions page, click Edit.
In the Available Custom Setting Definitions list, select each setting above and click Add to move it into Enabled Custom Setting Definitions. If your org is on v1, only add TR1.TalentRover Properties.
- Click Save.
2.6 System Permissions
From the Permission Set page, click System Permissions → Edit and enable the following:
| Permission |
|---|
| API Enabled |
| Access Activities |
| Edit Tasks |
| API Only User |
2.7 Assign the Permission Set
- Open your Integration Permission Set.
Click Manage Assignments → Add Assignment.
- Select your integration user → Next → Assign.
Part 3 — Create the External Client App
The integration authenticates via OAuth 2.0 against an External Client App in your Salesforce org. The next steps create that app and configure it for the Client Credentials flow.
3.1 Open the App Manager
- From Salesforce, click the gear icon (top right) → Setup.
- In the left-hand Quick Find menu, navigate to Platform Tools → Apps → App Manager.
- On the top right of the Lightning Experience App Manager page, click New External Client App.
3.2 Basic information
Fill in:
- External Client App Name — a descriptive name, e.g.
integration-app. - API Name — auto-fills (e.g.
integration_app); hyphens become underscores. - Contact Email — the developer or administrative contact email.
3.3 Enable and configure OAuth
Scroll to the API (Enable OAuth Settings) section:
- Check Enable OAuth.
- Enter the Callback URL for your environment — this is the only field that differs between Sandbox and Production:
- Sandbox:
https://test.salesforce.com/services/oauth2/success - Production:
https://login.salesforce.com/services/oauth2/success
- Sandbox:
- Under Available OAuth Scopes, move Manage user data via APIs (api) into Selected OAuth Scopes.
OAuth settings
3.4 Flow enablement & security
Scroll further down to configure the allowed flows and security parameters.
- Under Flow Enablement, check:
- [ ] Enable Client Credentials Flow
- [ ] Enable Authorization Code and Credentials Flow
- [ ] Enable Token Exchange Flow
- Under Security, ensure the following standard protections are enabled (usually defaults):
- [ ] Require secret for Web Server Flow
- [ ] Require secret for Refresh Token Flow
- [ ] Require Proof Key for Code Exchange (PKCE) extension
- [ ] Enable Refresh Token Rotation
- Click Save.
3.5 Configure App Policies
Once saved, you need to set the execution user for the Client Credentials flow.
- On the Manage External Client Apps screen for your new app, open the Policies tab.
Scroll down and click Edit on the right side of the page.
- Scroll to the OAuth Flows and External Client App Enhancements section and check Enable Client Credentials Flow.
- In the Run As (Username) field, enter the Username of the dedicated integration user you created in Part 1 and assigned the Permission Set to in Part 2 (e.g.
integration@yourcompany.com.api). - Click Save.
The Run As user must be the same user that has the Integration Permission Set assigned. The Client Credentials flow runs entirely as this user — its permissions are what the integration will have at runtime.
Part 4 — Retrieve the Consumer Key and Secret
- Salesforce requires a high-assurance session — you'll be prompted to verify your identity (usually a code sent to your email or authenticator app).
- After verifying, you'll see both the Consumer Key and Consumer Secret.
- Click Copy next to each value and store them in your secure vault or password manager.
Part 5 — Verify the connection
- In the integration dashboard, start the Bullhorn for Salesforce connection flow.
- Provide the Consumer Key and Consumer Secret from Part 4.
- The integration runs an automatic permission test that checks every object and field above against your org's.