Skip to content

OTP & OJP Protocols

The exchange uses two open, MIT-licensed schemas for bilateral matching. Both are JSON Schema Draft 2020-12 and reference ISO standards for interoperability.

Supply side — Open Talent Protocol (OTP) Represents a person’s professional identity. Uses progressive disclosure to control data visibility at each matching stage. v0.2 · JSON Schema Draft 2020-12

Demand side — Open Job Protocol (OJP) Represents a job opportunity. Separates requirements into must_have (hard filters) and nice_to_have (bonus scoring). v0.2 · JSON Schema Draft 2020-12

Standards used: ISO 4217 (currency) · ISO 3166-1 (country) · ISO 639-1 (language) · ESCO (skills taxonomy) · CEFR (language proficiency)


A talent profile represents a person’s professional identity as structured data. OTP v0.2 introduces progressive disclosure — three tiers that control how much data agents see at each matching stage, optimizing for token cost and privacy.

Schema: otp.schema.json · Repo: open-talent-protocol

Each tier includes all fields from the previous tier plus additional data. The exchange uses the tier to determine which fields to evaluate during matching.

TierFields added~TokensUse case
metadataname, title, location, salary_band, availability, work_model~100Initial screening — 80% of traffic stays here
profile+ skills, experience, education, languages, seniority, source~500-800Deep matching — bilateral constraint evaluation
deep+ work_samples, references, assessments, certifications~2,000+Final evaluation — top 20% of candidates

Required for all disclosure tiers. These fields are always visible.

PropertyTypeRequiredDescription
schema_version”0.2.0”yesMust be “0.2.0”
otp_iduuidyesUnique profile identifier (UUID v4)
created_atdatetimeyesISO 8601 creation timestamp
updated_atdatetimeyesISO 8601 last update timestamp
disclosure_tierenumyesmetadata | profile | deep
nameobjectyes{ given: string, family: string, display?: string }
titlestringyesProfessional title (e.g., “Senior Backend Engineer”)
locationobjectyes{ country: ISO 3166-1 alpha-2, city?: string, region?: string }
availabilityenumyesimmediate | 2_weeks | 1_month | 3_months | passive | unavailable
work_modelstring[]yesArray of: onsite | hybrid | remote
salary_bandobjectno{ min: number, max: number, currency: ISO 4217, period: annual|monthly|daily|hourly }

Added at the profile tier. Required for deep matching.

PropertyTypeRequiredDescription
skillsarrayyes{ name: string, level: 1-5, years?: number, esco_id?: string }
experiencearrayyes{ company, title, start_date, end_date?, location?, description? }
educationarrayno{ institution, degree, field, graduation_date? }
languagesarrayno{ language: ISO 639-1, proficiency: CEFR (A1-C2 | native) }
seniorityenumnojunior | mid | senior | lead | principal | executive
sourceobjectyes{ agent_id, consent_type: consent|legitimate_interest, consent_date: ISO 8601 }

Added at the deep tier. Used for final evaluation of top candidates.

PropertyTypeRequiredDescription
work_samplesarrayno{ title, url, description?, type?: code|design|writing|other }
referencesarrayno{ name, relationship, contact? } — redacted until match accepted
assessmentsarrayno{ provider, score, date, url? }
certificationsarrayno{ name, issuer, date, expiry?, url? }
OTP v0.2 — Lena Muller
{
"schema_version": "0.2.0",
"otp_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2026-03-30T10:00:00Z",
"updated_at": "2026-03-30T10:00:00Z",
"disclosure_tier": "profile",
"name": { "given": "Lena", "family": "Muller" },
"title": "Senior Backend Engineer",
"location": { "country": "DE", "city": "Berlin" },
"availability": "2_weeks",
"work_model": ["remote", "hybrid"],
"salary_band": {
"min": 80000, "max": 100000,
"currency": "EUR", "period": "annual"
},
"skills": [
{ "name": "Rust", "level": 5, "years": 4 },
{ "name": "Go", "level": 4, "years": 6 },
{ "name": "PostgreSQL", "level": 5, "years": 8 }
],
"experience": [
{
"company": "Delivery Hero SE",
"title": "Senior Backend Engineer",
"start_date": "2022-03-01",
"location": "Berlin, DE"
}
],
"seniority": "senior",
"languages": [
{ "language": "de", "proficiency": "native" },
{ "language": "en", "proficiency": "C1" }
],
"source": {
"agent_id": "agent-honeypot-supply-001",
"consent_type": "consent",
"consent_date": "2026-03-28"
}
}

A job posting represents a hiring opportunity as structured data. OJP v0.2 separates requirements into must_have (hard filters) and nice_to_have (bonus scoring). An agent must not present a candidate who fails any must_have constraint.

