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

# JobPost schema

> The Pydantic data model for a single job posting, and how its fields map to DataFrame columns in the scrape_jobs() output.

Each job returned by `scrape_jobs()` is internally represented as a `JobPost` Pydantic model. When building the output DataFrame, the model fields are flattened and nested objects (such as `location` and `compensation`) are expanded into individual columns.

## JobPost fields

<ResponseField name="id" type="str | None">
  Platform-specific job identifier. May be `None` for some job boards.
</ResponseField>

<ResponseField name="title" type="str" required>
  Job title as listed by the employer.
</ResponseField>

<ResponseField name="company_name" type="str | None">
  Name of the hiring company. Maps to the `company` column in the DataFrame.
</ResponseField>

<ResponseField name="job_url" type="str" required>
  Canonical URL of the job listing on the job board.
</ResponseField>

<ResponseField name="job_url_direct" type="str | None">
  Direct URL to the employer's own job application page, when available. For LinkedIn, this requires `linkedin_fetch_description=True`.
</ResponseField>

<ResponseField name="location" type="Location | None">
  Structured location of the job. Flattened to a display string in the DataFrame (e.g., `"San Francisco, CA, USA"`).

  <Expandable title="Location properties">
    <ResponseField name="country" type="Country | str | None">
      Country of the job, either as a `Country` enum value or a raw string.
    </ResponseField>

    <ResponseField name="city" type="str | None">
      City where the job is located.
    </ResponseField>

    <ResponseField name="state" type="str | None">
      State or province where the job is located.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="description" type="str | None">
  Full job description. The format is controlled by the `description_format` parameter passed to `scrape_jobs()` — one of `"markdown"`, `"html"`, or `"plain"`.
</ResponseField>

<ResponseField name="company_url" type="str | None">
  URL of the company's profile page on the job board.
</ResponseField>

<ResponseField name="company_url_direct" type="str | None">
  URL of the company's own website, when available.
</ResponseField>

