Open Standard · MIT License · v0.1

Open Job Protocol

A machine-first, vendor-neutral JSON standard for job opportunities — designed for employers, agents, and the agentic talent marketplaces of tomorrow. The counterpart to Open Talent Protocol.

Why Open Job Protocol?


Job postings today are unstructured prose optimized for SEO, not for AI agents. schema.org/JobPosting serves Google, not hiring agents. Every ATS, job board, and company career page uses a different format. Critical signals like salary, remote policy, and team composition are buried in paragraphs or missing entirely.

Open Job Protocol (OJP) fixes this. It encodes requirements with hard/soft distinctions agents can filter on, compensation and location as structured fields, and hiring process transparency so candidates know what to expect.

Goal What it means in practice
Machine-first JSON is the canonical format. Rendering to career pages or PDFs is a downstream concern.
Employer-controlled The visibility section lets employers decide what to share publicly vs. after application.
Agent-ready requirements split into must_have and nice_to_have — agents filter on hard constraints, rank on soft ones.
OTP-complementary Fields map directly to Open Talent Protocol for bilateral matching.
Vendor-neutral MIT licensed. No required registry, platform, or ATS.
Interoperable Mappable to schema.org/JobPosting, Google for Jobs, LinkedIn Job Posting API, and HR-XML.

Quick start


Validate a document

The validator CLI checks any JSON file against the schema and prints readable errors.

# Install and build the validator
git clone https://github.com/neogene-ai/open-job-protocol.git
cd open-job-protocol/tools/validator-cli
npm install && npm run build

# Validate one of the example documents
node dist/index.js ../../examples/backend-engineer-senior.json
✓ Valid Open Job Protocol document

Minimal valid document

Only meta, role, organization, requirements.must_have.skills, and offering.location.arrangement are required. Everything else is optional.

{
  "$schema": "https://openjobprotocol.org/schema/v0.1.json",
  "meta": {
    "version": "0.1",
    "job_id": "acme-fe-2026-001",
    "status": "ACTIVE",
    "created_at": "2026-02-21T10:00:00Z",
    "updated_at": "2026-02-21T10:00:00Z"
  },
  "role": {
    "title": "Senior Frontend Engineer",
    "description": "Build and maintain our React-based product...",
    "employment_type": "full_time"
  },
  "organization": {
    "name": "Acme Corp"
  },
  "requirements": {
    "must_have": {
      "skills": [
        { "name": "React" },
        { "name": "TypeScript" }
      ]
    }
  },
  "offering": {
    "location": {
      "arrangement": "hybrid"
    }
  }
}

Schema reference


The full schema is a JSON Schema (draft 2020-12) document at schema/openjob-protocol.schema.json. Below, each section is documented with its fields, types, and intent.

Coverage: The schema covers all 46 fields from the schema.org/JobPosting, Google for Jobs, LinkedIn API, and HR-XML cross-reference model, plus 19 agent-first extensions for a total of 65 distinct fields.

Identifiers and lifecycle metadata for tracking, deduplication, and expiration across ATS platforms and job boards.

PropertyTypeReq.Description
version string yes Must be "0.1". Used by parsers to select the correct validation rules.
job_id string yes Globally unique job identifier (URI, UUID, or requisition ID). Maps to schema.org identifier.
status enum yes Current posting state:
DRAFTACTIVEPAUSED CLOSEDEXPIREDFILLED
created_at date-time yes When the posting was first published. Maps to schema.org datePosted.
updated_at date-time yes Last modification timestamp.
valid_through date-time no Posting expiration date. Maps to schema.org validThrough.
source string no Origin ATS or system (e.g. "lever", "greenhouse", "direct").
source_url uri no Canonical URL of the posting. Maps to schema.org url.
locale string no BCP 47 language tag. Default: "en".

The substantive content of the job posting — what the role is and what it involves.

PropertyTypeReq.Description
titlestringyesJob title. Maps to schema.org title.
descriptionstringyesFull job description (markdown). Maps to schema.org description.
role_summarystringno1–3 sentence agent-optimized summary for quick screening.
functionstringnoStandardized function (e.g. "Engineering", "Sales"). Maps to schema.org occupationalCategory.
seniorityenumno
internjuniormid seniorstaffprincipal leaddirectorvpc_level
employment_typeenumyes
full_timepart_timecontract freelanceinternshiptemporary
Maps to schema.org employmentType.
total_openingsintegernoNumber of positions. Maps to schema.org totalJobOpenings.
responsibilitiesstring[]noKey responsibilities (≤7 items recommended). Maps to schema.org responsibilities.
work_hoursstringnoWorking hours description. Maps to schema.org workHours.
job_start_datedatenoExpected start date. Maps to schema.org jobStartDate.
immediate_startbooleannoPosition available immediately. Maps to schema.org jobImmediateStart.

