HRMS migration
Field-level mapping, validation, and rollback between ZenApply and Bullhorn ATS & CRM. We move data and schema; workflows are rebuilt natively in Bullhorn ATS & CRM.
ZenApply
Source
Bullhorn ATS & CRM
Destination
Compatibility
8 of 12
objects map 1:1 between ZenApply and Bullhorn ATS & CRM.
Complexity
BStandard
Timeline
2-4 weeks
Overview
Moving from ZenApply to Bullhorn is a structural migration for a staffing or recruiting firm that has outgrown a small-team ATS. ZenApply stores Jobs, Applications, and custom candidate profiles in a flat CSV export with no public REST API, which means we must enumerate every custom field manually during discovery before writing the migration mapping spec. Bullhorn's entity model splits what ZenApply calls an Applicant into a Candidate record and a JobSubmission record linked to a JobOrder, so we decompose the application relationship at migration time rather than post-load. Video resume URLs hosted by ZenApply become invalid once the source account is deactivated, so we re-upload video assets to Bullhorn's attached media store during the migration window. We do not migrate ZenApply Workflows or interview scheduling rules; we deliver a written inventory of these for the customer's Bullhorn admin to rebuild in Bullhorn Automation or through Bullhorn Launch configuration. Bullhorn pricing starts at $99 per user per month for the Starter tier, and Bullhorn does not publish pricing publicly, so we scope against the customer's target user count rather than the source record count.
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 ZenApply 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.
ZenApply
Job
Bullhorn ATS & CRM
JobOrder
1:1ZenApply Jobs (Positions) map to Bullhorn JobOrder records. We extract Job name, description, department, and status from the CSV export and load them into Bullhorn JobOrder via the REST API, setting the status field to reflect open/closed/paused. Bullhorn JobOrder includes additional fields (employment type, pay rate, overtime class, etc.) that ZenApply does not expose in its standard export; we create these as empty custom fields or flag them for the customer to populate post-migration. The CSV export does not include salary band data unless manually added during export preparation, so we flag salary range fields as requiring admin verification in Bullhorn.
ZenApply
Application
Bullhorn ATS & CRM
JobSubmission
1:1ZenApply Applications link a Candidate to a Job and carry submission date, application status, and source attribution. In Bullhorn the equivalent is a JobSubmission record tied to both a Candidate entity and a JobOrder entity. We decompose the application relationship at migration time: the Candidate record is created first, the JobOrder is confirmed to exist, and the JobSubmission is inserted last so that both foreign-key lookups are satisfied. Application status values from ZenApply vary by customer-configured pipeline; we normalise these to a standard set (Applied, Screening, Interview, Offer, Hired, Rejected) and map any non-standard status values to custom JobSubmission custom field values for audit.
ZenApply
Candidate (Applicant)
Bullhorn ATS & CRM
Candidate
1:1ZenApply Candidate records map directly to Bullhorn Candidate records. Standard fields (firstName, lastName, email, phone, address) migrate to Bullhorn Candidate fields by exact name match. The ZenApply custom profile fields (which vary per-customer and cannot be exported as a schema) are enumerated during the discovery phase and mapped to Bullhorn Candidate custom fields we pre-create in the destination schema. Any custom field that maps to a Bullhorn picklist or multi-select requires us to pre-create the picklist values during schema configuration. Candidate deduplication uses email as the primary key.
ZenApply
Video Profile URL
Bullhorn ATS & CRM
Candidate Attachment (Media)
1:1ZenApply video resume assets are hosted as URLs that may become invalid once the ZenApply account is deactivated. We download each video to temporary storage during the migration window, preserving original filename and MIME type, then re-upload to Bullhorn as a Candidate Attachment using Bullhorn's REST API file upload endpoint. The Bullhorn Candidate record's mediaURL or attached file is linked via the CandidateAttachments endpoint. This step extends the migration timeline by one to two days per 100 video assets. We validate that re-uploaded video URLs are accessible before declaring the media transfer phase complete.
ZenApply
Custom Profile Field
Bullhorn ATS & CRM
Candidate Custom Field
lossyZenApply allows custom profile fields at the position or global level with no admin-visible schema export. We enumerate every active custom field during discovery by walking through each Job's application form and the Candidate profile editor with the customer. Each discovered custom field is pre-created in Bullhorn as a Candidate custom field with the matching edit type (text, drop-down, multi-select, date, numeric) before the candidate import phase. Custom field values migrate as data during the Candidate import. Fields missed during discovery will not appear in Bullhorn; our structured discovery questionnaire is designed to capture every active custom field before the mapping spec is written.
ZenApply
Interview Scorecard
Bullhorn ATS & CRM
Note + Custom Scorecard Fields
1:1ZenApply Interview Scorecards are linked to Applications and Interviewers and contain template structures and individual ratings. We preserve the scorecard template structure as Bullhorn Note records (using the Note body for comments and reviewer feedback) and create Bullhorn Candidate custom fields to carry numeric ratings or rating categories. Reviewer names map to Bullhorn User records via email match. Any scorecard templates that exceed 55 custom fields per entity (Bullhorn's limit for a single Custom Object) require a split across multiple Custom Objects on the Candidate entity.
ZenApply
User (Hiring Team)
Bullhorn ATS & CRM
User
1:1ZenApply User records (Admin, Hiring Manager, Recruiter) map to Bullhorn User records. We match by email address during migration. Any ZenApply role type that does not map directly to a Bullhorn role (e.g., custom ZenApply roles) is flagged for the customer's Bullhorn admin to assign appropriate Bullhorn permissions post-migration. Unrecognised or inactive ZenApply users are held in a reconciliation queue.
ZenApply
Attachment (Document)
Bullhorn ATS & CRM
Candidate Attachment (Document)
1:1ZenApply stores resume files, cover letters, and portfolio attachments as hosted file URLs. We download each file to temporary storage during the migration window, preserving original filename and MIME type, then re-upload to Bullhorn as a Candidate Attachment via the Bullhorn REST API. The attachment's linkedCandidateId field points to the migrated Candidate record. Bullhorn applies its own virus scanning and file size limits during upload; files that exceed Bullhorn's limit are flagged for alternative storage (a customer-provided S3 bucket or Bullhorn's attached media store with manual relinking).
ZenApply
Candidate Source Attribution
Bullhorn ATS & CRM
Candidate Custom Field (source)
lossyZenApply application records include a source attribution field (e.g., job board, referral, career site). We map this to a Bullhorn Candidate custom field (candidateSource) that we pre-create as a picklist. If the source attribution was stored differently across different Jobs in ZenApply, we normalise during the transformation step and flag any source values that cannot be matched to the Bullhorn picklist for admin review.
ZenApply
Job Department
Bullhorn ATS & CRM
JobOrder Department or Custom Field
lossyZenApply Jobs carry a department field. We map this to Bullhorn JobOrder's built-in department field if the customer uses Bullhorn's standard department taxonomy. For customers with non-standard department naming that does not align with Bullhorn's defaults, we create a JobOrder custom field (department__c) with picklist values pre-loaded from the ZenApply CSV export.
ZenApply
Job Status
Bullhorn ATS & CRM
JobOrder Status
lossyZenApply Job status values (Open, Closed, Paused, Draft) map to Bullhorn JobOrder status values. We configure the Bullhorn JobOrder status field before migration to include any non-standard ZenApply status values as picklist entries, ensuring no status value is rejected during import.
ZenApply
Placement (if applicable)
Bullhorn ATS & CRM
Placement
1:1If ZenApply tracks placements as a record type within Applications or as a separate entity (depending on the customer's configuration), we map them to Bullhorn Placement records, which link a Candidate to a JobOrder and include start date, end date, pay rate, bill rate, and markup fields. Bullhorn Placement is a first-class entity with its own API endpoints, and placement data often requires Client/Company records to exist first, which affects the dependency ordering of the migration load sequence.
| ZenApply | Bullhorn ATS & CRM | Compatibility | |
|---|---|---|---|
| Job | JobOrder1:1 | Fully supported | |
| Application | JobSubmission1:1 | Fully supported | |
| Candidate (Applicant) | Candidate1:1 | Fully supported | |
| Video Profile URL | Candidate Attachment (Media)1:1 | Fully supported | |
| Custom Profile Field | Candidate Custom Fieldlossy | Fully supported | |
| Interview Scorecard | Note + Custom Scorecard Fields1:1 | Fully supported | |
| User (Hiring Team) | User1:1 | Fully supported | |
| Attachment (Document) | Candidate Attachment (Document)1:1 | Fully supported | |
| Candidate Source Attribution | Candidate Custom Field (source)lossy | Fully supported | |
| Job Department | JobOrder Department or Custom Fieldlossy | Fully supported | |
| Job Status | JobOrder Statuslossy | Fully supported | |
| Placement (if applicable) | Placement1:1 | 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.
ZenApply gotchas
No public API schema or documented export endpoints
Video media assets stored as URLs, not files
Custom profile fields are customer-specific and require manual discovery
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 CSV export audit
We conduct a structured discovery session with the ZenApply admin to enumerate every active Job, custom field on candidate profiles, video asset count, attachment type distribution, and any scorecard or user role data that exists. We then walk through the CSV export process in the ZenApply admin dashboard to confirm that every enumerated field is included in the export. If the export excludes fields visible in the UI, we identify and close that gap before proceeding. The discovery output is a written migration scope document that lists every object and custom field, its ZenApply location, and its target Bullhorn entity and field name.
Custom field enumeration and Bullhorn schema pre-configuration
We create the Bullhorn schema in a Sandbox environment before any production data moves. This includes pre-creating every ZenApply custom field as a Bullhorn Candidate or JobOrder custom field with the matching edit type (text, drop-down, multi-select, date, numeric). Bullhorn limits Custom Objects to 55 fields per entity and 10 searchable Custom Objects per entity for Front Office Growth/Enterprise; we design around these constraints if the customer's custom field inventory is large. Bullhorn field character limits are applied in the schema definition so that the Bullhorn validation rules fire correctly during data load.
Video and document asset download
We download all video resume URLs and file attachments from ZenApply to temporary encrypted storage during the migration window. We preserve original filenames, MIME types, and timestamps. This step runs in parallel with the Bullhorn schema configuration and before the source account is deactivated. We validate that each downloaded file is accessible and intact before adding it to the import queue. Video re-upload to Bullhorn's candidate attachment store runs as a separate phase after the candidate records are loaded in Bullhorn so that the attachment link (CandidateAttachments.candidateID) can be resolved correctly.
Owner and User reconciliation
We extract every distinct ZenApply User referenced on Jobs, Applications, and scorecards and match by email against the Bullhorn destination's User table. Any ZenApply user without a matching Bullhorn User is held in a reconciliation queue for the customer's Bullhorn admin to provision before record import resumes. Bullhorn requires an OwnerId on JobOrder and Candidate records; unresolved owners block the migration load. We also identify any custom ZenApply role types that do not map to a standard Bullhorn role and flag them for admin assignment.
Sandbox migration and reconciliation
We run a full migration into a Bullhorn Sandbox (Full Copy or Partial Copy) using production-like data volumes. The customer's Bullhorn admin reconciles record counts (JobOrders in, Candidates in, JobSubmissions in, Attachments in), spot-checks 25-50 random candidate profiles against the ZenApply source data, and validates that custom field values populated correctly. Bullhorn field-level security and validation rules can cause record rejection during data load; we coordinate with the admin to temporarily relax validation rules or grant the migration user the necessary permissions before the production migration phase. Any mapping corrections are made in the Sandbox and the migration script is updated before production cutover.
Production migration in dependency order
We run production migration in record-dependency order. JobOrders are loaded first so that they exist before JobSubmissions reference them. Candidate records are loaded second (with email-based deduplication) so that JobSubmissions can resolve the candidateId lookup. JobSubmissions link Candidates to JobOrders and carry application status and source attribution. User records are verified (or manually provisioned by the admin) before the load begins because Bullhorn requires OwnerId on standard entities. Video assets and document attachments are re-uploaded to Bullhorn's candidate attachment store after candidate records are confirmed in the system. Each phase emits a row-count reconciliation report before the next phase begins. We use Bullhorn's REST API with rate-limit handling and exponential backoff for standard-record loads, and Bulk API for high-volume candidate and activity imports if the customer's data volume warrants it.
Cutover, validation, and workflow rebuild handoff
We freeze ZenApply writes during the cutover window, run a final delta migration of any records created or modified during the migration window, then enable Bullhorn as the system of record. We deliver a written inventory of every ZenApply workflow, interview scheduling rule, and automation (if any exists) with a recommended Bullhorn Automation equivalent for the customer's Bullhorn admin to rebuild. We do not rebuild ZenApply automations as Bullhorn Automation inside the migration scope; that is a separate engagement or an internal admin task. We support a one-week hypercare window to resolve any record-level issues raised by the customer's team after go-live.
Platform deep dives
ZenApply
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 ZenApply 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
ZenApply: Not publicly documented.
Data volume sensitivity
ZenApply 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 ZenApply to Bullhorn ATS & CRM migration scoping. Not seeing yours? Book a call.
Walk through your ZenApply 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 ZenApply
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.