> ## Documentation Index
> Fetch the complete documentation index at: https://docs.recruitier.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Job Details

> View comprehensive job information including description, company, and contact details.

## The Job Detail Page

When you click on a job in your search results or all-jobs list, you open the job detail
page. This is a comprehensive view that brings together everything Recruitier knows about
the listing -- from the full job description to company information, contact details, and
your personal notes and tags.

The detail page is where you make the decision to pursue an opportunity: is this job the
right fit for your candidate, and who should you contact about it?

<Info>
  Opening a job detail page automatically updates the `last_viewed_at` timestamp on the
  Job record. This helps the system track which jobs you have reviewed and clears the
  "New" indicator for that specific job.
</Info>

## Page Layout

The job detail page is organized into several sections:

### Header Section

At the top of the page, you see the essential information at a glance:

| Element                  | Description                                                                    |
| ------------------------ | ------------------------------------------------------------------------------ |
| **Job Title**            | The title as it appears on the company's career page (proxied from ScrapedJob) |
| **Company Name**         | The hiring company, linked to their company profile in Recruitier              |
| **Location**             | Where the job is based (geocoded from the listing)                             |
| **Match Score**          | The relevance percentage from your search (30-99% scale)                       |
| **Match Classification** | Excellent, good, or poor match badge                                           |
| **Status Badges**        | Indicators for expired, new, via agency, or other states                       |
| **Action Buttons**       | Favorite, tag, delete, and outreach actions                                    |

### Essential Job Information

Below the header, a structured summary provides the key job attributes:

* **Experience Level** -- Junior, medior, senior, or lead
* **Job Type** -- Full-time, part-time, contract, temporary, or internship
* **Flexibility** -- Remote, hybrid, or on-site
* **Posting Date** -- When the job was listed, including the date source (e.g., from
  JSON-LD structured data, LLM extraction, HTML metadata, visible text, URL patterns,
  sitemap, or first-seen date)
* **Number of Applicants** -- If available from the original listing
* **Salary Range** -- Minimum and maximum salary with currency (EUR), when published
* **Requirements Summary** -- An AI-extracted list of key requirements from the
  description

<Note>
  Not all job listings include every attribute. Salary, applicant count, and experience
  level depend on what the company published in the original listing. Missing fields are
  simply not displayed rather than showing placeholder values.
</Note>

## Job Description

The full job description is rendered with proper formatting. Recruitier processes raw job
descriptions through a markdown formatter that structures the content for readability:

* **Headings** are properly formatted for section separation
* **Bullet lists** are rendered cleanly for requirements and responsibilities
* **Bold and italic text** preserves the original formatting emphasis
* **Links** to external resources are preserved and clickable

The description section is the core of the job detail -- this is where you evaluate
whether the role matches your candidate's skills and career goals.

<Tip>
  If a job description appears as unformatted plain text, the markdown formatting may
  still be processing in the background. Recruitier formats descriptions asynchronously.
  Refresh the page after a few moments to see the formatted version.
</Tip>

### Description Storage

Recruitier stores two versions of the job description on the ScrapedJob entity:

| Field                  | Content                                                         |
| ---------------------- | --------------------------------------------------------------- |
| `scraped_description`  | The raw description as extracted from the company's career page |
| `markdown_description` | The AI-formatted version with proper markdown structure         |

The detail page displays the `markdown_description` when available, falling back to the
`scraped_description` if formatting has not yet been applied. Both versions preserve the
original content -- Recruitier only reformats, never changes the substance of a description.

## Company Information

The company section provides context about the hiring organization:

| Field                | Description                                                     |
| -------------------- | --------------------------------------------------------------- |
| **Company Name**     | Official company name with a favicon (if available)             |
| **LinkedIn Profile** | Direct link to the company's LinkedIn page for further research |
| **Website**          | Link to the company's website                                   |
| **Employee Count**   | Number of employees, sourced from LinkedIn or public records    |
| **Industry**         | The company's primary industry classification                   |

This information is proxied through the Job entity from the linked Company and
GlobalCompany records. The `company_name`, `company_linkedin_url`, and `employee_count`
fields are available directly on the Job entity via property decorators.

<Info>
  Company information is enriched from Recruitier's global company database, which tracks
  thousands of Dutch companies. If a company is not yet in the database, basic information
  from the job listing is displayed, and the record is enriched over time as more data
  becomes available.
</Info>

## Contact Details

