Build a Korean Job Application Tracker in Claude

Build a Korean job application tracker in Claude. One prompt replaces your Excel spreadsheet with a ready-to-use tracker in about 60 seconds.

Share
job application tracker

Stop using excel spreadsheets to track your Korean job applications. Instead, try using Claude to build an interactive job tracker.

No more having to format complicated excels formulas, or spend hours trying to make it look organized. This one prompt will build out the entire thing for you in one click.

Here’s the step-by-step guide.

Korean job application tracker in Claude Prompt

Open Claude Cowork, paste the below prompt, and it builds the whole thing. Not a formatted spreadsheet. An actual interactive board you click into.

Here's the prompt:

korean-job-tracker-prompt
You are a senior product designer and front-end engineer building me a state-of-the-art AI Job Tracker for the Korean job market, as a Live Artifact: a single self-contained HTML file, persistent via localStorage, that opens in the Cowork sidebar. Not a one-off. A tool I will open every time I apply to a job in Korea or hear back from one. Premium polish, conversational input, built for the realities of job-hunting in Korea as a foreigner  visa sponsorship uncertainty, slower and quieter hiring cycles, and a stage structure (written tests, executive interviews) that doesn't match the standard Western funnel.

Step 1: Interview me

Before you build anything, walk me through these questions one at a time. Warm and concise tone. Wait for my answer before moving to the next question.


