Inferensys

Prompt

Job Posting Free Text to Structured Requisition Prompt Template

A practical prompt playbook for converting unstructured job descriptions into structured requisition records in production AI workflows.
Developer doing prompt engineering on laptop, prompt variations visible on screen, casual coding session.
PROMPT PLAYBOOK

When to Use This Prompt

Define the job, ideal user, and constraints for converting free-text job descriptions into structured requisition records.

This prompt is designed for recruiting platform engineers and integration developers who need to convert unstructured job descriptions—pasted from emails, web pages, or documents—into clean, typed requisition records. The core job is to extract and normalize fields like title, location, salary range, responsibilities, and qualifications from messy free text, producing a JSON object that can be ingested by an applicant tracking system (ATS) or job board API. The ideal user is building a data pipeline where human-readable job posts must become machine-readable records without manual data entry.

Use this prompt when the input is a single, self-contained job description in plain text or markdown. It is designed for cases where the model failed to produce structured output in the first pass, or where you are processing legacy text that was never structured. The prompt template includes placeholders for the raw input text, a target output schema, and constraints like required-vs-preferred classification for qualifications. It is not suitable for batch processing of hundreds of job descriptions in a single call, for extracting requisitions from multi-job career pages, or for parsing non-English text without adapting the schema and instructions. Do not use this prompt where the extracted data will directly trigger automated hiring decisions without human review.

Before wiring this into production, define your output schema precisely and prepare a golden dataset of 20-50 job descriptions with known correct extractions. Run the prompt against this dataset and measure field-level accuracy, especially for skill extraction and salary range normalization. Pay close attention to failure modes like hallucinated qualifications, misclassified required-vs-preferred skills, and salary ranges parsed from the wrong currency or pay period. The next section provides the copy-ready template you can adapt with your own schema and validation rules.

PRACTICAL GUARDRAILS

Use Case Fit

Where this prompt works, where it fails, and what you must provide before using it in production.

01

Good Fit: Structured ATS Ingestion

Use when: you have a free-text job description from a hiring manager or a legacy system and need a typed requisition record for an Applicant Tracking System (ATS). Guardrail: The prompt excels at extracting explicit fields like title, location, and requirements. Always validate the output against a strict JSON schema before ingestion.

02

Bad Fit: Implicit or Cultural Nuance

Avoid when: the job posting relies heavily on unwritten cultural norms, internal jargon, or implied seniority levels not stated in the text. Guardrail: The model will miss subtext. If a role's level is only implied by salary band, do not rely on the prompt to infer it. Route these cases for human review and explicit tagging.

03

Required Input: Raw Text with Explicit Delimiters

What to watch: The prompt fails silently if the input is a scanned image, a poorly OCR'd PDF, or a webpage with mixed navigation and body text. Guardrail: Pre-process the input to isolate the job description body. Strip headers, footers, and boilerplate before sending it to the model to prevent hallucinated fields from navigation elements.

04

Operational Risk: Required vs. Preferred Drift

What to watch: The model often misclassifies 'nice-to-have' skills as strict requirements, inflating the barrier to entry. Guardrail: Implement a post-processing eval that flags any requirement not preceded by a 'must-have' keyword in the source text. If confidence is low, route the record to a human for a quick binary classification check.

05

Operational Risk: Salary Range Hallucination

What to watch: If a salary range is not explicitly stated, the model may infer one based on the job title and location, introducing fabricated data into a compliant record. Guardrail: Add a hard constraint in the prompt to set the salary field to null if no explicit range is detected. Use a post-generation validator to reject any output where the salary field is populated but the source text lacks a currency symbol.

06

Bad Fit: Multi-Lingual Code-Switching

Avoid when: the job posting mixes languages within a single sentence or uses a non-English language for key technical terms. Guardrail: The model may drop or mistranslate critical terms. For multi-lingual posts, use a translation layer first, or route to a human who can verify that the structured output preserves the original technical terminology.

PROMPT PLAYBOOK

Copy-Ready Prompt Template

A reusable prompt template for converting free-text job descriptions into structured requisition records with typed fields, classification, and validation flags.

This prompt template transforms unstructured job posting text into a machine-readable requisition record. It is designed for recruiting platform engineers who need to ingest free-text job descriptions from emails, career sites, or hiring manager notes and produce a consistent JSON payload for downstream ATS, CRM, or approval workflows. The template uses square-bracket placeholders that you replace with your actual input, output schema, constraints, and examples before sending to the model.

