| id | Yes | | |
| url | No | Link to the original job posting, when known. | |
| notes | No | The user's notes on this vacancy. | |
| title | Yes | Vacancy title (often includes company, e.g. 'Backend Engineer at Acme'). | |
| status | No | Job-tracker status: 'new' | 'applied' | 'interview' | 'offer' | 'rejected' | 'accepted'. | new |
| app_url | Yes | Link to this vacancy's page in ResumeQuick, opened after signing in to this account; with a cover letter written it opens on the Cover Letter tab that keeps the letter. | |
| company | No | Company name, when known. | |
| key_gaps | No | Gaps in the CANDIDATE relative to the posting. Never carries remarks about the posting text itself — those live in input_quality. | |
| location | No | Job location, when known. | |
| is_pinned | No | The user pinned it to the top of their tracker; lists put pinned vacancies first. | |
| step_path | No | Path on the ResumeQuick site where vacancy_step is done; null without one. | |
| analyzed_at | Yes | ISO 8601 timestamp of when the vacancy was analyzed or, if never analyzed, added. | |
| is_archived | No | Archived vacancies are hidden from the user's main list. Only an archived one can be deleted. | |
| vacancy_step | No | The step inside this vacancy, the same one its page shows: tailor, cover_letter, apply, interview (it is at Interview), another (the analysis advises against it — the user's own next step from get_next_step is the one to take), or null (the analysis is not ready, or the case waits for the employer after an application). | |
| input_quality | No | Quality of the posting text this analysis was based on. When truncated is true the score came from a fragment; analyze_tracked_vacancy re-runs it on the full text. | |
| key_strengths | No | Strong points matching the vacancy. | |
| status_history | No | Job-tracker status changes, oldest first; the history keeps the newest 100 events. | |
| analysis_status | No | 'completed' — analyzed; 'none' — tracked, never analyzed (match fields are null); 'processing' — an analysis is running right now; 'failed' — the last analysis failed. Lists only return 'completed' and 'none'; get_vacancy_detail returns every state. | completed |
| chances_summary | No | Short prose verdict on chances (e.g. 'Strong fit, apply soon'). | |
| has_description | No | Whether the posting text is stored on this vacancy (the text itself is never returned). False means it cannot be analyzed until the text is added — analyze_tracked_vacancy takes it as 'description'. | |
| recommendations | No | Actionable steps to improve fit for this vacancy. | |
| tailored_resume | No | The tailored resume copy linked to this vacancy, if one exists (created by apply_vacancy_resume_suggestions with target='copy' or create_resume_version with vacancy_id). | |
| verdict_summary | No | Final verdict — 1–3 sentences explaining the recommendation. | |
| has_cover_letter | No | Whether a cover letter for this vacancy is already written and kept on its Cover Letter tab (the text itself is never returned). cover_letter_stale true means it predates the latest re-analysis. | |
| match_percentage | No | 0–100, computed by the analysis; null for never-analyzed manual entries. | |
| verdict_category | No | One of 'apply' | 'consider' | 'skip' | 'not_eligible' | 'invalid', or null if not categorized. 'not_eligible' means a hard eligibility blocker applies — the user cannot take this role as posted no matter how high match_percentage is; eligibility_blockers carries the reason. | |
| skills_comparison | No | Skill-by-skill comparison of resume vs. vacancy requirements (the structured requirements view). | |
| cover_letter_stale | No | The stored cover letter was written before the vacancy was analyzed again. | |
| resume_suggestions | No | Structured resume-improvement suggestions for this vacancy, if generated. Empty until request_vacancy_resume_suggestions has run and completed. Their list order is the index space for apply_vacancy_resume_suggestions. | |
| cover_letter_options | No | The options the stored cover letter was written with; null when there is no letter or it predates kept options. generate_cover_letter reuses each one it is not given. | |
| eligibility_blockers | No | Why the user may not be able to take this role at all — work model, location, timezone, work authorization, relocation. Separate from skill fit and never reflected in match_percentage. Any 'hard' blocker means verdict_category is 'not_eligible', whatever the match score. Empty when nothing is known about the user or nothing conflicts. | |
| applied_suggestion_indices | No | Indices (into resume_suggestions) that have already been applied to the resume. | |
| declined_suggestion_indices | No | Indices (into resume_suggestions) of questions the person answered no to — the experience they ask about is not theirs. | |
| unchanged_suggestion_indices | No | Indices (into resume_suggestions) whose last apply changed nothing: the resume states nothing they build on yet. Applying them again changes nothing until the resume gains what they need. | |