Skip to content
Solutions Blueprint

Architecting a Relational Recruitment RevOps Engine via HubSpot Custom Objects

Hero featured image

Flat ATS-to-CRM syncs destroy relational data vital for recruitment ROI reporting. For an executive search firm, we engineered a multi-object schema in HubSpot (Jobs, Placements, Functions, Attendance) integrated with Bullhorn via Pipedream. This structure enables gated candidate portals, automated placement reporting, and high-touch event-led growth strategies.

Executive Summary

context-header-icon

Context

An executive search firm was moving its website and marketing from a legacy recruitment CMS to HubSpot while keeping Bullhorn as its ATS. The firm wanted to unify recruitment operations with marketing automation and drive closed-loop reporting.

what-we-built-header-icon

What We Built

A complex relational data model in HubSpot using four distinct Custom Objects and a gated candidate portal controlled via CMS Membership Lists.

tech-stack-header-icon

Tech Stack

  • HubSpot Marketing & CMS Hub Enterprise
  • HubSpot Custom Objects (Jobs, Placements, Functions, Attendance)
  • Bullhorn REST API
  • Pipedream (Relational Middleware)
  • HubSpot Membership Lists (Authentication Layer)

Not a fit if your ATS does not track placements or event attendance as distinct records, or if you have no middleware layer capable of syncing that relational data into HubSpot. The reporting and portal access logic here depends on real-time status changes flowing from the ATS into four synced custom objects; without that source data feeding the sync, there is nothing for the workflows to act on.

the-challenge-header-icon

The Challenge

Bullhorn's deeply nested data structure was the constraint: standard off-the-shelf connectors can't replicate it. Mapping the many-to-one relationship, where a single candidate has multiple placements and event attendance records, required a schema that HubSpot's standard objects could not support. The CMO called it dark data: they knew candidates were getting placed, but that data existed only in the ATS, so they couldn't see which marketing workflows or job alerts were actually driving revenue.

our-approach-header-icon

Our Approach

We bypassed simple sync tools in favour of a custom Pipedream integration that maintains the relational integrity of the Bullhorn database. We prioritized building a Placements custom object to bridge the gap between application and revenue. Access to the candidate portal ran through HubSpot Membership Lists, triggered by a candidate's status in the ATS. That let us gate the "Functions" and "Attendance" objects, so exclusive industry event data stayed visible only to authenticated, high-value leads. That gave the technical team a stable database and the CMO a full-funnel view of the recruitment lifecycle.

This engagement is part of our customization + optimization work for professional services organisations.

impact-header-icon

Impact

check-icon

Closed-Loop Revenue Attribution

By syncing "Placements" as a custom object, the marketing team can now attribute search revenue directly to specific job alerts or website interactions. This moved the CMO from reporting on "leads" to reporting on "placed revenue."
check-icon

Event-Led Growth Capabilities

The inclusion of "Functions" and "Attendance" objects allows the firm to track and automate networking at scale. Marketing can now trigger personalized follow-ups based on real-world event engagement, a high-value signal in executive search.
check-icon

Self-Service Portal for 14,000+ Candidates

Using Membership Lists for authentication provided a secure, zero-friction portal for 14,000+ candidates. Job seekers can manage their own preference data, which updates both HubSpot and Bullhorn, so recruiters always work with the most current candidate information.

check-icon

Operational Parity with Specialized ATS

The multi-object architecture recreates the power of a specialized recruitment platform within a generalist CRM. This consolidation reduced the firm’s tech debt by allowing them to sunset legacy tools without losing the relational depth required for search operations.
Technical Blueprint
1

The integration layer handles complex POST requests to four different HubSpot object schemas. It uses the Bullhorn "Placement ID" and "Candidate ID" as primary keys, so records associate correctly across the HubSpot CRM.

2
Authentication is handled via a dynamic "Active Candidate" list in HubSpot. When a record in Bullhorn changes state, the middleware updates the HubSpot contact record, automatically granting or revoking access to the CMS Membership portal and its gated content.
3
We built custom reports that join data from the "Jobs" and "Placements" objects. This allows for real-time dashboards that show time-to-fill, placement-by-industry-vertical, and the conversion rate from job-board-view to final placement.
4

The "Functions" and "Attendance" objects manage recruitment events. Attendance carries a Role (Speaker, Attendee, VIP) and a Status (Invited, Registered, Attended), and Pipedream creates the record when a candidate joins the event shortlist in Bullhorn. Workflows trigger based on a change in the "Attendance" status (e.g., "Checked-in"), sending automated, recruiter-personalized emails that reference the specific event attended.

Bullhorn candidate, placement, function and attendance records mapped to HubSpot custom objects through Pipedream.

One candidate in Bullhorn can have many placements and event attendance records. Standard connectors can't replicate that nesting, and HubSpot's standard objects couldn't hold it. So we built a custom Pipedream integration that keeps the relational structure, with a Placements custom object. Membership Lists driven by ATS status gate the Functions and Attendance objects. Marketing can now attribute search revenue to specific job alerts or website interactions.

FAQ

Why use multiple custom objects instead of just one for "Recruitment Data"?
Using distinct objects for Jobs, Placements, and Events allows for accurate one-to-many relationships. A single candidate might have one "Contact" record but multiple "Placement" and "Attendance" records over their career. Combining these into one object would destroy the historical data integrity needed for recruitment analytics.
How do the Membership Lists stay in sync with Bullhorn?
The middleware monitors the "Status" field in Bullhorn. Any change triggers a webhook that updates a corresponding "Status" property in HubSpot. Because the Membership access is tied to an Active List based on that property, access is updated in near-real-time without manual intervention.
footerCTA footerCTA-mobile
Spice up your inbox
Sign up for our newsletter
Don't worry - we only average, like, two emojis per subject line.