Skip to main content
Softlimes Home
Softlimes
← Back to all articles•Development•7 min read

Integrating Bullhorn CRM With a Custom Laravel Recruitment Website

Ivan

Ivan

Lead Engineer & Strategist at Softlimes

Integrating Bullhorn CRM With a Custom Laravel Recruitment Website

Why Live Bullhorn API Calls on Page Load Slow Down Job Boards

Some recruitment plugins fetch open job listings directly from the Bullhorn REST API every time a candidate visits the careers page. That design fails as soon as traffic increases or a Google Ads campaign sends hundreds of applicants at once. External CRM API calls add latency to every page view and quickly hit rate limits.

When Googlebot crawls a slow or rate-limited job page, your job postings drop out of Google for Jobs search results. A high-performing recruitment site must serve job listings from a local indexed database while syncing with Bullhorn in the background.

Managing Bullhorn OAuth2 Flow and Session RestTokens in Redis

Bullhorn uses a multi-step authentication flow that requires exchanging an authorization code for an OAuth access token and refresh token, then trading that access token for a Bullhorn REST session token and regional base URL. If two concurrent worker processes attempt to use the same refresh token simultaneously, one process invalidates the token for the other.

We solve this in Laravel by wrapping token refresh inside a Redis atomic lock. Only one worker refreshes the OAuth credentials when a session expires, stores the new BhRestToken and regional restUrl in encrypted cache, and releases the lock for all other queued jobs.

  • Sync published JobOrder records from Bullhorn into local PostgreSQL tables every five minutes via scheduled delta queries.
  • Render Schema.org JobPosting JSON-LD markup on every job URL so listings appear directly in Google for Jobs.
  • Deduplicate incoming applicants by checking email and mobile number against Bullhorn Candidate entities before creating a new record.
  • Queue PDF resume file attachments and JobSubmission creation so candidate form submissions return in under 300 milliseconds.

Fast Local Job Search With Faceted Category and Salary Filters

By storing published Bullhorn jobs in our local Laravel database, candidates can filter roles by sector, contract type, location radius, and salary band with instant response times. When a recruiter closes a role or marks a job as filled inside Bullhorn, our background sync removes the public application button and displays similar open roles instead of returning a broken 404 page.

Keeping expired job URLs live with a clear status notice and related job links preserves the organic SEO authority that your agency builds from external backlinks and job aggregators.

Reliable Candidate Application Queues and Recruiter Notifications

When a candidate submits their CV on the website, our controller validates the file, saves the application locally first, and dispatches a queued sync job to Bullhorn. Even if Bullhorn undergoes scheduled maintenance at midnight, zero candidate applications are lost.

The background worker creates or updates the Candidate profile, uploads the original CV file to the Files endpoint, links a JobSubmission record to the exact JobOrder ID, and notifies the assigned consultant with a direct link to the Bullhorn record.

Related Softlimes Service

Laravel Development

See how our engineering team scopes, builds, and supports this workflow in production.

Explore Service →

Related articles by Ivan

Work With Us

Need engineering or marketing help on your next release

Talk directly with Ivan and the Softlimes engineering team to scope your web application, online store, AI workflow, or search campaign.