Each job may have one or more contact details extracted from various sources. The contact
section shows:

* **Contact person name** -- The name of the relevant contact, when identified
* **Email addresses** -- With verification scores indicating confidence in deliverability
* **Phone numbers** -- Direct lines when found in job descriptions
* **LinkedIn profiles** -- Links to decision-maker profiles at the company, with rank and
  relevance scoring

Contact details are aggregated from three levels, deduplicated to avoid showing the same
contact multiple times:

1. **Job-level contacts** -- Extracted directly from the job description
2. **Company-level contacts** -- From the company record associated with this listing
3. **GlobalCompany-level contacts** -- From the global company database

Contact details are one of the most valuable parts of the job detail page. For a complete
guide on understanding and using contact information, see
[Contact Information](/jobs/contact-information).

## Status Indicators

Several badges and indicators communicate the job's current state:

### Expired Badge

When Recruitier detects that a job listing is no longer available on the company's career
page, it shows an **Expired** badge along with the `expired_at` timestamp recording when
the expiration was detected.

<Warning>
  Expired jobs may have been filled or withdrawn. While the job detail remains available
  for reference, avoid reaching out about expired listings unless you have a specific
  reason to believe the role is still open.
</Warning>

### New Badge

Jobs that were recently added to your search results through monitoring appear with a
**New** badge (`is_new = true`). This badge is cleared when you view the search detail
page, indicating that you have seen the new additions.

### Via Agency Badge

If the job listing was posted by or through a recruitment agency (rather than the hiring
company directly), a **Via Agency** badge appears (`via_agency = true`). This helps you
distinguish between direct employer listings and agency-mediated positions.

<Note>
  Jobs posted via agencies require a different outreach strategy. The hiring company may
  have an exclusive arrangement with the listing agency, making direct outreach less
  effective or potentially causing friction.
</Note>

### Acquisition Not Wanted

Some Dutch job listings include a "geen acquisitie" (no acquisition) notice, indicating
that the company does not want to be contacted by recruitment agencies. Recruitier's
scraper detects this signal using the `acquisition_not_wanted` flag on the ScrapedJob
entity and displays it as a warning indicator.

<Warning>
  When a job is marked with "acquisition not wanted," the company has explicitly stated
  they do not wish to be contacted by recruiters. Respect this request -- contacting them
  anyway may damage your professional reputation. This flag is detected by scanning the
  job description for phrases like "geen acquisitie," "no recruitment agencies," and
  similar variations.
</Warning>

## Tags and Notes

The detail page shows all tags applied to the job and provides access to internal notes:

### Tags

Tags appear as color-coded chips on the job detail page. You can:

* View all applied tags
* Add new tags
* Remove existing tags
* See expiration dates for time-based tags (displayed as a countdown)

### Internal Notes

Internal notes are shared with your agency team. They appear in a notes section on the
detail page, each attributed to the team member who wrote it. Notes are useful for:

* Sharing observations about the job fit
* Logging communication with the company
* Recording candidate feedback about the position
* Noting follow-up actions needed

<Tip>
  Use internal notes to create a communication log for each job. When multiple team
  members work the same pipeline, notes prevent duplicate outreach and ensure everyone
  has context on what has been discussed with the company.
</Tip>

## Outreach Integration

From the job detail page, you can initiate outreach directly:

* **Auto-generated messages** -- For jobs with discovered contacts, Recruitier can
  generate a personalized outreach message using your tone of voice settings
* **Manual compose** -- Open the message composer to write a custom message
* **Outreach flow** -- Start a multi-step outreach sequence targeting the contact
  associated with this job

The outreach section shows the current outreach status if a flow has been started:
which steps are completed, which are pending, and what the next action is.

## Related Jobs

When viewing a job from a specific company, the detail page may show other active jobs
from the same company. This helps you identify additional opportunities at organizations
you are already evaluating, without running a separate search.

## Navigation

From the job detail page, you can navigate to:

* **The parent search** -- Click the search name in the breadcrumb to return to the
  search results
* **The company profile** -- Click the company name to view the full company detail page
  in Client Management
* **The original listing** -- Click the external link icon to open the job on the
  company's career page in a new tab (uses the `url` field from ScrapedJob)

## Advanced

### Job Entity Property Proxying

The Job entity does not store most of the job content directly. Instead, it proxies
fields from the ScrapedJob via `@property` decorators. This architecture means:

**Fields proxied from ScrapedJob:**

