How to Build an Applicant Tracking System Like Greenhouse

Building an applicant tracking system like Greenhouse requires a configurable per-job pipeline, resume parsing, interview scheduling, structured scorecards, offer management, and HRIS integration. RaftLabs has built recruiting platforms and HR tech tools across multiple markets. A full ATS costs $140K-$200K and takes 14-18 weeks. Interview scheduling is the most time-consuming feature to get right.

Key Takeaways

  • Greenhouse costs $6,000-$30,000/year. Staffing agencies processing 500+ candidates per month pay that fee for every client they serve. Owning the platform changes the unit economics entirely.
  • Build a configurable pipeline per job requisition, not a global pipeline. An engineering role needs Technical Assessment and System Design stages. A sales role needs Presentation and Territory Review. One global pipeline forces every role into the same structure.
  • Interview scheduling is the most time-consuming feature to get right. Calendar API integration, availability polling, scheduling link generation, and automatic event creation for all participants each require careful implementation.
  • Structured scorecards separate good ATS tools from bad ones. Without a per-stage scorecard, interviewers give verbal impressions that don't aggregate. With scorecards, hiring managers see numeric scores across candidates and identify interviewer disagreement.
  • When a candidate accepts an offer, push their data to the HRIS automatically. Manual data entry from ATS to HR system is where most hiring teams lose days between offer acceptance and onboarding start.

A staffing agency processing 500 candidates per month across 20 active roles pays Greenhouse $6,000-$30,000 per year for a system they don't own. When a client wants white-label branding, Greenhouse says no. When the hiring workflow requires custom stages or approval chains, the agency works around the limitations in spreadsheets. When the agency grows to serving 50 clients with different workflows, one shared Greenhouse instance becomes a mess.

According to SHRM, the average cost-per-hire in the US is $4,700 and top performers take an average of 36 days to hire. Time lost to manual handoffs between ATS and HRIS is a measurable cost.

The economics of building your own ATS are clear once volume is high enough. The architecture is well-understood. The hardest part is not the data model. It is interview scheduling.

This guide covers what ATS software does, where the hard problems are, and what it costs to build.

TL;DR

An applicant tracking system models candidates through a configurable per-job pipeline, parses resumes into structured profiles, schedules interviews against real calendar availability, collects structured scorecard feedback, manages offers with e-signature, and pushes hired candidates to the HRIS for onboarding. A full build costs $140K-$200K and takes 14-18 weeks. Interview scheduling is the most time-consuming feature to get right.

"The biggest driver of poor candidate experience is process failure, not employer brand. Slow scheduling, missing calendar events, and inconsistent scorecard feedback account for 60% of candidate drop-off after the first interview." LinkedIn, Global Talent Trends Report

Who builds custom ATS software

Staffing agencies are the primary case. An agency processing 500 or more candidates per month across many active clients is running a recruiting business. Greenhouse or Lever is a tool built for in-house HR teams at single companies. The workflow is different. A staffing agency needs to manage candidates across multiple client companies, track placements, and in many cases white-label the system so their clients see the agency's brand, not a third-party tool.

Companies in markets where Greenhouse pricing exceeds budget build their own. A $6,000-$30,000 annual fee is reasonable for a Series B SaaS company hiring 50 engineers per year. It is harder to justify for a 200-person manufacturing firm hiring 30 roles annually.

HR tech startups build specialized ATS tools for niche hiring segments: technical hiring (with coding assessments embedded in the pipeline), executive search (with relationship tracking across years of candidate touchpoints), or creative hiring (with portfolio review as a stage). Greenhouse is built for standard commercial roles. Niche hiring has enough workflow variation that a specialized tool commands a price premium.

Enterprise companies with complex multi-country hiring workflows find that generic ATS tools impose a single hiring model. A company hiring in 15 countries needs different approval chains, different offer letter templates, different background check integrations, and different compliance requirements per jurisdiction. Building custom gives full control over the data model and the workflow.

The recruiting pipeline

Every ATS is built around a pipeline: the sequence of stages a candidate moves through from application to hired or rejected.

The mistake is building one global pipeline for all roles. An engineering role needs stages like Technical Assessment, System Design Interview, and Bar Raiser. A sales role needs Presentation and Territory Review. An executive role needs Board Meeting and Reference Check. Forcing every role into the same stage sequence produces a pipeline that fits no role well.

