Skip to content
Gosai Digital
  • Services
  • Use Cases
  • Case Studies
  • Process
  • Resources
  • About
Book a call
←Back to resources
Resource guideAdvancedArchitecture & DataStaffing & Recruiting
By Gosai Digital·March 2026·8 min read
Back to Resources
13 min read

The staffing Salesforce data model that doesn't fight you

A flat schema that treats every person as a Lead and every job as an Opportunity works when the team is small. It stops working when you have recruiters running parallel searches, clients with multiple divisions, candidates flowing through simultaneous submission pipelines, and a board that wants margin rolled up by brand or region.

The schema that serves a five-person desk is rarely the schema that serves a fifty-person firm. Early Salesforce implementations in staffing tend to flatten everything onto standard objects: candidates as Leads or Contacts, jobs as Opportunities, placements buried in Opportunity custom fields. This works until volume grows and the questions get specific—and then it stops working all at once.

The collapse usually shows up in three places: there is no dedicated record for a candidate submission to a specific job, so pipeline visibility disappears into task notes; there is no clean way to assign multiple recruiters to a search, so the owner field gets overloaded; and there is no consistent field spanning accounts, jobs, and placements to slice revenue by brand or region.

This article covers the six objects at the core of a unified staffing data model, the relationships between them, how to model recruiter assignments without breaking attribution, and the minimum approach to multi-brand reporting that does not require splitting the org.

Schema decisions compound over years

The right object model makes every downstream workflow cheaper to build—and easier to maintain as the business changes.

3

custom objects nearly every staffing org eventually needs: Job, Submission, Placement

4

stages in the candidate pipeline: sourced, submitted, placed, billed

1

Business Unit field applied consistently across Account, Job, and Placement unlocks multi-brand reporting

The six objects that carry a staffing org

Three standard, three custom. The question is not whether to create them—most firms do eventually—but whether each is used correctly, or repurposed to compensate for a missing one.

The Submission object: the missing piece in most early orgs

Without a Submission object, there is no way to track that one candidate was submitted to four different jobs, screened for two, and offered one. Teams work around this by logging submissions as tasks or notes on the Contact record, which means the pipeline is invisible to reports and dashboards. Managers lose the ability to measure submission-to-interview rate, interview-to-offer rate, or time-to-fill by job type.

A Submission is a many-to-many junction between Contact (candidate) and Job. Each Submission carries its own stage, its own activity timeline, and its own rejection reason if the candidate did not advance. When a submission is accepted and a start date is confirmed, a Placement record is created—the Submission does not become a Placement, it produces one. Both records persist in parallel: the Submission records the selection decision, the Placement records the assignment.

Submission stages and Placement stages track different things. Submission tracks screening and selection: Submitted, Phone Screen, Interview Scheduled, Offer Extended, Accepted, Declined, Rejected. Placement tracks the assignment lifecycle: Pending Start, Active, On Hold, Ended, Converted to Perm. Conflating both timelines into a single status field on one object is the most common source of pipeline confusion in staffing orgs.

How to model recruiter assignments without breaking attribution

Recruiters are Users in Salesforce. The question is not whether to link them to jobs—it is how many recruiters can own a job, how split credit is tracked, and who owns the candidate relationship separately from the job search.

Multi-brand and multi-region without splitting the org

Multi-brand and multi-region questions arrive when a staffing firm acquires a second brand or opens a regional office with its own P&L. The impulse is often to create a second Salesforce org for operational separation. That is almost always the wrong decision.

A Business_Unit__c or Division__c picklist field applied consistently to Account, Job, Placement, and Contact provides the segmentation needed for separate pipeline views, list views, and margin analysis. Recruiters can work candidates across brands; revenue rolls up to a single dashboard; and a client that works with two of your brands is one Account with two distinct sales pipelines, not two separate records that have no relationship to each other.

Record Types add the next layer of separation when brands or regions have genuinely different workflows: different required fields, different page layouts, different email templates. Use them when the processes differ, not just to create visual separation. A firm with two brands that follow the same placement process and use the same required fields does not need two record types—it needs a consistent Business Unit filter on its existing reports.

Four relationship decisions that compound into structural debt

These patterns are tempting early on because they reduce the object count. They create problems that grow with every new recruiter, every new client, and every board reporting cycle.

Need to redesign your Salesforce data model for staffing?

We audit existing org schemas, identify structural debt, and design object models that support recruiter workflows, multi-brand reporting, and growth without rebuilding from scratch.

Continue reading

Related resources

Keep moving through the same operating model with a few nearby articles from the same topic cluster.

Architecture & Data10 min read

Scaling Salesforce for High-Volume Staffing and MSP Operations

When staffing volume grows, Salesforce stalls in predictable ways: automation fires synchronously on bulk imports, recruiter pages wait for backend processing, and governor limits surface mid-transaction. Here is how to architect around it.

Advanced

March 1, 2026