text
You are a recruiting data extraction system. Your task is to convert the following free-text job posting into a structured requisition record.

## INPUT
[INPUT]

## OUTPUT SCHEMA
Return ONLY valid JSON matching this schema:
{
  "title": "string (normalized job title)",
  "department": "string | null",
  "location": {
    "city": "string | null",
    "state": "string | null",
    "country": "string | null",
    "remote": "boolean",
    "hybrid": "boolean"
  },
  "employment_type": "string (enum: full-time, part-time, contract, internship, temporary)",
  "salary_range": {
    "min": "number | null",
    "max": "number | null",
    "currency": "string | null",
    "period": "string | null (enum: hourly, monthly, annual)"
  },
  "requirements": [
    {
      "skill": "string",
      "classification": "string (enum: required, preferred, nice-to-have)",
      "years_experience": "number | null"
    }
  ],
  "responsibilities": ["string"],
  "qualifications": {
    "education": "string | null",
    "certifications": ["string"],
    "clearance": "string | null"
  },
  "benefits": ["string"],
  "posting_date": "string (ISO 8601 date) | null",
  "closing_date": "string (ISO 8601 date) | null",
  "contact_email": "string | null",
  "company_name": "string | null",
  "extraction_confidence": "number (0.0 to 1.0)",
  "missing_fields": ["string (field names that could not be extracted)"],
  "ambiguous_phrases": ["string (phrases that had multiple interpretations)"]
}

## CONSTRAINTS
[CONSTRAINTS]

## EXAMPLES
[EXAMPLES]

## INSTRUCTIONS
1. Extract every field that is explicitly stated in the input.
2. Set fields to null or empty arrays when no information is available—do not invent values.
3. Classify each requirement as "required," "preferred," or "nice-to-have" based on language cues (e.g., "must have" = required, "bonus" = nice-to-have).
4. Normalize job titles to industry-standard forms (e.g., "Sr. SWE" → "Senior Software Engineer").
5. Parse salary ranges even when formatted inconsistently (e.g., "$80-100k" or "80,000 to 100,000 per year").
6. Set extraction_confidence based on how much of the schema you could populate from explicit text (1.0 = all fields populated from text, 0.0 = no fields populated).
7. List any fields you could not populate in missing_fields.
8. List any phrases where you were uncertain about interpretation in ambiguous_phrases.
9. Return ONLY the JSON object. No markdown, no explanation.

To adapt this template, replace [INPUT] with the raw job posting text, [CONSTRAINTS] with any domain-specific rules (e.g., "only accept US-based roles" or "require salary transparency"), and [EXAMPLES] with one or two input-output pairs that demonstrate correct extraction and classification behavior. The examples are critical for teaching the model how to distinguish required from preferred skills and how to handle edge cases like equity-only compensation or multi-location roles. If you are processing job postings in a regulated industry or where hiring decisions have legal implications, add a human review step before the structured record enters any downstream system of record.

IMPLEMENTATION TABLE

Prompt Variables

Required inputs for the Job Posting Free Text to Structured Requisition prompt. Each placeholder must be populated before the prompt is assembled and sent to the model. Validation notes describe how to verify the input is ready for production use.

PlaceholderPurposeExampleValidation Notes

[JOB_POSTING_TEXT]

Raw free-text job description from any source

We are looking for a Senior Backend Engineer to join our payments team in New York. You will design APIs, optimize database queries, and mentor junior engineers. 5+ years of experience required. Competitive salary and equity.

Non-empty string check. Minimum 50 characters to ensure enough signal. Reject inputs that are only URLs or file paths without extracted text.

[OUTPUT_SCHEMA]

Target JSON schema the structured requisition must conform to