Build the pipeline as a per-job configuration. When a recruiter opens a new job requisition, they choose a pipeline template (Engineering, Sales, Operations) or build a custom sequence from a stage library. The stage library contains all possible stages with default names and interview kit templates. Each job's pipeline is independent of every other job's pipeline.

A candidate's position in the pipeline is a state. State transitions are logged with a timestamp, the user who moved the candidate, and the reason if the transition is a rejection. This audit trail answers the question every recruiter eventually asks: "When did this person interview and who moved them forward?"

Job requisition and posting

Before a recruiter can source candidates, the role needs approval. Build a requisition workflow: the hiring manager submits a job requisition with job title, department, location, salary band, and headcount. The requisition routes to HR for review and to finance if the role is above a salary threshold. Approvals are logged with timestamps.

Once approved, the job needs a description. Build a description editor with a template library. Most roles in a company share a structure: responsibilities, requirements, nice-to-haves, benefits. Templates let recruiters start from an approved baseline rather than blank. Save the company's approved language for legal disclaimers and EEO statements as a locked template section.

Post the approved job to external channels: the company's careers page (embeddable JavaScript widget or a hosted page), Indeed via the Indeed Publisher API, LinkedIn via the LinkedIn Job Postings API, and Glassdoor. Each platform has its own posting API and its own data format. Budget two to three weeks for multi-channel posting integration.

Track source attribution on every application. When a candidate applies, record which channel brought them: direct careers page, LinkedIn, Indeed, referral, recruiter outreach. This data feeds the source attribution report that tells hiring teams which channels produce hires versus which channels produce volume without conversion.

Candidate profile and resume parsing

When a candidate applies, the system receives a form submission and usually a resume file. The goal is to create a structured candidate profile from an unstructured document with minimal manual data entry.

Integrate a resume parser. Sovren and Affinda are the two proven options. Both accept a PDF or Word file and return structured JSON: name, email, phone number, current title, employer, years of experience, education, and a skills list. That data populates the candidate profile. The recruiter reviews and corrects, but they are not keying in data from scratch.

Deduplication matters more than most teams expect. A candidate who applies to the same role twice, or applies to two different roles, should not create two unconnected profiles. Match on email address first, then on name plus phone if the email differs. Present the match to the recruiter and let them confirm whether it is the same person. Linked profiles give recruiters a full history of a candidate's interactions with the company across roles and time.

Store resumes in S3 with version control. When a candidate uploads an updated resume, keep the previous version with a timestamp. Interviewers sometimes reference the resume version that was current at the time of an interview, not the current version.

Interview scheduling

This is where most ATS builds underestimate scope. Interview scheduling sounds straightforward. It is not.

Connect to Google Calendar via the Google Calendar API and to Outlook and Microsoft Teams via Microsoft Graph API. Both require OAuth authentication from each interviewer who grants access. Collect availability from their calendars: free/busy data for the next two weeks during working hours, filtered by calendar events marked as busy.

When a recruiter needs to schedule an interview, they select the interviewers, select a duration, and the system shows available slots where all required interviewers are free. The recruiter picks a slot or generates a scheduling link the candidate self-selects from, similar to Calendly but connected to the ATS pipeline.

