Migration
In buildMove off Bullhorn without losing the history that makes the database worth moving
The accounts worth migrating are the ones with ten years of notes, custom fields and placement history, and those are exactly the accounts a generic importer breaks.
Surhires does not sell a one-click Bullhorn importer. The first migrations are run as scoped, paid, founder-led projects: a statement of work naming which objects are in scope, a test migration into a sandbox tenant, a reconciliation report, a rollback position and your sign-off before cutover.
By Surhires Editorial · Published · Reviewed
In the product: the first migrations are run as paid, founder-led concierge projects using internal tooling; only the repeated steps are productised
Why there is no one-click importer on this page
Every recruitment software vendor is tempted to put a migration button on the pricing page, because migration is the single biggest reason an agency stays where it is. The button is usually a CSV mapper that moves candidates and contacts and quietly loses everything else, and the customer discovers what was lost six weeks later when a recruiter goes looking for the note that explains why a client stopped using them.
We are not going to sell that. The first migrations are run as paid, founder-led concierge projects using internal tooling, and only the steps that repeat identically across engagements get productised. That is slower, it does not scale in the first year, and it is the honest description of what moving a decade-old database actually takes.
The consequence for you is that a migration is scoped and quoted rather than promised as included. You will know before you commit which objects are moving, which are not, what the reconciliation will show, and what happens if the numbers do not match.
What is actually inside an established Bullhorn tenant
The candidate and contact tables are the easy part, and they are perhaps a fifth of the value. Underneath them sit custom fields that were added over years by people who have left, notes running to hundreds of thousands of rows with authorship and timestamps that matter, and attachments in several formats where the original resume, a formatted version and a right-to-work document all hang off the same record.
Then there is the relational history: candidate ownership and the split arrangements behind it, activity streams, job orders with their own custom fields, submittals tied to specific contacts on specific dates, placements with rates, fees, guarantee windows and extension records, and the email associations that connect a thread to a candidate, a contact and a job order at the same time.
And there is the mess. Duplicate candidates created by four recruiters over six years, records with conflicting ownership, notes attached to the wrong object, custom fields holding three different meanings depending on which year they were populated. A migration plan that does not have a position on the mess is not a plan.
- Custom fields on candidates, contacts, companies, job orders and placements
- Notes and activity with original authors and timestamps preserved
- Attachments including originals, formatted versions and compliance documents
- Candidate and client ownership, including split and shared arrangements
- Submittals, placements, rates, fees, guarantee windows and extensions
- Consent and communication history, and email-to-record associations
Where a shallow importer fails, and on which accounts
A generic importer works fine on a two-year-old database with four thousand candidates and no customisation. It fails on the ten-year-old agency with two hundred thousand records, sixty custom fields and a placement book, which is exactly the account worth migrating and exactly the account that cannot afford to lose anything.
The failures are predictable. Notes arrive without authors, so every entry looks like it was written by the migration account and the audit trail is gone. Attachments arrive detached from the right record, or the second and third documents on a candidate are dropped because the importer assumed one file. Ownership collapses to whoever ran the import, and every commission calculation downstream is wrong.
Duplicates are the quiet one. An importer that does not merge on the way in creates a database that is worse than the one you left, because now every duplicate exists twice with half the history on each copy. Merging afterwards is significantly harder than merging during the load, and by then people are already working in the system.
The concierge engagement, step by step
It starts with a discovery pass over your tenant: object counts, custom field inventory, attachment volume and formats, note volume, user list and ownership map, and a sample of records from each era of the database. That produces a scope document rather than an estimate, and the scope document is where the argument happens, which is the right place for it.
The statement of work then names, explicitly, which objects are in scope and which are out. Out of scope is written down as clearly as in scope, because the failures in this kind of project are almost never about what was promised and almost always about what nobody said would not be there. Field-level mapping is agreed the same way, including what happens to a legacy field that no longer has a meaning anybody can reconstruct.
Only then does anything move. The load runs into a sandbox tenant that mirrors your production configuration, your people work in it against real records, and the issues that surface there are the ones you would otherwise have found on the Monday after cutover.
- Discovery pass producing object counts, field inventory and an ownership map
- A statement of work naming both in-scope and out-of-scope objects
- Field-level mapping agreed before anything is loaded
- A duplicate strategy decided during scoping, not after the load
- A test migration into a sandbox tenant your team works in
- A reconciliation report, a rollback position and sign-off before cutover
The reconciliation report is the deliverable that matters
After the test load, you get a reconciliation report rather than a confirmation email. It compares counts on both sides object by object, lists every record that did not transfer with the reason, shows how duplicates were resolved and how many merges occurred, reports attachment counts and total bytes moved against the source, and names every field that was dropped, defaulted or transformed.
Discrepancies are expected and they are the point. A source system with two hundred thousand candidates will have records that cannot be moved cleanly, and a report that shows a perfect match is usually a report that was not looking hard enough. What you should judge is whether every gap has an explanation you accept.
Sign-off is yours and it is explicit. Cutover does not happen because a migration window was booked; it happens because you have read the reconciliation report, worked in the sandbox and said yes in writing.
The rollback position, and what it honestly covers
Until cutover, your Bullhorn tenant is untouched and remains your system of record. Nothing in this process writes to it. If the sandbox work says the migration is not ready, the answer is to fix the mapping and run it again, and the cost of that decision is time rather than data.
At cutover we keep the sandbox state, a full export of what was loaded and the complete migration log, so a problem discovered in the first weeks can be traced to the record, the field and the transform that caused it. Recovery is a corrective run against a known state rather than a reconstruction from memory.
The limit is worth naming. Once your team has been working in the new tenant for a fortnight, going back means losing that fortnight of work, because the two systems have diverged. The rollback position protects the migration, not an indefinite right to change your mind, and any vendor who tells you otherwise is describing something that does not exist.
What it costs in effort, and what we will not quote
The cost driver is not record count, which is the thing everybody asks about first. It is the number of custom fields whose meaning has to be reconstructed, the number of legacy conventions in the data, the attachment volume, and how much of the history you insist on preserving exactly. A clean two-hundred-thousand-record database can be simpler than a messy twenty-thousand-record one.
In effort terms, discovery runs days rather than weeks, mapping is the part that consumes the most calendar time because it needs decisions from people on your side who know why a field exists, the test load and reconciliation take a further pass, and there is usually a second test load after the first report changes somebody's mind. Cutover itself is short. The elapsed time is dominated by your review cycles, not by our processing.
We are not going to publish a price on this page. A migration quote that is real depends on the discovery pass, and a number printed before anybody has looked at your tenant is either a guess that will move or a floor priced for the simplest possible case. Ask for the scoping conversation and we will quote against what is actually there.
What you get
Discovery pass
Object counts, custom field inventory, attachment volume, note volume and an ownership map.
Written scope
A statement of work naming in-scope objects and, just as explicitly, out-of-scope ones.
Field-level mapping
Agreed before the load, including what happens to legacy fields nobody can explain.
Note authorship preserved
Original authors and timestamps carried across rather than stamped as an import account.
Attachment fidelity
Originals, formatted versions and compliance documents kept against the right record.
Ownership mapping
Candidate and client ownership, including splits, mapped to your new user list.
Duplicate strategy
Merge rules decided during scoping and applied during the load, not afterwards.
Placement history
Rates, fees, guarantee windows, extensions and linked submittals moved as records.
Consent history
Basis, source and timestamps carried over so retention clocks do not restart at import.
Sandbox test migration
A full load into a tenant mirroring your configuration, for your team to work in.
Reconciliation report
Counts by object, failures with reasons, merges, bytes moved and every dropped field.
Explicit sign-off
Cutover happens when you approve the reconciliation in writing, not when a window opens.
Rollback position
Source untouched until cutover, with the load export and full migration log retained.
Productised repeats
Only the steps that repeat identically across engagements become tooling you self-serve.
Questions recruiters ask
Is there a one-click Bullhorn importer?
No, and we are not planning to describe one before it exists. The first migrations are run as paid, founder-led concierge projects using internal tooling, and only the steps that repeat identically across engagements are being productised. A button that claims to move a decade of custom fields, notes and placements unattended is the thing that goes wrong.
What does the migration actually move?
That is decided in the statement of work rather than assumed. Typically candidates, contacts, companies, job orders, submittals, placements, notes with their authors, attachments, ownership and consent history. What is out of scope is written down with the same clarity as what is in, because unstated omissions cause more damage than known ones.
How long does it take?
Discovery runs in days. Mapping consumes the most calendar time, because it needs decisions from people on your side who know why a field exists. The test load and reconciliation take another pass, and a second test load after the first report is common. Cutover is short. Elapsed time is driven by your review cycles rather than by processing.
What does it cost?
We will not print a number before looking at your tenant. The cost driver is custom field complexity, legacy conventions in the data, attachment volume and how exactly you need history preserved, not raw record count. A quote comes out of the discovery pass, and a price published before that is either a guess or a floor for the simplest case.
Can we roll back if it goes wrong?
Until cutover, yes, completely. Your Bullhorn tenant is untouched and stays the system of record, and a failed test load costs time rather than data. After cutover we keep the load export and the full migration log so faults can be traced and corrected. What nobody can offer is a rollback after a fortnight of work, because the systems have diverged.
What happens to duplicates?
The merge strategy is agreed during scoping and applied while loading, not afterwards. Importing duplicates and cleaning up later leaves every record split across two copies with half the history on each, and by then people are already working in the system. The reconciliation report shows how many merges ran and on which rules.
Do consent and retention records survive the move?
That is explicitly in scope where the source holds them. Lawful basis, consent source and timestamps are mapped across so retention clocks continue from real history rather than restarting at the import date. A migration that resets every clock quietly manufactures a data-protection problem on day one, and it is easily missed.
Keep reading
- Working out whether to leave Bullhorn, and what the alternatives really cost you
- Recruitment software that is not gated behind the top tier
- Getting your data out of Bullhorn intact
- Bring your database across, properly
- Stop paying twice for the same candidate
- Know why you hold every candidate record, and for how long
- How to reach a person about Surhires
See it against your own reqs
Bring one live role and three resumes. In twenty minutes you will see the match scores, the shortlist and the placement invoice that comes out the other end.