{"type":"object","properties":{"title":{"type":"string"},"requirements":{"type":"array","items":{"type":"string"}},"responsibilities":{"type":"array","items":{"type":"string"}},"location":{"type":"string"},"salary_range":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"},"currency":{"type":"string"}}},"qualifications":{"type":"object","properties":{"required":{"type":"array","items":{"type":"string"}},"preferred":{"type":"array","items":{"type":"string"}}}}},"required":["title","requirements","responsibilities","location"]}

Valid JSON Schema parse check. Schema must include required field constraints. Reject schemas that allow arbitrary additional properties without explicit design intent.

[FIELD_DEFINITIONS]

Natural language descriptions of what each output field means and how to populate it

title: The job title exactly as stated or inferred from the posting. requirements: Hard skills, years of experience, certifications that are non-negotiable. responsibilities: Day-to-day tasks and outcomes the role owns. location: City, state, remote policy, or hybrid arrangement. salary_range: Only populate if explicit numbers appear in the text; do not infer. qualifications.required: Must-have qualifications. qualifications.preferred: Nice-to-have qualifications.

Non-empty string check. Each field definition must include extraction rules and null-handling guidance. Reject definitions that say 'extract whatever you find' without boundary rules.

[CLASSIFICATION_RULES]

Rules for distinguishing required qualifications from preferred qualifications

Required indicators: 'must have', 'required', 'minimum', 'non-negotiable', 'you will need'. Preferred indicators: 'nice to have', 'bonus', 'preferred', 'familiarity with', 'experience with X is a plus'. When ambiguous, classify as preferred and flag with confidence score.

Non-empty string check. Rules must include indicator keywords and a tie-breaking default. Test with edge cases: 'experience with Python required, Java a plus' should split correctly.

[NULL_HANDLING_POLICY]

Instructions for when to leave fields null versus omit them versus infer values

salary_range: null if no numbers appear in text. location: infer from context clues like 'NYC office' or 'remote US' but flag confidence. qualifications.preferred: empty array if no preferred qualifications detected. Never hallucinate values to fill required fields.

Non-empty string check. Policy must distinguish null (known absent), empty array (none detected), and omitted (field not applicable). Test with postings that mention zero salary information.

[CONFIDENCE_THRESHOLD]

Minimum confidence score for extracted fields to be included without a flag

0.85

Float between 0.0 and 1.0. Values below threshold should trigger a low_confidence flag in the output rather than omission. Default to 0.80 if not specified. Reject thresholds below 0.50 as too permissive.

[MAX_OUTPUT_TOKENS]

Token budget for the structured output to prevent truncation

4096

Integer greater than 500. Must account for the largest expected requisition record. Set to at least 2x the estimated output size to allow for verbose postings. Monitor production for truncation errors and adjust upward.

PROMPT PLAYBOOK

Implementation Harness Notes

How to wire the job posting conversion prompt into a production application with validation, retries, and human review.

This prompt is designed to be called as a post-processing step in a recruiting pipeline, not as a standalone chat interface. The typical integration pattern is: an upstream system (ATS, email parser, or career site scraper) ingests the free-text job description, passes it to this prompt via an API call, and the structured output is validated before being written to the requisition database. Because the prompt handles unstructured-to-structured conversion, it should be treated as a data transformation step with the same rigor as an ETL job—including schema validation, error handling, and observability.

Validation and Retry Logic: The prompt output must pass a JSON schema validator before being accepted. Key checks include: required fields present (title, requirements, responsibilities), salary_range conforming to {min, max, currency} shape, and qualifications correctly split into required and preferred arrays. If validation fails, implement a single retry by appending the validation error to the prompt as [PREVIOUS_ERRORS] and re-running. Do not retry more than twice—after two failures, route the job posting to a human review queue with the original text and both failed attempts attached. This prevents infinite loops on genuinely ambiguous or malformed inputs.

Model Choice and Latency: For this task, prefer models with strong instruction-following and JSON mode support (e.g., GPT-4o, Claude 3.5 Sonnet). Enable structured output mode if the provider supports it, as this dramatically reduces malformed JSON rates. Set a timeout of 15 seconds for the API call; if the model exceeds this, fall back to a faster model (e.g., GPT-4o-mini) for the retry. Log every conversion attempt with the input hash, model used, latency, and validation result. This trace data is essential for debugging extraction quality over time and identifying job descriptions that consistently break the pipeline.

Human-in-the-Loop Integration: Even when validation passes, flag outputs for human review if the model's confidence indicators are low—specifically, if [CONFIDENCE_FLAGS] in the output contains warnings about ambiguous skill classification or conflicting requirements. Build a simple review UI that shows the original free text side-by-side with the structured record, highlighting fields that were flagged. This is not optional for regulated industries or roles with compliance requirements (e.g., healthcare, finance). The prompt template includes a [RISK_LEVEL] parameter; when set to high, the harness should enforce mandatory human approval before the record enters the requisition database.

Next Steps: After integrating this prompt, run a batch evaluation against 50–100 historical job postings with known-good structured records. Measure field-level accuracy (especially skill extraction and required-vs-preferred classification) and track the retry rate. Use these metrics to tune the prompt's few-shot examples and field descriptions. Avoid the temptation to add more fields to the output schema without updating the eval harness—every new field is a new failure mode.

IMPLEMENTATION TABLE

Expected Output Contract

Define the exact shape of the structured requisition record. Use this contract to build a downstream validator, schema, or API payload. Every field must be parseable and verifiable.

Field or ElementType or FormatRequiredValidation Rule

requisition_id

string (UUID v4)

Must be a valid UUID v4 string. Generate if not present in [INPUT].

title

string

Must be extracted from [INPUT]. Cannot be empty or 'Untitled'. Max 200 chars.

department

string | null

If inferred, append ' (inferred)'. Null allowed if no signal in [INPUT].

location

object

Must contain 'city' (string), 'state' (string | null), 'country' (string), and 'remote_allowed' (boolean). Parse from [INPUT].

employment_type

enum

Must be one of: 'Full-time', 'Part-time', 'Contract', 'Temporary', 'Internship'. Normalize from [INPUT] text.

salary_range

object | null

If present, must have 'min' (number), 'max' (number), 'currency' (ISO 4217 string), and 'interval' (enum: 'hourly', 'monthly', 'annual'). Null if no salary info in [INPUT].

summary

string

A 2-4 sentence synthesis of the role from [INPUT]. Must not introduce external facts. Max 500 chars.

responsibilities

array of strings

Each item must be a distinct, actionable statement extracted from [INPUT]. Minimum 1 item. No markdown.

required_qualifications

array of objects

Each object must have 'skill' (string) and 'years_required' (number | null). Minimum 1 item. Classify only as 'required'.

preferred_qualifications

array of objects

Each object must have 'skill' (string) and 'years_preferred' (number | null). Classify only as 'preferred'. Empty array if none.

source_text_hash

string

SHA-256 hash of the exact [INPUT] text used for extraction. Used for audit and traceability.

PRACTICAL GUARDRAILS

Common Failure Modes

When converting free-text job descriptions into structured requisition records, these failure patterns surface most often in production. Each card identifies a specific breakage and the guardrail that prevents it.

01

Skill Extraction Confuses Required vs. Preferred

What to watch: The model flattens all mentioned skills into a single list, losing the distinction between must-have qualifications and nice-to-have experience. A posting that says 'bonus if you know Rust' ends up with Rust listed as required. Guardrail: Add explicit output schema fields for required_skills and preferred_skills, and include a few-shot example where the same skill appears in different sections based on source language cues like 'must have' versus 'nice to have.'

02

Salary Range Parsing Produces Garbage Numbers

What to watch: Free-text salary descriptions like 'competitive,' 'based on experience,' or '120-180k plus equity' produce hallucinated numbers, null fields, or unparseable strings instead of clean min/max/currency records. Guardrail: Post-extraction type coercion and range validation. If the source text contains no explicit numeric range, set salary_range to null rather than guessing. Add a salary_notes field for non-numeric compensation language, and validate that min ≤ max when both exist.

03

Location Field Collapses Remote/Hybrid/Onsite into Ambiguous Text

What to watch: Job postings that say 'remote with quarterly travel to NYC' or 'hybrid 2 days in office' get flattened into a single city name or an unhelpful 'Remote' string that loses the nuance needed for candidate matching. Guardrail: Use a structured location object with type (remote/hybrid/onsite), primary_location, remote_details, and travel_requirements fields. Add enum constraints on type and validate that hybrid entries include a primary location.

04

Responsibilities and Qualifications Get Swapped or Merged

What to watch: The model places '5+ years of experience' under responsibilities or 'manage a team of 4' under qualifications. When the source text is poorly structured, the model guesses section boundaries and gets them wrong. Guardrail: Include a classification step before extraction that identifies which spans of text belong to responsibilities versus qualifications. Add a post-extraction sanity check: if a qualification field contains action verbs like 'manage' or 'build,' flag it for review.

05

Job Title Gets Over-Normalized or Fabricated

What to watch: Creative or company-specific titles like 'Developer Advocate, Cloud Native Ecosystems' get normalized to 'Software Engineer' or the model invents a title when the source text only describes the role without naming it. Guardrail: Extract the raw_title from the source text verbatim and separately produce a normalized_title for matching. If no title is present in the source, set raw_title to null rather than generating one. Flag records where raw_title is null for human review.

06

Hallucinated Requirements from Thin Context

What to watch: When the job posting is brief or vague, the model fills gaps by inventing standard industry requirements—adding 'Bachelor's degree required' or '5+ years experience' when the source text never mentioned education or years. Guardrail: Require source grounding for every extracted field. Add a source_span reference for each qualification and responsibility. Run a post-extraction hallucination check: if a field has no corresponding source span, strip it or flag it with confidence: low and route for human approval.

IMPLEMENTATION TABLE

Evaluation Rubric

Use this rubric to test the structured requisition output before integrating it into your recruiting platform. Each criterion targets a specific failure mode common in unstructured-to-structured conversion.

CriterionPass StandardFailure SignalTest Method

Skill Extraction Accuracy

All hard skills mentioned in [JOB_DESCRIPTION] appear in the output with correct classification as required or preferred

A technical skill from the source text is missing, misclassified, or hallucinated

Diff extracted skills against a manually labeled skill list from 20 test job descriptions

Required vs. Preferred Classification

Skills explicitly labeled as required in source are tagged as required; nice-to-have language maps to preferred

A skill described as mandatory in source is tagged as preferred, or vice versa

Spot-check 10 skills across 5 job descriptions for correct boolean flag on [REQUIRED] field

Salary Range Normalization

Salary is parsed into [SALARY_MIN], [SALARY_MAX], and [SALARY_CURRENCY] with consistent annualized values

Hourly rate left as annual, currency missing, or range inverted where min exceeds max

Validate [SALARY_MIN] < [SALARY_MAX] and currency is ISO 4217 code for 30 test outputs

Location Field Completeness

Output contains [CITY], [STATE], [COUNTRY], and [REMOTE] boolean derived from source text

Remote-only roles missing city/state, hybrid roles missing office location, or [REMOTE] is null

Assert all four fields are non-null and [REMOTE] is true or false for 50 test postings

Responsibility Extraction Fidelity

Each responsibility in output is traceable to a sentence or clause in the source job description

Output contains a responsibility not mentioned in source, or merges two distinct responsibilities into one

Random sample 15 responsibilities across 5 outputs and require annotator to locate source sentence

Title Normalization

Output [TITLE] matches a standard job title without preserving internal jargon or creative titles from source

Output copies a non-standard source title verbatim instead of normalizing to a canonical role name

Check [TITLE] against a known title taxonomy; flag exact matches to source when source contains special characters or marketing language

Qualification Section Structure

Output separates [MINIMUM_QUALIFICATIONS] and [PREFERRED_QUALIFICATIONS] into distinct arrays

All qualifications dumped into a single array, or education and experience requirements mixed without separation

Assert both arrays exist and are non-empty for 25 test postings that contain both required and preferred language

Output Schema Compliance

Output validates against the expected JSON schema with all required fields present and correct types

Missing required field, wrong type for a numeric field, or extra undeclared field in output

Run automated schema validation on 100 test outputs; reject any output that fails JSON Schema validation

ADAPTATION OPTIONS

Adapt This Prompt

How to adapt

Use the base prompt with a single model call and minimal post-processing. Focus on getting the field extraction logic right before adding validation layers. Start with a small set of 10-20 job descriptions and manually review outputs.

code
[SYSTEM]: You are a recruiting data extraction assistant. Convert the following job posting into a structured requisition record.

[INPUT]: [JOB_POSTING_TEXT]

[OUTPUT_SCHEMA]:
{
  "title": "string",
  "requirements": ["string"],
  "responsibilities": ["string"],
  "location": "string",
  "salary_range": {"min": number, "max": number, "currency": "string"} | null,
  "qualifications": {"required": ["string"], "preferred": ["string"]}
}

Watch for

  • Missing salary range extraction when format varies (e.g., "competitive", "DOE")
  • Requirements and qualifications getting merged into a single list
  • Location fields capturing remote/hybrid/onsite inconsistently
  • No confidence flags on extracted fields
Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.