When the slot is confirmed, the system creates calendar events for all participants: the candidate, each interviewer, the recruiter. The event includes an interview kit (a link to the scorecard the interviewer needs to complete, the candidate's resume, and any relevant notes from previous stages). Send confirmation emails to all participants.

Send reminders 24 hours before the interview. Interviewers who miss their reminders cost the company candidates who took time off work for an interview.

When an interview is rescheduled, update all calendar events, send notifications to all participants, and update the pipeline stage timestamp. That state management is where most teams find bugs in production.

Structured scorecards

Google's Project Oxygen research found that structured interviews with consistent scoring rubrics predict job performance 2x better than unstructured conversations. Scorecards are what separate rigorous hiring from gut-feel hiring. Without a scorecard, interviewers give verbal summaries. With a scorecard, every interviewer answers the same questions on the same 1-4 scale: 1 (No Hire), 2 (Lean No), 3 (Lean Yes), 4 (Strong Yes).

Build scorecards per pipeline stage. A phone screen scorecard has four to six questions: communication clarity, role interest alignment, compensation expectations, availability timeline, and an overall hire/no-hire recommendation. A technical assessment scorecard has ten to fifteen questions covering specific competencies.

Assign scorecards to interviewers when the interview is scheduled, not after. The system sends the scorecard link with the calendar invite. The interviewer completes it within a few hours of the interview. After all interviewers for a stage have submitted, the hiring manager sees an aggregated view: individual scores, written comments, and an overall recommendation.

When interviewers disagree significantly (one gives a 4, another gives a 1), flag the disagreement for the hiring manager's attention. Disagreement at the extremes is signal. It either means the evaluation criteria are unclear or the candidate is genuinely polarizing. Either way, it warrants a conversation before a decision.

Lock scorecards after submission. Interviewers should not be able to edit their scores after seeing another interviewer's feedback. Score anchoring (changing your assessment to match the consensus) defeats the purpose of structured evaluation.

Offer management

When a hiring manager moves a candidate to offer stage, the system needs to generate an offer letter, route it for internal approval, and send it to the candidate for signature.

Build offer letter templates by role category. Fill variable fields (name, title, start date, salary, equity grant, sign-on bonus) from form inputs. Generate the populated letter as a PDF using a document generation library. Store the template version used so you can show the candidate and hiring manager the exact document in effect at the time of the offer.

Route the offer through internal approvals before sending to the candidate. The typical chain: hiring manager confirms the numbers, HR reviews the offer for consistency with compensation bands, and finance approves if base salary exceeds a threshold. Log each approval with the approver's name and timestamp.

When approvals are complete, send the offer to the candidate via DocuSign or HelloSign. Both provide APIs for document sending, status tracking, and signature collection. Do not build native e-signature. The legal requirements for a valid electronic signature (audit trail, intent capture, email verification, IP logging) take three to six months to get right, and candidates and their lawyers trust DocuSign more than a custom implementation.

Track acceptance and decline. When a candidate accepts, record the timestamp and trigger the HRIS push. When a candidate declines, record the reason if provided and flag the role as needing another offer.

HRIS integration

When a candidate accepts an offer, their data needs to go to the HRIS for onboarding. Without an integration, an HR coordinator manually keys the new hire's information into BambooHR, Workday, or ADP: name, title, department, manager, start date, salary, location. This takes 20-30 minutes per hire and introduces transcription errors.

The integration pushes structured data from the ATS to the HRIS when the offer status changes to accepted. Map ATS fields to HRIS fields for each supported system. BambooHR and ADP each have REST APIs for creating employee records. Workday's API is more complex and requires a dedicated integration module.

Use Merge.dev for HRIS integrations if you need to support more than two or three HR systems. Merge provides a normalized API across BambooHR, Workday, ADP, Rippling, and similar platforms. One integration to Merge's API covers all of them.

Also see our guide on how to build an app like Workday for more on HRIS data models and integration patterns.

Reporting

Five reports cover 80% of what hiring teams need.

Time-to-hire is the number of days from application received to offer accepted, broken down by department, role level, and location. It answers whether the hiring process is getting faster or slower.

Pipeline conversion rates show what percentage of candidates advance from each stage to the next. A 60% conversion from phone screen to technical assessment is healthy. A 20% conversion means the phone screen criteria are unclear or the job description is attracting the wrong candidates.

Source attribution shows which channels produce hires versus which produce volume without conversion. LinkedIn may send 40% of applications but only 20% of hires. Indeed may send 20% of applications but 40% of hires. That data drives recruiting spend decisions.

Interviewer load shows how many interviews each person conducts per week. Uneven interviewer load is one of the fastest ways to burn out senior engineers who end up in every technical interview. The report surfaces the problem before it becomes a retention issue.

Offer acceptance rate is accepted offers divided by total offers extended. A rate below 80% signals a problem: compensation is below market, competitors are winning candidates late in the process, or the candidate experience during the process is leaving a bad impression.

Build these as saved reports with date range filters. A general report builder is tempting but adds six to eight weeks and hiring teams use the same five reports repeatedly.

Tech stack

React for the dashboard. Node.js for the API. PostgreSQL for candidates, jobs, applications, pipeline states, scorecards, and offers. Elasticsearch for candidate search (searching across 50,000 candidate profiles by name, skill, or previous employer requires full-text search, not SQL LIKE queries). AWS S3 for resume and offer letter storage.

Google Calendar API and Microsoft Graph API for interview scheduling. DocuSign or HelloSign API for offer e-signature. SendGrid for transactional emails (application confirmations, interview reminders, offer notifications). Sovren or Affinda for resume parsing.

The stack is standard. The complexity is in the calendar integration state management, the pipeline state machine, and the multi-provider resume parsing normalization.

Cost and timeline

A full ATS with configurable pipeline, resume parsing, interview scheduling (Google Calendar plus Outlook), structured scorecards, offer management with e-signature, HRIS integration, and the five core reports costs $140,000-$200,000 and takes 14-18 weeks.

Interview scheduling accounts for $25,000-$40,000 of that range and four to six weeks. It is the feature with the most edge cases and the highest cost of getting it wrong in production.

A focused build covering pipeline management and candidate profiles only (no interview scheduling automation, no offer management) costs $50,000-$75,000 in 8-10 weeks. This works for teams that want to digitize their tracking without replacing their current scheduling workflow.

Adding AI features (AI resume scoring, automated candidate ranking by job requirements, or a conversational sourcing assistant) adds $30,000-$60,000 depending on scope.

Build vs. buy

Greenhouse costs $6,000-$30,000 per year. Lever costs $8,000-$25,000. Workable costs $3,000-$6,000. For a single company hiring 20-50 roles per year, buy. The commercial tools are well-built and the per-seat cost is manageable.

Build custom when you are a staffing agency processing 500 or more candidates per month. The commercial tool fee compounds with every client you add. Owning the platform means the marginal cost of adding a new client is near zero.

Build custom when you need white-label for your clients. Greenhouse does not offer white-label. If your clients expect to see your brand on the recruiting platform, you need a custom build or a platform that explicitly supports multi-tenancy with custom branding.

Build custom when your hiring workflow is the product. If you are building an ATS for technical hiring with embedded coding assessments, or an executive search platform with decades of relationship data, the workflow is what differentiates you. That workflow requires ownership.

Build custom when off-the-shelf ATS tools can't model your hiring process. Multi-country approval chains, non-standard assessment stages, complex compensation structures with equity modeling, or integration requirements that commercial tools don't support: these are signals to build.

For companies pursuing SaaS application development where the ATS is the core product, the architecture decisions above apply directly. For companies that need to ship a recruiting platform quickly to validate a market, MVP development with a focused feature set (pipeline plus candidate profiles plus basic scheduling) gets you to market in 8-10 weeks at roughly half the cost of the full build.

Frequently asked questions

A full ATS with configurable pipeline, resume parsing, interview scheduling (Google Calendar + Outlook), structured scorecards, offer management with e-signature, HRIS integration, and reporting costs $140K-$200K and takes 14-18 weeks. A focused build covering just pipeline management and candidate profiles (no interview scheduling, no offer management) costs $50K-$75K in 8-10 weeks. Interview scheduling and calendar API integration add $25K-$40K and 4-6 weeks.
Staffing agencies processing 500+ candidates per month are the primary use case. At Greenhouse's pricing, a staffing agency serving multiple clients pays the fee without owning the platform. Companies in markets where Greenhouse pricing exceeds budget, HR tech startups building specialized tools for technical hiring or executive search, and companies with multi-country hiring workflows that generic ATS tools can't model all build custom. The common thread: the workflow is the product, and the workflow requires ownership.
Interview scheduling. Connecting to Google Calendar API and Microsoft Graph API, handling timezone differences, polling interviewer availability across calendar systems, generating scheduling links candidates can self-serve, and automatically creating calendar events for all participants with interview kits attached: each step has edge cases. When the meeting is rescheduled, the system needs to update all calendar events, notify all participants, and update the pipeline stage timestamp. That state management is where most teams underestimate scope.
When a candidate applies, the system receives a PDF or Word file. A resume parser (Sovren, Affinda, or an NLP-based service) extracts structured data: name, email, phone, current title, years of experience, education, and skills. That data populates the candidate profile automatically. Without parsing, every application requires a recruiter to manually key in candidate data. Deduplication logic checks whether the same candidate has applied to another role using name plus email matching. Candidates who appear multiple times are linked to a single profile.
When a hiring manager moves a candidate to offer stage, they fill in offer parameters: job title, department, location, start date, base salary, equity, sign-on bonus. The system generates an offer letter from a template using those values. The letter routes through an internal approval chain: hiring manager confirms, HR reviews, finance approves if salary is above a threshold. Once approved internally, the system sends the offer to the candidate via DocuSign or HelloSign for electronic signature. The ATS records acceptance or decline and timestamps both actions. Accepted offers trigger HRIS onboarding data push.

Ask an AI

Get an instant summary of this post from your preferred AI assistant.