DEV Community

Cover image for I built a hiring platform where candidates never apply - here's how the matching works
Akshay Sharma
Akshay Sharma

Posted on AI-assisted

I built a hiring platform where candidates never apply - here's how the matching works

The problem I was trying to solve

Candidates send hundreds of applications.
Companies receive thousands of resumes.
Most candidates never hear back.

Both sides exhausted. Most of the effort wasted.

The insight that changed my thinking: senior engineers don't apply to jobs. They get headhunted. A recruiter finds them, reaches out, and they evaluate the opportunity on their terms.

Why is that only available to senior people?

It shouldn't be.

What I built

Wrkmark Jobs — a hiring platform where candidates never apply.

Here's how it works:

  1. Candidates create one profile
  2. Algorithm scores them against active roles
  3. Companies see their top 15 ranked matches
  4. Companies reach out. Candidates choose to respond.

No applications. No cover letters. No ghosting.

How the matching algorithm works

This is the part I want to talk about technically.

The algorithm scores each candidate against each job across four dimensions:

Skills — 40% of score

Simple exact match (case-insensitive) with a synonym map for common variations:

const SKILL_SYNONYMS: Record<string, string[]> = {
  'ruby on rails': ['rails', 'ror', 'ruby-on-rails'],
  'kubernetes': ['k8s', 'kube'],
  'postgresql': ['postgres', 'pg', 'psql'],
  'javascript': ['js', 'es6', 'ecmascript'],
  // 60+ mappings
}
Enter fullscreen mode Exit fullscreen mode

A candidate with "RoR" on their profile matches a job requiring "Ruby on Rails". Simple but surprisingly effective at this scale.

Salary — 25% of score

All salaries converted to USD for comparison using live exchange rates (Frankfurter API).

The logic:
job_max_usd >= candidate_min_usd → score 100
job_max_usd < candidate_min_usd → score 0

If a company offers $80-120K and a candidate expects $30-50K — that's a great match. The company can easily meet the candidate's
expectation. Score: 100.

The common mistake is calculating range overlap. Overlap fails in the overqualified-offer case.

Experience — 20% of score

Years of experience vs role requirement.
Meeting or exceeding → full score.
Under by 50% → partial score.

Timezone — 15% of score

This one I'm most proud of. Most platforms do binary bucket matching:

  • "US East" or not

We calculate actual UTC hour overlap:

const UTC_WINDOWS = {
  us_east: [14, 22],   // 9am-5pm EST
  europe: [8, 16],     // 9am-5pm CET
  apac: [1, 9],        // 9am-5pm IST/SGT
}

function getOverlapHours(window1, window2) {
  const start = Math.max(window1[0], window2[0])
  const end = Math.min(window1[1], window2[1])
  return Math.max(0, end - start)
}
Enter fullscreen mode Exit fullscreen mode

6+ hours overlap → 100 score
4-5 hours → 80
2-3 hours → 50
1 hour → 25
0 → fail

A US East job and a European candidate have 2 hours overlap (14:00-16:00 UTC). That scores 50 — workable with async communication. Better than the binary "not US East = zero" approach.

Hard filters (before scoring)

Before scoring, candidates must pass:

  • Employment type match
  • Work arrangement match (remote/hybrid/onsite)
  • Visa/sponsorship check (checks work_authorized_countries)

The visa check was interesting. An Indian citizen applying to an Indian company doesn't need sponsorship even if they've marked "needs_sponsorship: yes" globally.
We check work_authorized_countries first.

Why not ML?

At current scale — a few thousand candidates and hundreds of jobs — pure algorithmic matching is more accurate than ML.

ML needs large datasets to find patterns.
With small data, it overfits.

The algorithmic approach is also:

  • Explainable (candidates see exactly why they matched)
  • Debuggable (I can trace every score)
  • Fast (no model inference, just math)

I'll add ML when I have 100K+ matches worth of outcome data.

The paid candidate model

Candidates pay $9/year globally (₹99 in India).

Controversial? Yes. But here's the logic:

Free platforms have millions of profiles.
Most are fake, inactive, or outdated.
Companies stop responding because signal is lost.
Candidates get ghosted.

$9/year is a filter. Every profile on Wrkmark
is someone who meant it enough to pay.
Companies know this. They actually respond.

On free platforms, candidates are the product.
On Wrkmark, they're the client.

Tech stack

  • Frontend/Backend: Next.js 14 App Router
  • Database: Supabase (PostgreSQL + Auth + Storage)
  • Hosting: Vercel
  • Payments: Dodo Payments (MoR — handles global tax compliance without company registration)
  • Email: Resend
  • Resume parsing: Gemini 3.6 Flash (native PDF, no pdf-parse library)
  • Analytics: Umami (privacy-first)

What's live

Wrkmark Jobs — open beta.

Looking for candidates: engineering, product, data, design, DevOps. India, US, UK, EU, Southeast Asia. Remote-first.

Candidate membership: ₹99/year India, $9/year global.
Company job post: ₹5,000 India, $149 global.

Happy to answer questions about the algorithm, the stack, or the two-sided marketplace problem.

Top comments (0)