HRMS migration
Field-level mapping, validation, and rollback between JOIN and Bullhorn ATS & CRM. We move data and schema; workflows are rebuilt natively in Bullhorn ATS & CRM.
JOIN
Source
Bullhorn ATS & CRM
Destination
Compatibility
10 of 12
objects map 1:1 between JOIN and Bullhorn ATS & CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Moving from JOIN to Bullhorn restructures a recruiting database from JOIN's job-centric model into Bullhorn's entity-relationship model. In JOIN, Jobs are the parent container with Candidates as children and Applications as the join table; in Bullhorn, JobOrder is the parent, Candidate and ClientCorporation are separate entities, and JobSubmission links them. We resolve that structural difference during scoping by extracting the per-job stage sequence, building the Bullhorn JobOrder schema with matching custom status values, and sequencing the parent-load before Candidate insert so every foreign-key constraint is satisfied at migration time. Activity history cannot be pulled from JOIN's API, so we ingest it from a dashboard CSV export and attach it to each candidate record in Bullhorn as a Note or custom activity block. Workflows, email sequences, and job board credits do not migrate; we deliver a written inventory for the customer's admin to rebuild.
Every standard and custom field arrives verified.
AI proposes the map; you confirm before any record moves.
Parent–child, lookups, and ownership stay linked.
Calls, emails, meetings — with original timestamps.
Documents, uploads, and inline notes move with the record.
Why teams make this switch
Leaving
What's pushing teams away
Choosing
What's pulling them in
Object mapping
Each row shows how a JOIN object lands in Bullhorn ATS & CRM, including any object-level transformations, lookup resolution, or schema-design dependencies.
Typical mapping — final map is confirmed during the sample migration step.
JOIN
Job
Bullhorn ATS & CRM
JobOrder
1:1JOIN Jobs map to Bullhorn JobOrder. We extract the full job record (title, description, department, location, employment type, posting status) and map it to the Bullhorn JobOrder standard fields. The Bullhorn JobOrder must be inserted before any Candidate or JobSubmission records because JobSubmission references JobOrderID as a foreign key. If the JOIN job posting has expired or is closed, we preserve the status and set JobOrder.isDeleted or isClosed accordingly.
JOIN
Candidate
Bullhorn ATS & CRM
Candidate
1:1JOIN Candidate records map directly to Bullhorn Candidate with contact info, work history, education, skills tags, and source attribution. The Candidate's current pipeline stage from JOIN migrates as a custom Candidate text field because Bullhorn's standard status values are scoped to JobSubmission rather than Candidate. We resolve Candidate duplicates by email dedupe before insert.
JOIN
Application
Bullhorn ATS & CRM
JobSubmission
1:1JOIN Applications (the join table linking a Candidate to a Job) map to Bullhorn JobSubmission. The mapping preserves applied date, referral source, and rejection or offer flags. JobSubmission is inserted after both JobOrder and Candidate are loaded so that JobOrderID and CandidateID foreign keys are satisfied. A rejection or offer on the JOIN Application maps to JobSubmission.status with the corresponding Bullhorn status value.
JOIN
Pipeline Stage (per-job)
Bullhorn ATS & CRM
JobSubmission Status + Sales Process
lossyJOIN exposes no universal stage schema; each job carries its own stage sequence that varies by plan. We extract the full stage list per job during the scan phase and build a customer-specific mapping table. In Bullhorn, we scope stage values to the JobOrder's Sales Process and record type. Where JOIN has more stages than Bullhorn supports, we collapse intermediate stages and preserve the stage-entry date as a custom field on JobSubmission so no timing context is lost.
JOIN
Scorecards and Interview Feedback
Bullhorn ATS & CRM
Note + Custom Fields
1:1Structured interview evaluations from JOIN migrate as Bullhorn Note records attached to the JobSubmission or Candidate. Where the evaluation uses a rubric with numeric scores, we map each criterion to a custom Candidate field or JobSubmission custom field. Free-text feedback migrates as Note body text with the interviewer name and interview date in the Note title.
JOIN
Custom Fields (Jobs)
Bullhorn ATS & CRM
JobOrder Custom Fields
1:1JOIN employer-defined custom fields on Jobs map to Bullhorn JobOrder custom fields. Bullhorn supports ~55 custom fields per entity. We detect all JOIN Job custom fields during the scan, validate the count against Bullhorn's limit, and flag any overflow to the customer for custom object design. Custom fields are created in Bullhorn via the Field Mappings admin panel before data load.
JOIN
Custom Fields (Candidates)
Bullhorn ATS & CRM
Candidate Custom Fields
1:1JOIN Candidate custom fields map to Bullhorn Candidate custom fields. Bullhorn's custom field limit per entity (~55 fields) may require a custom object or a JSON-serialised text block for fields exceeding the limit. We surface the full custom field schema at scoping, confirm the intended mapping with the customer, and create the destination fields before migration. Custom fields that cannot map to typed Bullhorn fields land as free-text custom properties and can be restructured post-migration.
JOIN
Attachments and Resume Files
Bullhorn ATS & CRM
Candidate Resume + ContentDocument
1:1Candidate resume files and supporting documents export from JOIN and upload to Bullhorn as Candidate resume files or ContentDocument records linked via ContentDocumentLink. JOIN file naming uses internal IDs that we normalise to CandidateName_JobTitle_Date during export to prevent filename collisions and ensure files are identifiable in Bullhorn. We validate each file uploads successfully before marking the Candidate record as complete.
JOIN
Owner
Bullhorn ATS & CRM
User
1:1JOIN Owners map to Bullhorn User records. We match by email address against the Bullhorn destination User table. Any JOIN Owner without a matching Bullhorn User goes to a reconciliation queue for the customer's Bullhorn admin to provision before record import resumes. Migration cannot proceed past User reconciliation because User references are required on JobOrder, Candidate, and JobSubmission.
JOIN
Client / Company
Bullhorn ATS & CRM
ClientCorporation
1:1If JOIN stores employer company records separate from Jobs, those map to Bullhorn ClientCorporation. ClientCorporation is created before JobOrder when a client record exists in JOIN, providing the ClientCorporationID for the JobOrder foreign key. JOIN employer-branding data (company description, website, industry) maps to the corresponding ClientCorporation standard fields.
JOIN
Activity and Communication History
Bullhorn ATS & CRM
Note + CSV Ingest
1:1JOIN does not expose email threads, scheduled events, or interview activity through a documented API endpoint. We require the customer to export this data as a CSV from the JOIN dashboard before cutover. We ingest the CSV alongside the API extract, normalise the activity data (email body, event date, interviewer name), and attach each entry as a Bullhorn Note linked to the Candidate or JobSubmission. Stage-entry timestamps from JOIN also land as custom date fields on JobSubmission, preserving the original pipeline timing context.
JOIN
Job Posting Board Distribution
Bullhorn ATS & CRM
JobOrder Distribution Settings
lossyJOIN's 250+ job board distribution network has no direct Bullhorn equivalent as a native feature. Bullhorn distributes job postings through its integrated job board connectors and the Bullhorn Marketplace (350+ partner integrations). We document each active JOIN job board posting as a JobOrder custom field or an external reference note so the customer's Bullhorn admin can re-enable distribution on the equivalent Bullhorn-integrated board at their preferred time.
| JOIN | Bullhorn ATS & CRM | Compatibility | |
|---|---|---|---|
| Job | JobOrder1:1 | Fully supported | |
| Candidate | Candidate1:1 | Fully supported | |
| Application | JobSubmission1:1 | Fully supported | |
| Pipeline Stage (per-job) | JobSubmission Status + Sales Processlossy | Fully supported | |
| Scorecards and Interview Feedback | Note + Custom Fields1:1 | Mapping required | |
| Custom Fields (Jobs) | JobOrder Custom Fields1:1 | Fully supported | |
| Custom Fields (Candidates) | Candidate Custom Fields1:1 | Fully supported | |
| Attachments and Resume Files | Candidate Resume + ContentDocument1:1 | Mapping required | |
| Owner | User1:1 | Fully supported | |
| Client / Company | ClientCorporation1:1 | Fully supported | |
| Activity and Communication History | Note + CSV Ingest1:1 | Not supported | |
| Job Posting Board Distribution | JobOrder Distribution Settingslossy | Fully supported |
Gotchas + challenges
Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.
JOIN gotchas
Activity log and communication history are not exported via JOIN API
Pipeline stage names vary per job and per plan
Custom fields on Candidates require manual equivalence review
Resume and attachment export format is non-standard
Bullhorn ATS & CRM gotchas
ATS Growth edition has no API access
Attachments excluded from CSV bulk exports
Custom Object limits vary sharply by edition
Opportunity pipeline stages are recruitment-specific
Resume parse quality varies by document format
Pair-specific challenges
Migration approach
Discovery and scoping
We audit the JOIN portal across Jobs, Candidates, Applications, custom fields (per job and per candidate), per-job pipeline stage sequences, active scorecard templates, and attachment volumes. We pair this with the customer's Bullhorn edition confirmation (Starter, Core, or Pro) to validate custom field and custom object limits. We provide the customer with JOIN dashboard export instructions for activity history CSV and confirm the expected record counts before producing a written migration scope and mapping table.
Schema design and Bullhorn configuration
We design the Bullhorn destination schema: JobOrder custom fields (mapped from JOIN Job custom fields), Candidate custom fields (mapped from JOIN Candidate custom fields), JobSubmission status values scoped per Sales Process, and any custom objects required for JOIN schema elements that exceed Bullhorn's per-entity field limits. Bullhorn Field Mappings (Admin > Field Mappings) are configured for each entity before any data load. Schema is validated in a Bullhorn sandbox or test environment first.
Sandbox migration and reconciliation
We run a full migration into the customer's Bullhorn sandbox environment using production-like data volumes. The customer's Bullhorn admin reviews record counts (JobOrders, Candidates, JobSubmissions), spot-checks 25-50 candidate records against the JOIN source, and validates that pipeline stages, custom field values, and resume files appear correctly. Any mapping corrections are made at this stage before production migration begins.
Owner reconciliation and User provisioning
We extract every distinct JOIN Owner referenced on Job, Candidate, and Application records and match by email against the Bullhorn destination User table. Any Owner without a matching Bullhorn User is held in a reconciliation queue. The customer's Bullhorn admin provisions missing Users (active or inactive depending on whether the original JOIN user is still with the firm) before the production migration begins, because UserID references are required on JobOrder, Candidate, and JobSubmission.
Production migration in dependency order
We run production migration in the correct foreign-key sequence: ClientCorporation records (if applicable), JobOrders with the per-job stage schema configured, Candidates with dedupe by email, JobSubmissions with JobOrderID and CandidateID resolved, then custom fields, attachments (normalised filenames), and finally the activity history CSV ingested as Notes. Each phase emits a row-count reconciliation report. Bullhorn's REST API rate limits are respected through exponential backoff and batch chunking.
Cutover, validation, and handoff
We freeze JOIN writes during the cutover window, run a final delta migration of records modified during the migration, then enable Bullhorn as the system of record. We deliver a written inventory of any JOIN workflows, email sequences, or job board distribution settings requiring manual rebuild in Bullhorn (via Bullhorn Automation or the Marketplace integrations). We support a one-week post-cutover window for reconciliation issues. We do not rebuild JOIN automations as Bullhorn automations inside the standard migration scope; that is a separate engagement.
Platform deep dives
JOIN
Source
Strengths
Weaknesses
Bullhorn ATS & CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard HRMS migration. 1 of 7 objects need a mapping; the rest are 1:1.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across JOIN and Bullhorn ATS & CRM.
Object compatibility
1 of 7 objects need a mapping; the rest are 1:1.
Field mapping clarity
Field mapping is derived from defaults — final spec confirmed during the sample migration.
Timeline complexity
7-object category — typical timelines run 2–7 days end-to-end.
API constraints
JOIN: Not publicly documented.
Data volume sensitivity
JOIN doesn't expose a bulk API — REST + parallelization used for high-volume runs.
Estimator
Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.
Step 1
Pick a category, then your source and destination platforms.
Category
FAQ
Answers to the questions buyers ask most during JOIN to Bullhorn ATS & CRM migration scoping. Not seeing yours? Book a call.
Walk through your JOIN to Bullhorn ATS & CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.
Book a free 30 minute consultationAdjacent paths
Other ways to leave JOIN
Other ways to arrive at Bullhorn ATS & CRM
Ready when you are
Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.