Read article
Architecture & Data7 min read

The Hidden Cost of Bad Salesforce Architecture in Staffing Firms

Bad Salesforce architecture in staffing doesn't announce itself. It accumulates as reporting workarounds, duplicate operations, fragile automation, and change resistance that compounds until fixing it costs more than living with it.

Applied

March 1, 2026

Read article
Architecture & Data9 min read

Salesforce Reporting for Staffing Firms: Pipeline, Margin, and Recruiter Productivity

Salesforce reports in staffing firms are often wrong because the source objects, field conventions, and report types were built for a generic sales org. Here's how to fix the three layers that determine whether your numbers are trustworthy.

Applied

March 1, 2026

Read article

Resource updates

Get notified when new guides go live.

Practical notes on Salesforce, staffing workflows, and operational cleanup. No newsletter bloat.

Gosai Digital

Senior Salesforce architecture, admin, and development on a fractional retainer.

Services

  • Services
  • Use Cases
  • Case Studies
  • Process

Company

  • About
  • Contact
  • Resources

More

  • FAQ
  • Pricing

© 2026 Gosai Digital. All rights reserved.

PrivacyTerms
Share:
Salesforce Architecture
Data Model
Whiteboard showing a data architecture diagram with connected nodes representing objects in a staffing CRM

Account

Standard · Client organization

Represents the client: billing entity, divisions, site locations. Parent-child Account hierarchy handles multi-site clients. A Business Unit field here is the anchor for multi-brand reporting across the entire org.

Contact

Standard · Candidate or hiring manager

Contacts serve two distinct roles: candidate (no Account link, or linked to a candidate Account type) and client-side hiring manager (linked to an employer Account). A Contact Type field gates which workflows apply and prevents candidate records from bleeding into client relationship views.

Opportunity

Standard · Sales pipeline only

Represents the sales pursuit: a new client, a new division, a contract renewal. Linked to Account. Not a job order—keeping Opportunity for sales and Job for fulfillment is the single most important structural boundary in this schema.

Job

Custom · Open requisition

A specific open role at a client. Linked to Account and optionally to an Opportunity. Tracks headcount, pay rate, bill rate, status, and fill deadline. This is where recruiter assignments live—either via the Owner field or a dedicated junction for multi-recruiter searches.

Submission

Custom · Candidate-to-job pipeline record

The junction between a candidate (Contact) and a Job. One candidate submitted to four jobs generates four Submission records, each with its own stage, interview notes, and rejection reason. Without this object, the screening pipeline lives in tasks and is invisible to reporting.

Placement

Custom · Confirmed assignment

Created when a Submission converts to a hire. Stores start and end dates, bill rate, pay rate, and margin. A master-detail child of both Job and Contact. This is the source of truth for revenue reporting—not Opportunity, not Job.

Recruiter modeling

Single owner

Job.OwnerId points to the responsible recruiter's User record. The simplest model—clean for reporting, zero maintenance. It breaks when a search has a primary recruiter and a separate sourcer, or when credit must be split between two team members.

Use when: each job has one recruiter, compensation is not split

Multi-recruiter junction

A Job_Recruiter_Assignment__c junction object links Users to Jobs with a Role picklist (Primary, Secondary, Sourcing) and a Credit Split percentage. Required when comp plans involve split credit, or when a lead recruiter delegates sourcing to a different team member.

Use when: split credit matters, multi-recruiter teams, dedicated sourcers

Candidate relationship owner

Contact.OwnerId identifies who manages the ongoing candidate relationship—independent of who runs any specific search. This separation matters when a recruiter places a candidate and then another recruiter reactivates them six months later. Attribution on the Placement traces to both the job owner and the contact owner.

Use when: candidate reactivation is common, relationship ownership is tracked separately

Avoid

Create separate Salesforce orgs per brand or region to achieve operational separation

Preferred

Apply a Business Unit field consistently to Account, Job, Placement, and Contact; use Record Types only when workflows genuinely differ between brands

Avoid

Model multi-site clients as separate unrelated Account records with no parent relationship

Preferred

Use parent-child Account hierarchy: National HQ → Regional Division → Site; keep billing relationships on the correct account level

Avoid

Use Opportunity as a job order—you lose the sales pipeline once jobs and pursuits share the same object

Preferred

Create a Job custom object linked to Account; keep Opportunity for sales pipeline only

Avoid

Track candidate submissions in task records or notes on the Contact

Preferred

Create a Submission object as a junction between Contact and Job; each submission gets its own stage and interview history

Avoid

Track candidate and client contacts in the same record type with no persona differentiation

Preferred

Use a Contact Type field to gate workflows—one Contact object, two clearly separated personas with separate views

Avoid

Store placement financial data—bill rate, pay rate, margin—in Opportunity or Job fields

Preferred

Create a Placement object as a master-detail child of both Job and Contact; all financial fields live here

Book a call
Read: ATS integration for staffing