<ResponseField name="job_type" type="list[JobType] | None">
  Employment type(s) associated with the posting (e.g., `FULL_TIME`, `CONTRACT`). In the DataFrame, this is serialized as a comma-separated string of the primary values (e.g., `"fulltime"`). See [JobType](/reference/enums#jobtype).
</ResponseField>

<ResponseField name="compensation" type="Compensation | None">
  Salary or compensation data. In the DataFrame, this object is expanded into four separate columns: `interval`, `min_amount`, `max_amount`, and `currency`.

  <Expandable title="Compensation properties">
    <ResponseField name="interval" type="CompensationInterval | None">
      Pay frequency. One of `YEARLY`, `MONTHLY`, `WEEKLY`, `DAILY`, `HOURLY`. See [CompensationInterval](/reference/enums#compensationinterval).
    </ResponseField>

    <ResponseField name="min_amount" type="float | None">
      Minimum salary or pay amount for the stated interval.
    </ResponseField>

    <ResponseField name="max_amount" type="float | None">
      Maximum salary or pay amount for the stated interval.
    </ResponseField>

    <ResponseField name="currency" type="str | None" default="USD">
      ISO 4217 currency code (e.g., `"USD"`, `"GBP"`, `"EUR"`). Defaults to `"USD"`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="date_posted" type="date | None">
  The date the job was posted, as a Python `datetime.date` object.
</ResponseField>

<ResponseField name="emails" type="list[str] | None">
  Email addresses extracted from the job description. In the DataFrame, serialized as a comma-separated string.
</ResponseField>

<ResponseField name="is_remote" type="bool | None">
  Whether the job is remote. `True` for remote, `False` for on-site, `None` if not specified.
</ResponseField>

<ResponseField name="listing_type" type="str | None">
  The type of listing (e.g., organic vs. sponsored), when available from the job board.
</ResponseField>

<ResponseField name="job_level" type="str | None">
  Seniority or experience level (e.g., `"Entry level"`, `"Mid-Senior level"`). **LinkedIn-specific.**
</ResponseField>

<ResponseField name="company_industry" type="str | None">
  The industry the company operates in. Available from **LinkedIn and Indeed**.
</ResponseField>

<ResponseField name="company_addresses" type="str | None">
  Physical address(es) of the company. **Indeed-specific.**
</ResponseField>

<ResponseField name="company_num_employees" type="str | None">
  Company headcount range as a string (e.g., `"1001-5000 employees"`). **Indeed-specific.**
</ResponseField>

<ResponseField name="company_revenue" type="str | None">
  Company annual revenue as a string (e.g., `"$1B to $5B"`). **Indeed-specific.**
</ResponseField>

<ResponseField name="company_description" type="str | None">
  Short description of the company from its job board profile. **Indeed-specific.**
</ResponseField>

<ResponseField name="company_logo" type="str | None">
  URL of the company's logo image. **Indeed-specific.**
</ResponseField>

<ResponseField name="banner_photo_url" type="str | None">
  URL of the company's banner photo. **Indeed-specific.**
</ResponseField>

<ResponseField name="job_function" type="str | None">
  Functional area of the role (e.g., `"Engineering"`, `"Product Management"`). **LinkedIn-specific.**
</ResponseField>

<ResponseField name="skills" type="list[str] | None">
  Skills and technologies listed in the posting. In the DataFrame, serialized as a comma-separated string. **Naukri-specific.**
</ResponseField>

<ResponseField name="experience_range" type="str | None">
  Required years of experience as a range string (e.g., `"2-5 Yrs"`). **Naukri-specific.**
</ResponseField>

<ResponseField name="company_rating" type="float | None">
  Aggregate company rating from AmbitionBox. **Naukri-specific.**
</ResponseField>

<ResponseField name="company_reviews_count" type="int | None">
  Number of company reviews on AmbitionBox. **Naukri-specific.**
</ResponseField>

<ResponseField name="vacancy_count" type="int | None">
  Number of open positions for this listing. **Naukri-specific.**
</ResponseField>

<ResponseField name="work_from_home_type" type="str | None">
  Work arrangement type (e.g., `"Hybrid"`, `"Remote"`, `"Work from Office"`). **Naukri-specific.**
</ResponseField>

## DataFrame column mapping

The table below maps each `JobPost` model field to its corresponding column name in the `scrape_jobs()` output DataFrame.

| Model field               | DataFrame column        | Notes                              |
| ------------------------- | ----------------------- | ---------------------------------- |
| `id`                      | `id`                    |                                    |
| *(added by scraper)*      | `site`                  | Source job board name              |
| `job_url`                 | `job_url`               |                                    |
| `job_url_direct`          | `job_url_direct`        |                                    |
| `title`                   | `title`                 |                                    |
| `company_name`            | `company`               | Renamed in DataFrame               |
| `location`                | `location`              | Flattened to display string        |
| `date_posted`             | `date_posted`           |                                    |
| `job_type`                | `job_type`              | Comma-separated string             |
| *(from compensation)*     | `salary_source`         | `"direct_data"` or `"description"` |
| `compensation.interval`   | `interval`              |                                    |
| `compensation.min_amount` | `min_amount`            |                                    |
| `compensation.max_amount` | `max_amount`            |                                    |
| `compensation.currency`   | `currency`              |                                    |
| `is_remote`               | `is_remote`             |                                    |
| `job_level`               | `job_level`             | LinkedIn only                      |
| `job_function`            | `job_function`          | LinkedIn only                      |
| `listing_type`            | `listing_type`          |                                    |
| `emails`                  | `emails`                | Comma-separated string             |
| `description`             | `description`           |                                    |
| `company_industry`        | `company_industry`      | LinkedIn & Indeed                  |
| `company_url`             | `company_url`           |                                    |
| `company_logo`            | `company_logo`          | Indeed only                        |
| `company_url_direct`      | `company_url_direct`    |                                    |
| `company_addresses`       | `company_addresses`     | Indeed only                        |
| `company_num_employees`   | `company_num_employees` | Indeed only                        |
| `company_revenue`         | `company_revenue`       | Indeed only                        |
| `company_description`     | `company_description`   | Indeed only                        |
| `skills`                  | `skills`                | Naukri only, comma-separated       |
| `experience_range`        | `experience_range`      | Naukri only                        |
| `company_rating`          | `company_rating`        | Naukri only                        |
| `company_reviews_count`   | `company_reviews_count` | Naukri only                        |
| `vacancy_count`           | `vacancy_count`         | Naukri only                        |
| `work_from_home_type`     | `work_from_home_type`   | Naukri only                        |

## Example

```python theme={null}
from jobspy import scrape_jobs

jobs = scrape_jobs(
    site_name=["indeed", "linkedin"],
    search_term="data engineer",
    results_wanted=10,
)

# Access individual columns
print(jobs[["title", "company", "location", "min_amount", "max_amount", "currency"]])

# Filter remote jobs with salary data
remote_with_salary = jobs[
    (jobs["is_remote"] == True) & (jobs["min_amount"].notna())
]
```
