AI-powered job matching, call-likelihood scoring, and resume tailoring for mobile
Job seekers apply broadly and hear back rarely. The core failure isn't effort, it's information: a candidate can't easily tell, before applying, which of the 40 open roles in their search actually fit their background well enough to get a callback - and if a role is close-but-not-quite, they don't know what specifically to change on their resume to close the gap.
Today this requires manually reading each job description, mentally comparing it to a resume, and guessing. It doesn't scale past a handful of roles, and it gets worse the more senior or niche the search is.
Signal's job: for any given resume, continuously surface open roles ranked by realistic call-likelihood, explain the gap for each one, propose the specific resume edit that closes it, and surface a human to reach out to - all from a phone, in the small pockets of time job searching actually happens in (a commute, a lunch break, right before bed).
Three tabs, one detail view:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Resume │ │ Matches │ │ Contacts │
│ (input) │──▶│ (ranked) │──▶│ (aggregated)│
└─────────────┘ └──────┬──────┘ └─────────────┘
▼
┌──────────────┐
│ Job detail │
│ - score │
│ - gap │
│ - edits │
│ - contact │
└──────────────┘
This is the product's central promise, so it has to be legible, not a black box.
What feeds it: - Skill/keyword overlap between resume and job description (explicit, shown as matched vs. missing chips) - Seniority alignment (years of experience implied vs. required) - Posting freshness (a 3-hour-old posting behaves differently than a 3-week-old one - older postings may already have a shortlist) - Historical response-rate patterns for similar profiles/roles, where available (a real system would train this from outcome data over time, with the person's consent to share application outcomes)
Design decision: show the reasoning, not just the number. Every score is paired with 2–4 sentence justification and an explicit matched/missing skill breakdown. A percentage without a "why" trains distrust; this system is only useful if people believe it enough to act on it.
Design decision: separate the cheap, instant score (client-side/heuristic, computed the moment a resume is pasted, used to rank the list) from the deep AI analysis (a real model call, run on demand per role, that reads the full job description and resume and produces a written gap analysis + rewrite suggestions). This keeps the list fast and free to browse, and reserves the expensive, high-quality reasoning for the roles a person actually cares about - which also keeps inference cost proportional to engagement.
For each role, Signal proposes edits at two levels:
Guardrail: the person always sees a before/after diff and approves changes explicitly - nothing is auto-submitted anywhere. Signal tailors, the person decides.
This is the most legally and ethically sensitive part of the product, and it's worth being explicit about the constraint: Signal does not scrape LinkedIn. Scraping LinkedIn profile data violates LinkedIn's Terms of Service and, depending on jurisdiction, relevant data-protection law, regardless of the end use.
Production approach instead: - LinkedIn's official Talent Solutions / Recruiter System Connect API, where the employer or a licensed partner has opted in - Licensed B2B contact-data providers (e.g. providers that maintain consented, opted-in professional contact graphs) rather than direct scraping - Publicly published company contacts (e.g. a recruiter's email listed directly on the job posting itself, or a company's own careers page) - Where no compliant source exists for a given company, Signal shows the job with no contact card rather than fabricating or scraping one
This is a hard constraint on the product, not a nice-to-have: any contact surfaced in the app should be traceable to a source that had a right to share it.
Every job card and detail view names the source portal the listing came from (e.g. "via LinkedIn", "via Indeed", "via Company Careers Site"). This matters for two reasons: it sets expectations about the application process itself (a company-site posting behaves differently than a LinkedIn Easy Apply), and it's a prerequisite for the next feature - attributing where any comparison or contact data came from, rather than presenting it as if Signal generated it independently.
The job detail view also shows "how you compare": an estimated percentile against other applicants for that specific posting, plus applicant count and average experience. This deliberately mirrors a feature job seekers already trust in the wild - LinkedIn's own "how you compare to other applicants" panel - rather than inventing a new mental model. In production this data would come directly from the portal's own applicant-analytics API where the employer has made it available (LinkedIn and several ATS platforms already expose aggregate, anonymized applicant stats for this purpose); where a portal doesn't expose it, the section should say so rather than estimate silently.
Every job's detail view also links out to the original posting and the company's own site, both opening in a new tab. Signal is a triage and prep layer, not a replacement for the actual application flow - a person should always apply on the portal or company site itself, where the data and process are authoritative.
Similarly, board-by-board scraping is fragile and frequently against individual sites' terms. Production sourcing should prioritize: - Official job-board APIs where available (Indeed Publisher API, Google for Jobs structured data, etc.) - Direct ATS integrations (Greenhouse, Lever, Ashby all expose public job feeds by design) - Employer-direct feeds for companies the person has opted to track
Freshness (shown on every card) is a first-class signal, not decoration - a 2-day-old post at a fast-moving startup and a 2-day-old post at a slow enterprise employer carry different implications, and the design should eventually let the freshness read adapt per company hiring cadence.
The product is about a phone that might ring. That's the design's organizing metaphor, deliberately, rather than a generic dashboard treatment:
#E8A33D) is the one accent color reserved for calls-to-action and the brand mark, so it stays meaningful rather than decorative.#3F7C5D) marks strong matches and matched skills; a quiet wine (#8B3A55) marks gaps - both desaturated enough to sit calmly in a list of five without turning the screen into a traffic light.| Token | Hex | Use |
|---|---|---|
| Ink | #12172B |
Text, headers, primary buttons |
| Cloud | #F6F4EE |
App background |
| Panel | #FFFFFF |
Cards |
| Signal Amber | #E8A33D |
Accent, primary CTA, brand mark |
| Dial Green | #3F7C5D |
Strong match / matched skill |
| Ring Wine | #8B3A55 |
Gap / missing skill |
| Static Grey | #8D93A6 |
Secondary text |
First-time use 1. Land on Resume tab → paste resume → tap "Find matching jobs" 2. Matches tab populates, sorted by score 3. Tap top card → detail view: score, reasoning, skill gaps, contact 4. Tap "Run live AI analysis" for a full written breakdown and tailored bullet suggestions on that specific role 5. Switch to Contacts → see every recruiter surfaced so far in one place
Returning use 1. Open app → land directly on Matches (resume already stored) 2. New roles since last visit are visually marked "New" via the freshness chip 3. Score re-ranks automatically as new postings arrive or the resume is updated