The hiring entity. Only name is required within this section.

PropertyTypeReq.Description
namestringyesCompany name. Maps to schema.org hiringOrganization.name.
urlurinoCompany website.
logo_urlurinoCompany logo image URL.
industrystringnoPrimary industry (NAICS code or free-text). Maps to schema.org industry.
sizeenumno
startupscale_upmid_marketenterprise
departmentstringnoHiring department or division. Maps to schema.org employmentUnit.
foundedintegernoYear founded.
headquartersstringnoHQ location.

Split into must_have (hard constraints agents MUST filter on) and nice_to_have (soft preferences agents SHOULD rank on). This distinction is the key differentiator from schema.org and existing standards.

Design note: An OJP-compliant agent must not present a candidate who fails any must_have constraint. This is a hard rule, not a hint.

must_have

PropertyTypeReq.Description
skillsskill[]yesRequired skills. Each: name (required), min_years, taxonomy ("esco" | "onet"), taxonomy_id.
experience_yearsobjectnomin and optional max. Maps to schema.org experienceRequirements.
credentialscredential[]noRequired degrees. Each: type, field, level. Maps to schema.org educationRequirements.
certificationsstring[]noRequired professional certifications (e.g. "PMP", "AWS CCP").
languageslang[]no Each: language (BCP 47), proficiency:
basicconversationalprofessionalnative
legal.work_authorizationstring[]noISO country/region codes. Maps to schema.org eligibilityToWorkRequirement.
legal.security_clearancestringnoClearance level required. Maps to schema.org securityClearanceRequirement.
legal.physical_requirementsstring[]noPhysical demands. Maps to schema.org physicalRequirement.

nice_to_have

PropertyTypeReq.Description
skillsskill[]noPreferred additional skills (same shape as must_have skills).
experience_yearsobjectnopreferred years of experience.
credentialscredential[]noPreferred qualifications. Maps to schema.org qualifications.
experience_in_place_of_educationbooleannoWhether experience can substitute for a degree. Maps to schema.org experienceInPlaceOfEducation.
preferred_qualificationsstring[]noFreeform preferred qualifications.

What the employer provides: compensation, location, benefits, and growth opportunities. At minimum, location.arrangement is required.

offering.compensation

PropertyTypeReq.Description
salaryobjectnomin, max, currency (ISO 4217), period (hourly | daily | weekly | monthly | annual). Maps to schema.org baseSalary.
additional_compensationarrayno Each: type and description. Types:
bonuscommissionequity tipssigning_bonus
Maps to schema.org incentiveCompensation.
transparencyenumno
publicon_requestafter_interview

offering.location

PropertyTypeReq.Description
arrangementenumyes
remotehybridonsite
Maps to schema.org jobLocationType.
primary_locationstringnoPrimary work location. Maps to schema.org jobLocation.
alternate_locationsstring[]noAdditional office locations.
remote_regionsstring[]noEligible remote regions (ISO codes). Maps to schema.org applicantLocationRequirements.
relocation_supportbooleannoWhether relocation assistance is offered.
visa_sponsorshipbooleannoWhether visa sponsorship is available.

offering.benefits

PropertyTypeReq.Description
benefitsbenefit[]no Each: category and detail. Categories:
healthretirementdevelopment flexibilityfamilyfinancialother
Maps to schema.org jobBenefits.

offering.growth

PropertyTypeReq.Description
career_pathstringnoCareer progression description.
mentorshipbooleannoMentorship availability.
promotion_cadencestringnoReview/promotion cycle.

Team composition and context. No equivalent in schema.org — this is a key OJP differentiator for culture matching.

PropertyTypeReq.Description
namestringnoTeam or squad name.
sizeintegernoCurrent team size.
reports_tostringnoHiring manager title.
tech_stackstring[]noTeam's technology stack.
methodologystringnoWork methodology (e.g. "scrum", "kanban").
descriptionstringnoTeam mission and purpose.

Hiring process transparency — stages, timeline, and application method. Candidates and agents can use this to set expectations.

PropertyTypeReq.Description
stagesstage[]noEach: name, duration_minutes, type ("async" | "call" | "video" | "onsite" | "take_home").
total_duration_daysintegernoTarget time-to-offer in days.
decision_timelinestringnoWhen candidates hear back after final round.
application_urlurinoWhere to apply. Maps to schema.org url.
direct_applybooleannoWhether the URL enables direct application. Maps to schema.org directApply.
accepts_otp_profilebooleannoWhether OTP profiles are accepted as applications.
ai_screeningbooleannoTransparency: is AI used in candidate screening?