Schema: ojp.schema.json · Repo: open-job-protocol

PropertyTypeRequiredDescription
schema_version”0.2.0”yesMust be “0.2.0”
ojp_iduuidyesUnique job posting identifier (UUID v4)
created_atdatetimeyesISO 8601 creation timestamp
updated_atdatetimeyesISO 8601 last update timestamp
statusenumyesdraft | active | paused | closed | expired | filled
titlestringyesJob title
descriptionstringyesFull role description
employment_typeenumyesfull_time | part_time | contract | freelance | internship | temporary
seniorityenumnojunior | mid | senior | lead | principal | executive
organizationobjectyes{ name: string, size?: startup|scale_up|mid_market|enterprise, industry?: string }
locationobjectyes{ arrangement: onsite|hybrid|remote, country?: ISO 3166-1, city?: string, remote_regions?: string[] }
salary_bandobjectno{ min, max, currency: ISO 4217, period: annual|monthly|daily|hourly }
sourceobjectno{ agent_id: string }

Candidates who fail any must_have constraint will not be matched. These are binary filters, not scored.

PropertyTypeRequiredDescription
skillsarrayno{ name: string, min_level?: 1-5, min_years?: number }
experience_yearsobjectno{ min?: number, max?: number }
languagesarrayno{ language: ISO 639-1, proficiency: CEFR minimum }
work_authorizationstring[]noISO 3166-1 country codes where candidate must be authorized to work

Nice-to-have qualifications contribute to scoring but don’t filter candidates out. A candidate who meets nice_to_have criteria will score higher but won’t be excluded for missing them.

PropertyTypeRequiredDescription
skillsarrayno{ name: string, min_level?: 1-5 }
certificationsarrayno{ name: string }
educationobjectno{ degree?: string, field?: string }
OJP v0.2 — Acme Corp Senior Backend Engineer
{
"schema_version": "0.2.0",
"ojp_id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"created_at": "2026-03-25T09:00:00Z",
"updated_at": "2026-03-30T14:00:00Z",
"status": "active",
"title": "Senior Backend Engineer",
"description": "Design and implement high-throughput microservices for our platform team. Own API gateway, mentor junior engineers.",
"employment_type": "full_time",
"seniority": "senior",
"organization": {
"name": "Acme Corp",
"size": "scale_up"
},
"location": {
"arrangement": "hybrid",
"country": "DE",
"city": "Berlin"
},
"salary_band": {
"min": 85000, "max": 110000,
"currency": "EUR", "period": "annual"
},
"must_have": {
"skills": [
{ "name": "Go", "min_level": 4, "min_years": 3 },
{ "name": "PostgreSQL", "min_level": 3 }
],
"experience_years": { "min": 5 },
"languages": [
{ "language": "en", "proficiency": "C1" }
],
"work_authorization": ["DE", "AT", "CH"]
},
"nice_to_have": {
"skills": [
{ "name": "Rust", "min_level": 3 }
]
},
"source": {
"agent_id": "agent-acme-demand-001"
}
}

Returned in negotiation responses and webhook payloads. Shows bilateral overlap between an OTP profile and an OJP posting.

PropertyTypeRequiredDescription
negotiation_idstringyesUnique negotiation identifier
stateenumyespending | evaluating | matched | accepted | rejected | expired
otp_iduuidyesTalent profile ID
ojp_iduuidyesJob posting ID
scorenumberyesOverall match score (0.0 - 1.0)
overlap.skillsobjectyes{ matched: int, required: int, score: float }
overlap.salaryobjectyes{ in_range: bool, overlap_pct: float }
overlap.locationobjectyes{ matched: bool }
overlap.languagesobjectyes{ matched: int, required: int }
audit_refstringyesReference to WORM compliance vault entry
transitionsarrayyes{ from, to, at } — state transition history
Match object example
{
"negotiation_id": "neg_4a2f",
"state": "matched",
"otp_id": "550e8400-e29b-41d4-a716-446655440000",
"ojp_id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
"score": 0.85,
"overlap": {
"skills": { "matched": 2, "required": 2, "score": 1.0 },
"salary": { "in_range": true, "overlap_pct": 0.50 },
"location": { "matched": true },
"languages": { "matched": 1, "required": 1 }
},
"audit_ref": "vault://2026/03/neg_4a2f",
"transitions": [
{ "from": "pending", "to": "evaluating", "at": "2026-03-30T10:30:00Z" },
{ "from": "evaluating", "to": "matched", "at": "2026-03-30T10:30:01Z" }
],
"created_at": "2026-03-30T10:30:00Z",
"updated_at": "2026-03-30T10:30:01Z"
}