Data Types
This page documents all enum values, object structures, and special values used in the Jobven API.
Industries
Filter and classify jobs by industry category. Use the Value column in API queries.
| Value | Display Name |
|---|---|
technology_software | Technology / Software |
healthcare_medical | Healthcare / Medical |
finance_banking | Finance / Banking |
education | Education |
retail_ecommerce | Retail / E-commerce |
manufacturing | Manufacturing |
consulting_professional | Consulting / Professional Services |
marketing_advertising | Marketing / Advertising |
government_public | Government / Public Sector |
energy_utilities | Energy / Utilities |
transportation_logistics | Transportation / Logistics |
real_estate_construction | Real Estate / Construction |
hospitality_food | Hospitality / Food Service |
media_entertainment | Media / Entertainment |
nonprofit_ngo | Non-profit / NGO |
other | Other |
technology_software, not technology software.Remote Types
Work arrangement classification for job positions.
| Value | Description |
|---|---|
onsite | Work performed entirely at employer's physical location |
remote | Fully remote position, work from anywhere |
hybrid | Mix of remote and on-site work (e.g., 2-3 days in office) |
flexible | Employee chooses their work arrangement |
Experience Levels
Seniority classification for job positions.
| Value | Description | Typical Years |
|---|---|---|
entry | Entry-level / Junior | 0-2 years |
mid | Mid-level | 2-5 years |
senior | Senior | 5-8 years |
lead | Lead / Staff / Principal | 8-12 years |
executive | Executive / Director / VP+ | 12+ years |
Employment Types
Classification of employment arrangement.
| Value | Description |
|---|---|
full_time | Full-time permanent position (typically 40 hours/week) |
part_time | Part-time position (fewer than 40 hours/week) |
contract | Fixed-term contract or freelance engagement |
internship | Internship program (paid or unpaid) |
seasonal | Seasonal or holiday-specific work |
volunteer | Volunteer position |
temporary | Temporary position with defined end date |
per_diem | Day-rate or as-needed basis |
other | Other employment arrangement |
Job Status
Status values differ between query parameters and response fields.
Query Parameter Values
Use these when filtering jobs with the status query parameter:
| Value | Description |
|---|---|
active | Currently accepting applications (default) |
closed | No longer accepting applications |
Response Field Values
Jobs in responses may have these status values:
| Value | Description |
|---|---|
active | Currently accepting applications |
closed | Manually closed by employer |
expired | Automatically expired past expiresAt date |
Education Levels
Required or preferred education qualifications.
| Value | Description |
|---|---|
high_school | High school diploma or equivalent |
associate_degree | Associate's degree (2-year) |
bachelor_degree | Bachelor's degree (4-year) |
master_degree | Master's degree |
doctorate_degree | Doctorate / PhD |
professional_certificate | Professional certification |
vocational_training | Vocational or trade school |
not_specified | No specific requirement stated |
Salary Object
Pay as the posting states it, with its yearly equivalent.
{
"min": 55,
"max": 65,
"currency": "USD",
"period": "hourly",
"annualMin": 114400,
"annualMax": 135200
}
| Field | Type | Description |
|---|---|---|
min | number | Lowest amount, as stated |
max | number | Highest amount, as stated |
currency | string | ISO 4217 code of the currency the posting states, for example USD, EUR, PLN or HUF |
period | string | What the amounts are per (see below) |
annualMin | number | min per year, in the same currency |
annualMax | number | max per year, in the same currency |
annualMin and annualMax are min and max times the period's yearly multiplier: hourly ×2,080, daily ×260, weekly ×52, bi-weekly ×26, monthly ×12, annual ×1. No exchange rate is applied. They are absent when the period has no yearly equivalent. The minSalary and maxSalary filters compare these values; see Filtering jobs.
When the employer's job board publishes the pay range as data, the salary comes from that range. Otherwise it is read from the posting text.
Currency
currency is any ISO 4217 code: the currency the posting states, never a conversion. A Polish posting paid in złoty has PLN, a Hungarian one in forint HUF. currency is null when the posting gives an amount without one.
Salary Periods
| Value | Description |
|---|---|
annual | Annual salary |
hourly | Hourly rate |
monthly | Monthly rate |
weekly | Weekly rate |
bi-weekly | Every two weeks |
daily | Daily rate |
These six cover almost every salary. When a posting pays per something else, such as a visit, a session or a one-off payment, period carries that unit as the posting states it (for example visit or one-time). period is null when the posting gives an amount without one.
Skills Object
AI-enriched skill categorization for job requirements.
{
"primarySkills": ["React", "TypeScript", "Node.js"],
"secondarySkills": ["Docker", "AWS", "PostgreSQL"],
"softSkills": ["Communication", "Leadership", "Problem-solving"]
}
| Field | Type | Description |
|---|---|---|
primarySkills | string | Core technical skills required for the role |
secondarySkills | string | Nice-to-have or supplementary technical skills |
softSkills | string | Non-technical skills (communication, teamwork, etc.) |
primary_skills, secondary_skills, soft_skills) until December 15, 2026, and those names are removed after that date. Read primarySkills, secondarySkills and softSkills. See API stability.Skills Filtering
When filtering jobs by skills, the API matches against primary and secondary skills:
GET /v1/public/jobs?skills[]=react&skills[]=typescript
This returns jobs where React OR TypeScript is one of the primary or secondary skills, ignoring case. Soft skills are not matched.
Benefits
Benefits are returned as a string array of lowercase, underscore-separated tokens extracted from job descriptions. The vocabulary is open rather than a fixed enum, so treat unfamiliar tokens as valid, but in practice virtually every value follows the token form — match on exact strings, not on prose.
["health_insurance", "dental_insurance", "paid_time_off_vacation_personal_days", "remote_work_hybrid_work_options", "pensions_401k"]
The most common tokens are:
| Token | Category |
|---|---|
paid_time_off_vacation_personal_days | Time off |
professional_development | Development |
health_insurance | Health & wellness |
flexible_work_hours | Work flexibility |
employee_discounts | Perks |
remote_work_hybrid_work_options | Work flexibility |
dental_insurance | Health & wellness |
pensions_401k | Retirement |
Location Object
Geographic location information for job positions.
{
"streetAddress": "123 Main St",
"addressLocality": "San Francisco",
"addressRegion": "California",
"postalCode": "94105",
"addressCountry": "US",
"workLocation": "hybrid"
}
| Field | Type | Description |
|---|---|---|
streetAddress | string | Street address (often null for privacy) |
addressLocality | string | City name |
addressRegion | string | State, province, or region |
postalCode | string | Postal or ZIP code |
addressCountry | string | Country code (ISO 3166-1 alpha-2). May be absent — see Special Value: XX |
workLocation | string | Work arrangement at this location (onsite, remote, hybrid, flexible) |
workLocation vs remoteType
workLocation(in location object): Work arrangement for a specific office locationremoteType(top-level job field): Overall remote policy for the job
A job may have multiple locations with different workLocation values. The top-level remoteType represents the general policy.
Country Codes
ISO 3166-1 alpha-2 country codes are used for location filtering.
Common Country Codes
| Code | Country |
|---|---|
US | United States |
CA | Canada |
GB | United Kingdom |
AU | Australia |
DE | Germany |
FR | France |
NL | Netherlands |
IE | Ireland |
SG | Singapore |
IN | India |
Special Value: XX
The code XX means the job carries no location information at all — no city, no region, no street address. These are typically "work from anywhere" postings with no geographic restriction.
GET /v1/public/jobs?country=XX&remoteType[]=remote
XX does not by itself mean the job is remote. Check workLocation (or the top-level remoteType) for that.
When addressCountry is absent
A location can have a city but no addressCountry. That means the job has a known location whose country we could not identify with confidence. Usually the posting names a place that exists in several countries, or a small town we cannot place from the listing alone. We leave the country absent rather than guess, because a wrong country is harder to work around than a missing one.
{
"addressLocality": "Springfield",
"workLocation": "onsite"
}
These jobs match no country filter, including country=XX. If you need them, request without a country filter and read addressLocality yourself.
remoteType[]=remote without a country filter. Use country=XX specifically for jobs with no location information at all.Supported Countries
All 249 ISO 3166-1 alpha-2 country codes are accepted, plus the special value XX.
Language Codes
ISO 639-1 two-letter language codes for job language requirements.
Common Language Codes
| Code | Language |
|---|---|
en | English |
fr | French |
es | Spanish |
de | German |
zh | Chinese (Mandarin) |
ja | Japanese |
ko | Korean |
pt | Portuguese |
it | Italian |
nl | Dutch |
All Supported Languages
The API supports 40 language codes:
en, fr, es, de, zh, ja, ko, pt, it, ru, ar, hi, nl, sv, no, da, fi, pl, tr, he, id, th, vi, cs, el, hu, ro, uk, bg, hr, fa, ms, tl, bn, ta, te, ur, gu, kn, ml
Travel Percentage
The travelPercentage field indicates required travel as a percentage (0-100).
| Value | Meaning |
|---|---|
0 | No travel required |
10-25 | Occasional travel |
25-50 | Regular travel |
50-75 | Frequent travel |
75-100 | Extensive travel |
Timestamps
postedAt and expiresAt are Unix timestamps in seconds, returned as JSON
numbers. The postedAfter and postedBefore filters take the same unit.
JavaScript's Date constructor expects milliseconds, so multiply by 1000:
const posted = new Date(job.postedAt * 1000)
Python's datetime.fromtimestamp takes seconds, so no conversion is needed:
from datetime import datetime, timezone
posted = datetime.fromtimestamp(job["postedAt"], tz=timezone.utc)
A value of null means the date is unknown — expiresAt is null for most jobs,
since few postings publish a closing date.
Extracted vs AI-Enriched Fields
Every job starts as the text of an employer's own posting. Some response fields are taken from that text as written; others are produced by AI enrichment, which classifies, normalizes, and where the posting is silent, estimates from context. Knowing which is which tells you how much to trust a value and where to apply your own thresholds.
Taken from the posting
These fields are returned only when the posting states them, and null otherwise:
title,description,applyUrlsalary(min,max,currency,period)postedAt,expiresAthasVisaSponsorship,hasRelocation,requiresTravel,travelPercentage
For hasVisaSponsorship, hasRelocation and requiresTravel, false and null mean different
things: false is a posting that says no ("we are unable to sponsor visas"), and null is one that
does not mention it.
AI-enriched
These fields are classified or normalized by AI, and may be inferred when the posting does not state them outright:
| Field | How it is produced |
|---|---|
summary | Written from the description; not a quote |
skills | Extracted, normalized to canonical names, and sorted into primary, secondary and soft |
benefits | Matched to the standard benefit categories |
experienceLevel | From stated years where given; otherwise inferred from the title and role ("Senior Engineer" is senior, "Cashier" is entry) |
employmentType | From stated terms where given; a permanent salaried role with no other indication is full_time |
minYearsExperience | Usually the minimum the posting states ("3-5 years" gives 3). Where no figure is stated, a small share of jobs carry an estimate from context. Treat as approximate |
industry | Classified from the company and the role |
educationRequirement | Matched to the standard education levels |
inLanguage | Stated language requirements, plus the language the posting is written in |
locations[].addressCountry | Inferred from the city or region when the posting names one without a country |
remoteType | Classified from the posting; flexible when the arrangement is unclear |
For filtering, this means enum fields (experienceLevel, employmentType, industry,
remoteType) are reliable as categories, while numeric enrichment such as minYearsExperience
is best used as a range rather than an exact cut-off.
Handling Null and Optional Fields
Most response fields are optional and may be null or undefined. Only these fields are guaranteed:
Always Present
id- Job UUIDtitle- Job titledescription- Job description (HTML)status- Job statuscompanies- Array with at least one company
Often Null
All other fields may be null depending on available data:
summary,locations,remoteTypeskills,salary,benefitsexperienceLevel,employmentTypeeducationRequirement,industryminYearsExperience,travelPercentagehasVisaSponsorship,hasRelocation,requiresTravelinLanguage,postedAt,expiresAt,applyUrl
Safe Access Pattern
Always check for null values before accessing nested properties:
// JavaScript/TypeScript
const salary = job.salary?.min
? `$${job.salary.min.toLocaleString()}+`
: 'Not specified';
const skills = job.skills?.primarySkills?.join(', ') || 'Not listed';
const location = job.locations?.[0]?.addressLocality || 'Location not specified';
# Python
salary = f"${job['salary']['min']:,}+" if job.get('salary', {}).get('min') else 'Not specified'
skills = ', '.join(job.get('skills', {}).get('primarySkills', [])) or 'Not listed'
locations = job.get('locations', [])
location = locations[0].get('addressLocality', 'Location not specified') if locations else 'Location not specified'