* `title`, `url`, `location`
* `scraped_description`, `markdown_description`
* `experience_level`, `job_type`, `flexibility`
* `when` (recency category), `list_date`
* `num_applicants`, `requirements_summary`
* `salary_min`, `salary_max`
* `acquisition_not_wanted`, `is_active`, `is_expired`

**Fields proxied from Company/GlobalCompany:**

* `company_name`, `company_linkedin_url`, `employee_count`

**Fields stored directly on Job:**

* `match_score`, `match_type`
* `favorited`, `deleted`, `is_new`
* `last_viewed_at`, `via_agency`, `source_keywords`

This proxy pattern ensures that when the underlying ScrapedJob is updated (e.g., the
description is reformatted, the listing expires, or new contact info is added), all
Job records linked to that ScrapedJob automatically reflect the change.

### Posting Date Source Hierarchy

The `list_date` field on ScrapedJob comes from the most reliable available source.
Recruitier checks sources in the following order of reliability:

| Priority | Source         | Description                                      |
| -------- | -------------- | ------------------------------------------------ |
| 1        | `jsonld`       | JSON-LD structured data embedded in the page     |
| 2        | `llm`          | LLM-extracted date from the job description text |
| 3        | `html_meta`    | HTML meta tags (e.g., `datePublished`)           |
| 4        | `visible_text` | Date visible on the page (parsed from text)      |
| 5        | `url_pattern`  | Date encoded in the URL path                     |
| 6        | `sitemap`      | Date from the website's sitemap.xml              |
| 7        | `first_seen`   | The date Recruitier first discovered the listing |

The source type is tracked alongside the date so the system knows how reliable the
posting date is. JSON-LD dates are the most accurate; first-seen dates are the least
(they reflect when Recruitier found the listing, not when it was actually posted).

### Contact Information Aggregation

The contact details shown on the job detail page are aggregated from three levels:

1. **Job contacts** -- Extracted from the job description using AI parsing. These are
   stored in the ScrapedJob's `contact_information` JSONB field.
2. **Company contacts** -- From the Company record linked to this job.
3. **GlobalCompany contacts** -- From the global company database.

The aggregation process deduplicates contacts across all three levels, so you never see
the same person listed twice. Deduplication is based on email address, phone number, or
LinkedIn profile URL matching.

Each contact type (EMAIL, TEL, LINKEDIN\_CONTACT\_PERSON) has its own set of quality
indicators. See [Contact Information](/jobs/contact-information) for the full details.

### Power-User Tips

<Accordion title="Check the date source for timing decisions">
  When deciding whether a job is worth pursuing based on its posting date, consider the
  date source. A date from JSON-LD structured data is highly reliable. A "first\_seen"
  date only tells you when Recruitier found the listing -- the actual posting date could
  be days or weeks earlier. For time-sensitive outreach, prioritize jobs with reliable
  date sources.
</Accordion>

<Accordion title="Use the original listing link for verification">
  Before reaching out about a job, open the original listing on the company's career page
  using the external link. This serves two purposes: (1) verify the listing is still live
  (Recruitier's expiration check has a delay), and (2) see the listing in its original
  context, which may include additional details not captured by the scraper.
</Accordion>

<Accordion title="Cross-reference company info with LinkedIn">
  The company information shown on the job detail page is enriched from Recruitier's
  database, but the LinkedIn profile link gives you direct access to the most current
  company data. Check the LinkedIn profile for recent posts, employee growth trends,
  and mutual connections that could warm up your outreach.
</Accordion>

### Business Rules

* **Description immutability**: The `scraped_description` is never modified after initial
  extraction. The `markdown_description` can be regenerated by the AI formatter but always
  preserves the original content's substance.
* **Expiration cascade**: When a ScrapedJob's `is_expired` flag is set, all Job records
  linked to that ScrapedJob automatically reflect the expiration through the proxy
  property.
* **Contact enrichment is incremental**: New contact information can be added to a
  ScrapedJob or its linked Company/GlobalCompany at any time. When you revisit a job
  detail page, you may see new contacts that were not available during your initial review.

## Related

* [Contact Information](/jobs/contact-information) -- Full guide to contacts and outreach
* [Saving & Managing Jobs](/jobs/saving-and-managing) -- Managing your job collection
* [Active Jobs](/jobs/active-jobs) -- Understanding active vs. expired status
* [Tagging Jobs](/jobs/tagging-jobs) -- Organizing jobs with tags