What's your first name? I'll use this to sign every follow-up email the tracker drafts on your behalf.
What kind of role are you applying for in Korea? (e.g., software engineering, marketing, teaching-adjacent/education, finance, product, design, ops, sales, etc.) I'll use this to seed your tracker with realistic example jobs at companies that actually hire foreigners in Korea, and to tone the follow-up emails correctly.
What's your visa/work-authorization situation? (Already have work authorization — F-visa, permanent residency, citizenship / Need an employer to sponsor a visa, most likely E-7 / Not sure yet, still researching.) This decides whether visa-sponsorship status gets surfaced as a prominent flag on every job card — for most of KOVE's audience, this is the single biggest filter on which jobs are even worth pursuing.
What's your Korean language level? (None/very basic / conversational / business-level / fluent or native.) This shapes whether the tracker's stage labels and follow-up drafts assume Korean-language interview rounds, and whether follow-up emails should proactively address language ability.
Do you want to start with an empty tracker, or seed it with 5 example jobs in your field so you can see how everything works? You can delete them in one click. (If seeded, I'll generate 5 realistic example jobs at companies known to hire foreign talent in Korea — large Korean firms, Korea offices of global companies, and Korea-native tech companies — spread across the stages: some active at different points in a Korean hiring pipeline, one stalled, one closed.)
Pick a follow-up email tone: warm and conversational, professional and formal, or direct and startup-flavored. This shapes the voice of every email the tracker drafts — note that even the "direct and startup-flavored" option stays within Korean professional correspondence norms, which run more formal than US/Western equivalents even at companies like Toss or Woowa Brothers.
Anything else I should know that would help? (Optional. Example: "I'm applying from outside Korea, so time zones matter for interview scheduling," or "I'm only looking at roles that confirm E-7 sponsorship upfront," or "most of my leads come through a headhunter, not direct applications." If nothing comes to mind, just say skip.)


After my answers, build the artifact. Do not show me any code or summaries first. Just build it and publish.

Step 2: Build the artifact

Build a single self-contained HTML file and publish via mcp__cowork__create_artifact with id "kove-job-tracker". The artifact must work exactly as specified below.

Seed data (on first render only, if localStorage is empty)

Compute today's date dynamically using new Date(). Use that as the anchor for all relative dates ("Updated Xd ago," stalled calculations, weekly review windows).

If the user picked "empty tracker" in Step 1, skip seeding and let them add jobs via the chat input.

If the user picked "seeded tracker," generate 5 example jobs in the user's stated field. Use real, recognizable companies known to hire foreign talent in Korea — large Korean employers (e.g. Samsung, LG, SK, Naver, Kakao), Korea-native tech/unicorns (e.g. Coupang, Toss/Viva Republica, Woowa Brothers, Wanted, Line), or the Korea office of a global company (e.g. Google Korea, Amazon Korea, Deloitte Korea, EY Korea). Spread the stages so all states are visible:


Job 1: Far along. Applied ~28 days ago, lastUpdated ~5 days ago. Stages completed through Executive Interview. Notes mention a specific upcoming touchpoint (e.g. salary/처우 discussion scheduled) and confirm visa sponsorship as "Yes."
Job 2: Mid-pipeline. Applied ~20 days ago, lastUpdated ~4 days ago. Stages completed through 2nd/Practical Interview. Notes mention an upcoming round, an interviewer first name, and visa sponsorship as "Unknown — need to ask."
Job 3: Early. Applied ~12 days ago, lastUpdated ~6 days ago. Stages completed through 1st Interview. Notes mention a scheduled recruiter or headhunter call. Sourced via a named platform (see "Source platform" below).
Job 4: Stalled. Applied ~40 days ago, lastUpdated ~40 days ago (no movement since document screening). Stages completed only through Applied. Notes mention how they applied (referral, headhunter, direct posting) and note it's been silent since. Status active, amber-tinted.
Job 5: Closed (rejected). Applied ~35 days ago, lastUpdated ~19 days ago. Stages completed through 1st Interview. Notes mention the outcome  either a polite rejection email or, just as realistically, "no response after 3 weeks, presumed closed" (see the "No response" closing reason below  this is common in Korean hiring and shouldn't be modeled as an anomaly).


Active tab renders by default. The first 4 sit in Active, with Job 4 amber-tinted and a "Generate next move" button. Job 5 lives under Closed.

Three tabs


Active: every job whose status !== 'closed' (stalled jobs included, amber-tinted in place).
Stalled: subset of active where (today - lastUpdated) >= 10 days (not 7 — Korean document screening and inter-round scheduling routinely take 1–3 weeks, and following up too early reads as impatient rather than proactive). Each card surfaces a "Generate next move" button.
Closed: offers, rejections, no-response closes, and withdrawals.


Job card


Company (serif heading) + role.
Visa sponsorship badge, small colored pill next to the company name: "Sponsors visa" (sage), "Does not sponsor" (rose), or "Unknown — confirm" (amber, default for new jobs unless stated). Clicking it cycles through the three states. This is the single most decision-relevant flag for KOVE's audience and should be visually prominent, not buried in notes.
Source platform tag: Saramin / JobKorea / Wanted / LinkedIn / Rocket Punch / Headhunter / Referral / Direct / Other. Small pill, editable via dropdown. Feeds the weekly review's channel-mix insight.
Application date + relative "Updated Xd ago."
Horizontal progress line across the card with 6 checkpoints, relabeled to match a real Korean corporate hiring pipeline rather than a generic Western funnel: Applied → Aptitude/Written Test → 1st Interview → 2nd/Practical Interview → Executive Interview → Offer & Terms. (Many companies skip the aptitude/written test stage — clicking any later stage still auto-completes everything before it, so skipping is handled naturally.) Checkboxes use a satisfying elastic pop animation on tap. Clicking a stage auto-completes all earlier stages. Un-checking clears later ones.
Notes textarea (interviewer names, headhunter contact, test format, visa questions asked, salary/처우 discussion). Auto-saves on blur.
AI button: "Generate next move" on stalled cards (amber). "Draft follow-up" on active cards (sage).
Footer: "Mark offer / Rejected / No response / Withdrew" buttons. ("No response" is a distinct, first-class closing reason — Korean employers frequently never send a formal rejection, and forcing that reality into a generic "rejected" bucket erases something the user should be able to name honestly.) Closed cards get a "Reopen" button.


Chat input (top of artifact)

Conversational input field. When the user types things like "I just applied to Coupang for a supply chain role" or "I had my practical interview at Toss, moving to executive round":


Parse the natural language.
If anything is missing, ask ONE clarifying question.
Add or update the job card in real time.
Confirm concisely ("Got it, added Coupang," "Checked off 2nd Interview for Toss").


CRITICAL — Parser architecture

Do NOT route every message to window.cowork.askClaude. Build a deterministic regex fast-path first, with the LLM as fallback. Without this, the parser will fail on common inputs.

The fast-path must handle:


"(just) applied to/at/with <company> for/as (a|an|the) <role>" → action=add.
"(just) applied to <company>" with no role → action=clarify, ask "What role at <company>?", store pendingClarification. The user's next message becomes the role.
Existing-company stage updates: match the company name case-insensitively against state.jobs, then map phrases to the Korea-pipeline stages:

"applied / submitted / sent my resume / sent my 자소서"  applied
"aptitude test / written test / 인적성 / 필기시험 / online assessment / coding test"  aptitudeTest
"1st interview / first round / phone screen / video interview / round 1"  interview1
"2nd interview / practical interview / technical interview / portfolio review / take-home / whiteboard / onsite / round 2"  interview2
"executive interview / final round / final interview / 임원면접 / CEO interview / panel"  executiveInterview
"offer / 처우협의 / salary negotiation / got the job / decision"  offerTerms



"going to / moving to <stage>" means complete the PRIOR stage (not the target). e.g., "had my practical interview, going to executive round"  interview2=true.
Closing: "rejected / passed / didn't move forward"  action=close, outcome=rejected. "haven't heard back in weeks / went silent / ghosted"  action=close, outcome=noResponse. "got an offer / accepted / signed"  offer. "withdrew / pulled out"  withdrawn.
Case-insensitive company match. TitleCase new company and role names.


Only fall through to askClaude when the regex returns null. The LLM prompt should request a strict JSON object with: action ("add" | "update_stage" | "update_notes" | "close" | "clarify" | "unknown"), jobId, company, role, stageKey, stageValue, appendNotes, closedOutcome, clarifyQuestion, confirmation. Extract JSON robustly (strip code fences, balance braces). If the LLM returns action=unknown or throws, attempt the regex parser one more time in "loose" mode (bare company mention adds a note) before showing an error.

CRITICAL  Response coercion

window.cowork.askClaude may return a plain string OR a structured object. Never assume the shape. Calling String(obj) on the wrong shape yields [object Object] in the UI. Implement a coerceText(res) helper that handles every shape:


plain string
{ text: "..." }
{ content: "..." } or { content: [{ type: 'text', text: '...' }, ...] }
{ message: { content: ... } }
{ response | output | completion: ... }
{ choices: [{ message: { content: ... } }] }
arrays of the above (concatenate)


Pass every askClaude response through coerceText before using it. Never String(res) directly on the response.

CRITICAL  Timeouts and optimistic rendering (don't make the user wait)

window.cowork.askClaude can take a long time, and sometimes it hangs. The artifact must NEVER show a spinner with no content. Implement a withTimeout(promise, ms) helper:

jsfunction withTimeout(promise, ms) {
  return new Promise((resolve, reject) => {
    const t = setTimeout(() => reject(new Error('timeout')), ms);
    Promise.resolve(promise).then(
      v => { clearTimeout(t); resolve(v); },
      e => { clearTimeout(t); reject(e); }
    );
  });
}

Wrap EVERY askClaude call with it:


Follow-up draft: 8 seconds.
Chat parser fallback: 6 seconds.
Weekly coach line: 6 seconds.


Optimistic rendering pattern (use everywhere a deterministic fallback exists):


Render the deterministic template (or local fallback) INSTANTLY.
Show a subtle label like "Draft ready · polishing with AI…".
Race the LLM against the timeout.
If the LLM wins AND the response passes validation (length >= 60, not [object Object], passes isRecruiterVoice check), swap it in.
Otherwise leave the template in place and just remove the "polishing" label.


Never block UI rendering on an LLM call.

Next move / Draft follow-up button

Calls window.cowork.askClaude (wrapped in withTimeout) to draft a follow-up email. CRITICAL: get the perspective right on the first try, AND get Korean professional-correspondence formality right — this audience is foreigners who often under-formalize by Korean standards without realizing it.

Perspective (the #1 failure mode, be explicit):
The email is written FROM the candidate (the user, by their first name collected in Step 1) TO the interviewer, recruiter, or headhunter. Not the other way around. The naive prompt "write a follow-up message for a job applicant" is ambiguous, and the model defaults to writing AS a recruiter TO the candidate ("Hi [Name], we were impressed by your..."). That is WRONG.

Spell it out in the prompt to askClaude:


Author: the candidate, by first name (use the name collected in Step 1).
Recipient: the interviewer, recruiter, or headhunter named in the notes if present. Otherwise, "the hiring team."
First-person ("I", "my") refers to the candidate. Second-person ("you", "your", "the team") refers to the recipient.
Forbid recruiter phrases: "we were impressed by your," "you're exactly the kind of," "we'd like to move you forward," "we're excited to have you," "expect to hear from us," "thank you for applying," "your candidacy," "based on your interview," "we will contact you after internal discussion," "please await our decision," etc.
Greeting addresses the interviewer/recruiter by name, not the candidate.
Sign-off is "Best, [candidate first name]" — never [Name] or [Signature] placeholders.


Korean professional-correspondence norms (apply regardless of which tone the user picked in Step 1 — even "direct and startup-flavored" stays inside this floor):


Always explicitly thank the recipient for their time — omitting this reads as abrupt to a Korean-side reader, even at a startup like Toss or Woowa Brothers.
No humor, no self-deprecation, no overly casual openers ("hey!", "just wanted to..."). Sincere and warm is fine; flippant is not.
If the job's notes mention the role was sourced through a headhunter, the follow-up should be addressed to the headhunter contact, not the hiring manager, unless notes indicate a direct relationship was already established.
If the job's visa-sponsorship badge is "Unknown  confirm" and the stage is early (Applied or Aptitude/Written Test), the follow-up may include one brief, professional line proactively confirming the candidate's visa/work-authorization status and availability to start — foreign candidates often forget to raise this early, and Korean hiring teams frequently need it before proceeding.


Include both a correct example (candidate writing to a named interviewer, appropriately formal) and a wrong example (recruiter writing to the candidate) in the prompt itself so the model cannot drift.

Other constraints:


90 to 130 words.
Salutation + 2 to 3 short paragraphs + sign-off as the candidate.
Mine the notes for specifics (names, test format, headhunter, visa questions, dates) and reference them naturally.
Never opens with "Hi, hope you're well" or "just checking in."
Stalled jobs → gently circling back, confident not apologetic, candidate asking for an update — but calibrated to Korean pacing (a stalled follow-up at day 10-14 should read as reasonable, not premature).
Active jobs → forward-looking touchpoint from the candidate (thank-you, prep question, scheduling, or a proactive visa-status confirmation per above).
No emoji. Return text only.
Match the email tone the user picked in Step 1, filtered through the Korean formality floor above.


CRITICAL — Deterministic fallback templates

Do NOT trust the LLM alone, and NEVER wait for it. Build a templateFollowUp(job, stalled, daysSilent) function that returns a fully-formed, candidate-voice follow-up email from the user, branching on stage (Aptitude/Written Test / 1st Interview / 2nd Interview / Executive Interview / Stalled). It must:


Extract a likely recipient first name from notes ("with <Name>", "from <Name>", or the first capitalized non-stopword).
Reference the role and company, and the headhunter if notes indicate one.
Be rendered IMMEDIATELY when the button is clicked (no waiting), then optionally replaced by the LLM version per the optimistic-rendering pattern.
Be the only thing shown if any of the following are true:

LLM response is empty, under 60 chars, or contains [object Object].
isRecruiterVoice() flags the LLM output (see below).
The LLM call times out or throws.





CRITICAL — Recruiter-voice detector

Implement isRecruiterVoice(text) that returns true if the output contains any of:


"we were/are impressed by your"
"you're exactly the kind of"
"we'd/we would like to move/invite/advance you"
"we want you on (our|the) team"
"expect to hear (back) from us"
"we'll/we will be in touch / reach out / follow up / get back to you"
"thank you for applying / your interest in"
"we're moving you into the next round"
"the team is/was excited about|to meet/interview"
"your candidacy"
"our hiring team/manager/committee"
"we will contact you after internal discussion / review" (a very common Korean-HR-email-in-translation phrase — still wrong-perspective if the candidate is supposedly the author)
"please await our decision / further notice"
Salutation that begins with the candidate's own first name as the addressee (e.g., "Hi <candidate-name>", "Hello <candidate-name>", "Dear <candidate-name>"). If the candidate is the recipient, perspective is flipped.
Sign-off from "the hiring team / recruiting team / talent team / HR team"


Any match  discard the LLM output and use templateFollowUp instead.

Also strip placeholder signatures ([Name], [Your Name], [Signature]) and replace with the candidate's first name collected in Step 1.

Render the output inline below the button with a Copy button.

Weekly review panel

Toggle at the bottom expands a navy panel with white text showing:


Applications submitted this week vs last week (+delta).
Interviews moved (stages advanced) this week.
Stale jobs needing follow-up.
Visa-sponsorship coverage: how many active jobs still have "Unknown — confirm" as their sponsorship status, since chasing that answer early saves wasted prep time.
Channel mix: which source platforms (Saramin / JobKorea / Wanted / LinkedIn / headhunter / referral / direct) the active pipeline is concentrated in, so the user can see if they're over-reliant on one channel.
One AI coaching line via askClaude (wrapped in withTimeout(6000), response passed through coerceText), max 35 words, references the actual pipeline and Korea-specific patterns  e.g. "3 of your last 5 stalled right after document screening — that often points to resume formatting, not fit," or "all 5 active applications came through Saramin, try cross-posting to Wanted or LinkedIn Korea"  not boilerplate. Cached so it does not regenerate on every render. Render a deterministic local fallback FIRST, then upgrade if the LLM returns something better in time.


Visual design


White/cream background (#fbfaf7), navy headers (#002e3c), accent (#ff3758), warm amber for stalled/unknown-sponsorship (#ffb518), muted rose for rejections/non-sponsoring badges.
Custom serif for headings: Fraunces or Playfair Display from Google Fonts. Inter for body.
Job cards: 14px rounded corners, soft shadow depth, 1px line border.
Stalled cards: gradient from amber-tint to cream, amber-soft border.
Stage circles: 26px, sage fill with white check on completion, elastic pop animation (cubic-bezier(.6, -0.4, .3, 1.6), keyframes scale 0.6  1.25  1.08).
Horizontal progress bar threads behind the circles, fills to the % of completed stages.
Tabs are pill-style segmented control with count badges.
Mobile-readable (max-width 920px, responsive grid).
Looks like something a $200/hour career coach who actually knows the Korean market would send you  not a generic template with the labels swapped.


Persistence

Single localStorage key ("kove.jobtracker.v1") holds { jobs, chat, activeTab, reviewOpen, seeded, userName, emailTone, visaStatus, koreanLevel }. Save on every mutation. Reload tomorrow or next month  everything is exactly where it was left, including chat history (capped at last 50 messages) and which tab was open. userName, emailTone, visaStatus, and koreanLevel are set once from the Step 1 interview and persisted. Each job object additionally carries visaSponsor ("sponsors" | "no" | "unknown") and sourcePlatform.

Date handling

Use new Date() for today. All "Updated Xd ago," stalled calculations (≥10 days), and weekly review windows use that anchor. Seed data uses dates computed relative to today so it always looks fresh.

Summary of non-obvious requirements (read twice)


Regex parser BEFORE the LLM for chat input. Common phrases like "applied to X for Y" or "moving to executive round" must work without an LLM round-trip.
coerceText(askClaudeResponse) everywhere you use the LLM. Never String(res). The response is often an object, not a string.
withTimeout wraps every askClaude call (6 to 8 seconds) and the deterministic fallback renders INSTANTLY. Nothing in the artifact waits on the LLM. The LLM only ever upgrades content that is already on screen.
Follow-up perspective is FROM the candidate TO the interviewer/headhunter  AND every follow-up clears the Korean formality floor (gratitude stated explicitly, no casual openers) regardless of tone setting. The model will get both wrong without explicit examples and a post-hoc isRecruiterVoice detector that triggers a template fallback.
Stage labels match a real Korean hiring pipeline (Applied  Aptitude/Written Test  1st Interview  2nd/Practical Interview  Executive Interview  Offer & Terms), not the generic Western 5-stage funnel. Stalled threshold is 10 days, not 7, because Korean screening and scheduling cycles run slower.
Visa-sponsorship status is a first-class, prominent field on every card  not buried in notes  because it's the single most decision-relevant fact for this audience.
"No response" is a distinct closing reason, separate from "Rejected" — Korean employers frequently never send a formal rejection, and the tool should let the user name that honestly.
Deterministic templates for every LLM-generated string: follow-up emails, coaching note. The artifact must work even if the LLM is offline, slow, or returns garbage.
Sign emails as the candidate's first name (collected in Step 1), never as [Name] or [Signature]. Strip placeholders if they sneak through.


Build the HTML file, then publish via mcp__cowork__create_artifact with id "kove-job-tracker".

That's it. No formulas. You get a board with a button to add a new job and a button to update any one already on it. Change a status from "applied" to "interviewing," drop in a note about who you talked to, set the date you need to follow up. Every change is a click, not a cell edit.

If you want to tweak the prompts for your own search, just ask Claude in plain language. Add a salary range field, a visa-sponsorship yes/no, a column for which platform the role came from. You describe it, it rebuilds.


Here’s the ideal output:

example output of a korean job tracker
example output of a korean job tracker

The part that actually matters: it remembers

Because this is built as a Claude artifact, you can close it, walk away, come back next week, and you land exactly where you left off.

A Claude artifact is interactive, self-contained workspaces generated by Claude, so basically you can easily click back into it, instead of having buried under other chats and projects.

example claude artifact for korean job tracker
example claude artifact for korean job tracker

Be honest about what this tool does and doesn't do. A tracker keeps you organized and keeps you on time. It does not get you the interview. That part is still your resume, your portfolio, and how well you're positioned for the Korean market as a foreigner.

So think of the tracker as half the setup. The other half is a resume that actually lands the interview in Korea, which works differently than it does back home. Format expectations, how you handle your visa status, what a Korean hiring manager scans for first, all of it matters more than most people applying from abroad realize.

If you need more help with your resume and positioning for the Korean job market, feel free to reach out to me here.

Grab the free job search guide

Download the free starter guide to learn the Korean-style resume format and how to target English-friendly, visa-sponsoring companies.