Culture signals for work-style and values matching.

PropertyTypeReq.Description
valuesstring[]noCore company values.
work_stylestring[]noWork style descriptors (e.g. "async-first", "low-meeting").
special_commitmentsstring[]noSocial/environmental commitments. Maps to schema.org specialCommitments.
dei_statement_urlurinoDEI statement link.
eeo_statementstringnoEqual employment opportunity statement.
diversity_statementstringnoDiversity commitment text.
employer_overviewstringnoBrief employer branding text. Maps to schema.org employerOverview.

Privacy controls governing what information is publicly visible versus restricted to specific stages of the hiring process.

PropertyTypeReq.Description
salaryenumno
publicon_requestafter_interview
team_detailsenumno
publicafter_application
process_stagesenumno
publicafter_application
hiring_managerenumno
publicafter_applicationafter_interview
"visibility": {
  "salary": "public",
  "team_details": "public",
  "process_stages": "public",
  "hiring_manager": "after_application"
}

A free extension object for domain-specific or proprietary fields. Use namespaced keys to avoid collisions with future spec additions.

"extensions": {
  "jobgrow:match_score": 87,
  "myats:requisition_id": "REQ-2026-0421"
}

Adding data to extensions never breaks a conforming parser. Removing extensions never breaks core functionality.

OTP ↔ OJP bilateral matching


The killer feature: symmetric matching between Open Talent Protocol candidate profiles and OJP job listings. An agent with both documents can compute a bilateral match score without any natural language processing.

OTP (Candidate)OJP (Job)Match typeLogic
skills[]requirements.must_have.skills[]hard filterSkill name match + min_years ≤ candidate years
skills[]requirements.nice_to_have.skills[]soft rankBonus score for matching preferred skills
credentials[]requirements.must_have.credentials[]hard filterCredential type + level match
work_history[].durationrequirements.must_have.experience_years.minhard filterSum of durations ≥ min
languages[]requirements.must_have.languages[]hard filterProficiency ≥ required level
preferences.salaryoffering.compensation.salarybilateralcandidate.min ≤ job.max AND job.min ≤ candidate.max
preferences.locationoffering.locationhard filterArrangement + region compatibility
preferences.work_styleculture.work_stylesoft rankOverlap scoring
preferences.industryorganization.industrysoft rankIndustry preference match

Discovery


Employers host a well-known discovery file so agents can find all active listings without scraping.

# https://acme.com/.well-known/ojp.json

{
  "version": "0.1",
  "organization": "Acme Corp",
  "jobs_url": "https://acme.com/api/jobs.ojp.json",
  "total_active_jobs": 12,
  "updated_at": "2026-02-21T14:00:00Z",
  "accepts_otp_profile": true,
  "contact": "careers@acme.com"
}

Examples


Three complete, schema-conforming documents are included in the repository. They illustrate how requirements, offering, and process are used across different industries and seniority levels.

Tools


Validator CLI

A Node.js CLI that validates any JSON file against the OJP schema and prints readable errors. Source: tools/validator-cli/

cd tools/validator-cli
npm install && npm run build
node dist/index.js path/to/job.json

Agent tools

TypeScript stubs for integrating OJP into MCP-compatible agent frameworks. Source: tools/agent-examples/

Provides composable functions ready to be registered as MCP tools: validateJobPosting, matchCandidateToJob, and introspectJobPosting.

Migration


OJP is designed to be clearly mappable to and from existing job posting formats.

FormatGuideNotes
schema.org/JobPosting migration-schemaorg.md Full field-by-field mapping. OJP is a superset of schema.org’s job properties.
HR-XML migration-hrxml.md Conceptual guide. HR-XML’s PositionOpening maps to OJP without data loss.
LinkedIn Job Posting API migration-linkedin.md Maps LinkedIn’s foundation schema fields to OJP sections.

Governance & neutrality


Open Job Protocol is vendor-neutral. JobGrow and neogene.ai are its initial sponsors, but the spec is designed for broad ecosystem adoption. No single company has veto power over the schema.

OJP is the employer-side counterpart to Open Talent Protocol. Together, they form a complete, open standard for agentic talent marketplaces.

The project is governed by a maintainer council using lazy consensus. See GOVERNANCE.md for the full process.

Licensed under MIT. The spec will always be free to implement.