update_candidate_profile
Update a candidate profile
All MCP toolsWrite
Update one person's canonical CandidateProfile by SECTION MERGE — read, modify, write: (1) read the current profile and version with get_candidate_profile; (2) build ONLY the sections you intend to change; (3) call this with those sections and the version you read as expectedVersion. A section you omit keeps its stored value — never send sections you did not change. A present array section replaces that whole array (send [] to clear it, except desiredEmploymentTypes and desiredLocations, which must stay non-empty); null on a scalar section clears it (except sideJobDesire, which cannot return to unset). A person's profile is theirs and service-global, so no organization's field settings gate what they may write about themselves. desiredOccupations takes { id } from search_occupations (name may ride along; it is not stored — reads return it in the person's language), or { name } alone for a word the vocabulary does not know — a row is created for it and its number stored. Tag claims you author with x_matchwire provenance: use `observed` for facts you saw evidence for and `inferred` for conclusions you derived — reserve `provided` for what the candidate stated themselves. An { id } that names no occupation row refuses the whole call (error reason occupation_unknown, details.ids naming the numbers) and nothing is saved — take ids only from search_occupations hits or from what a { name } element returned.
Input schema
{
"type": "object",
"properties": {
"personId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The person to update (persons.id)."
},
"profile": {
"type": "object",
"properties": {
"schemaVersion": {
"description": "Contract version as a SemVer core triple with major locked to 2 (e.g. \"2.0.0\"). Present = replace (a required document key — cannot be cleared). Omit this key to keep the stored value.",
"type": "string",
"pattern": "^4\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$"
},
"basics": {
"description": "Present = replace the whole basics object (a required document key — cannot be cleared). Omit this key to keep the stored value.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Full display name."
},
"label": {
"description": "Short headline, e.g. \"Web Developer\".",
"type": "string"
},
"summary": {
"description": "Short free-text biography.",
"type": "string"
},
"url": {
"description": "Personal website / homepage URL.",
"type": "string",
"format": "uri"
},
"profiles": {
"description": "External profile links (mirrors JSON Resume basics.profiles).",
"type": "array",
"items": {
"type": "object",
"properties": {
"network": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Network / site name, e.g. \"GitHub\"."
},
"username": {
"description": "Username on the network.",
"type": "string"
},
"url": {
"description": "URL to the profile page.",
"type": "string",
"format": "uri"
}
},
"required": [
"network"
],
"additionalProperties": false,
"description": "One external profile link (GitHub, LinkedIn, portfolio, …)."
}
},
"location": {
"description": "Current residence as ISO codes: countryCode (3166-1 alpha-2) and/or region (3166-2), at least one required; when both are present the region must belong to the country. Absent = undisclosed. Finer-grained address data (address/city/postalCode) is deliberately not modeled.",
"type": "object",
"properties": {
"countryCode": {
"description": "Residence country as ISO 3166-1 alpha-2, e.g. \"JP\".",
"type": "string",
"pattern": "^[A-Z]{2}$"
},
"region": {
"description": "Residence subdivision as ISO 3166-2, e.g. \"JP-13\" (Tokyo).",
"type": "string",
"pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"work": {
"description": "Work history, one claim per employment. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Employer / organization name, e.g. \"ACME Corp\"."
},
"position": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Role title, e.g. \"Software Engineer\"."
},
"department": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Department within the organization, e.g. \"Payments Platform Division\"."
},
"team": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Team within the department, e.g. \"Billing Infrastructure Team\"."
},
"startDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Start date as ISO 8601 with optional month/day, e.g. \"2019\", \"2019-04\", or \"2019-04-01\"."
},
"endDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "End date as ISO 8601 with optional month/day; absent while the position is current."
},
"current": {
"description": "Currently-employed declaration: true while the position is ongoing. The write boundary requires a dated entry to carry exactly one of endDate / current: true, so an \"ended\" and an \"ongoing\" entry can never share one stored shape; stored documents that predate the field read back unchanged and self-heal to current: true on their next write.",
"type": "boolean"
},
"summary": {
"description": "Free-text overview of the responsibilities.",
"type": "string"
},
"highlights": {
"description": "Notable accomplishments in this position.",
"type": "array",
"items": {
"type": "string",
"description": "A single accomplishment."
}
},
"employmentType": {
"description": "Employment type: \"FULL_TIME\" (regular employment), \"PART_TIME\", \"CONTRACTOR\" (outsourcing / freelance), \"TEMPORARY\" (fixed-term or dispatch), or \"INTERN\". Same vocabulary as JobPosting.employmentType (schema.org / HR Open Standards aligned). Absent = undisclosed.",
"type": "string",
"enum": [
"FULL_TIME",
"PART_TIME",
"CONTRACTOR",
"TEMPORARY",
"INTERN"
]
},
"workplaceType": {
"description": "Workplace type: how this engagement was worked — \"none\" (on-site), \"hybrid\", or \"full\" (fully remote). Same vocabulary as JobPosting.remote. Absent = undisclosed.",
"type": "string",
"enum": [
"none",
"hybrid",
"full"
]
},
"location": {
"description": "Work location as an ISO 3166-2 subdivision code, e.g. \"JP-13\" — the same format as desiredLocations and JobPosting.jobLocation. Absent = undisclosed.",
"type": "string",
"pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
},
"sideJob": {
"description": "Side-job flag: true when this engagement ran alongside a primary job, false when it was the primary engagement. Orthogonal to employmentType — freelance work as the main job is CONTRACTOR + sideJob false. Absent = undisclosed.",
"type": "boolean"
},
"url": {
"description": "URL of the organization / employer website (standard JSON Resume slot).",
"type": "string",
"format": "uri"
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"name",
"position"
],
"additionalProperties": false,
"description": "One work-history claim (an employment at one organization)."
}
},
"education": {
"description": "Education history, one claim per enrollment. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"institution": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "School / university name, e.g. \"University of Tokyo\"."
},
"area": {
"description": "Field of study, e.g. \"Computer Science\".",
"type": "string"
},
"studyType": {
"description": "Degree or program type, e.g. \"Bachelor\".",
"type": "string"
},
"level": {
"description": "Structured education level on the shared ordered ladder, least to most advanced: \"high_school\", \"associate\" (junior / technical / vocational college, KOSEN), \"bachelor\", \"master\", or \"doctorate\" — the job-side EDUCATION_LEVELS ladder without \"none\". Derived from studyType whenever the wording maps; studyType keeps the raw verbatim wording either way. Anything else is rejected.",
"type": "string",
"enum": [
"high_school",
"associate",
"bachelor",
"master",
"doctorate"
]
},
"startDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Start date as ISO 8601 with optional month/day, e.g. \"2015\", \"2015-04\"."
},
"endDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "End date as ISO 8601 with optional month/day; absent while enrolled."
},
"current": {
"description": "Currently-enrolled declaration: true while the enrollment is ongoing. Same write-boundary rule as work — a dated entry carries exactly one of endDate / current: true; predating stored documents read back unchanged and self-heal on write.",
"type": "boolean"
},
"score": {
"description": "Grade / GPA as free text, e.g. \"3.67/4.0\".",
"type": "string"
},
"courses": {
"description": "Notable courses/subjects taken.",
"type": "array",
"items": {
"type": "string",
"description": "A notable course or subject."
}
},
"url": {
"description": "URL of the institution website (standard JSON Resume slot).",
"type": "string",
"format": "uri"
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"institution"
],
"additionalProperties": false,
"description": "One education-history claim (an enrollment at one institution)."
}
},
"skills": {
"description": "Skill claims, one raw verbatim skill per element. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Raw verbatim skill string exactly as stated (trimmed only): one skill per element, never split on commas or slashes, never normalized away."
},
"proficiency": {
"type": "object",
"properties": {
"scale": {
"type": "string",
"const": "mw7",
"description": "Proficiency scale identifier; only \"mw7\" (matchwire's neutral 7-level responsibility ladder) is defined."
},
"level": {
"type": "integer",
"minimum": 1,
"maximum": 7,
"description": "Integer 1-7 on the mw7 ladder: 1 follow, 2 assist, 3 apply, 4 enable, 5 advise, 6 initiate, 7 set strategy. Values outside 1-7 are rejected."
}
},
"required": [
"scale",
"level"
],
"additionalProperties": false,
"description": "Structured proficiency: { scale: \"mw7\", level: 1-7 }."
},
"keywords": {
"description": "Free-form keywords pertaining to this skill.",
"type": "array",
"items": {
"type": "string",
"description": "Free-form keyword related to this skill."
}
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "A single skill claim with the raw verbatim name and optional structured proficiency."
}
},
"languages": {
"description": "Language abilities on structured scales (CEFR / JLPT). Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"language": {
"type": "string",
"enum": [
"aa",
"ab",
"ae",
"af",
"ak",
"am",
"an",
"ar",
"as",
"av",
"ay",
"az",
"ba",
"be",
"bg",
"bi",
"bm",
"bn",
"bo",
"br",
"bs",
"ca",
"ce",
"ch",
"co",
"cr",
"cs",
"cu",
"cv",
"cy",
"da",
"de",
"dv",
"dz",
"ee",
"el",
"en",
"eo",
"es",
"et",
"eu",
"fa",
"ff",
"fi",
"fj",
"fo",
"fr",
"fy",
"ga",
"gd",
"gl",
"gn",
"gu",
"gv",
"ha",
"he",
"hi",
"ho",
"hr",
"ht",
"hu",
"hy",
"hz",
"ia",
"id",
"ie",
"ig",
"ii",
"ik",
"io",
"is",
"it",
"iu",
"ja",
"jv",
"ka",
"kg",
"ki",
"kj",
"kk",
"kl",
"km",
"kn",
"ko",
"kr",
"ks",
"ku",
"kv",
"kw",
"ky",
"la",
"lb",
"lg",
"li",
"ln",
"lo",
"lt",
"lu",
"lv",
"mg",
"mh",
"mi",
"mk",
"ml",
"mn",
"mr",
"ms",
"mt",
"my",
"na",
"nan",
"nb",
"nd",
"ne",
"ng",
"nl",
"nn",
"no",
"nr",
"nv",
"ny",
"oc",
"oj",
"om",
"or",
"os",
"pa",
"pi",
"pl",
"ps",
"pt",
"qu",
"rm",
"rn",
"ro",
"ru",
"rw",
"sa",
"sc",
"sd",
"se",
"sg",
"si",
"sk",
"sl",
"sm",
"sn",
"so",
"sq",
"sr",
"ss",
"st",
"su",
"sv",
"sw",
"ta",
"te",
"tg",
"th",
"ti",
"tk",
"tl",
"tn",
"to",
"tr",
"ts",
"tt",
"tw",
"ty",
"ug",
"uk",
"ur",
"uz",
"ve",
"vi",
"vo",
"wa",
"wo",
"xh",
"yi",
"yo",
"yue",
"za",
"zh",
"zu"
],
"description": "Language code from the closed vocabulary: ISO 639-1 two-letter codes plus the allowlist \"yue\" (Cantonese) and \"nan\" (Taiwanese Hokkien), e.g. \"ja\", \"en\", \"zh\". Language names, unassigned codes, region-qualified tags (\"zh-TW\"), and uppercase are rejected."
},
"fluency": {
"description": "Common self-assessed fluency tier, least to most proficient: \"basic\" (basic conversation), \"daily\" (daily conversation), \"business\" (business conversation), \"fluent\", or \"native\". Anything else (free text, CEFR grades, JLPT ranks) is rejected — test results belong in certificates.",
"type": "string",
"enum": [
"basic",
"daily",
"business",
"fluent",
"native"
]
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"language"
],
"additionalProperties": false,
"description": "A language ability claim: a language code from the closed vocabulary plus the common self-assessed fluency tier. Framework grades (CEFR) and test ranks (JLPT) are not level keys — a rank is a credential and belongs in certificates (ADR-0174)."
}
},
"certificates": {
"description": "Certification claims. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Certificate name, e.g. \"AWS SAA\" or \"PMP\"."
},
"date": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Date awarded as ISO 8601 with optional month/day."
},
"expiresAt": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Expiration date as ISO 8601 with optional month/day; absent when the certification does not expire or the expiry is unknown."
},
"issuer": {
"description": "Issuing organization, e.g. \"IPA\".",
"type": "string"
},
"credentialId": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Issuer-assigned credential / license number as printed on the credential, e.g. \"AP-2016-10-12345\"."
},
"url": {
"description": "URL to the certificate or issuer page.",
"type": "string",
"format": "uri"
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "One certification claim."
}
},
"awards": {
"description": "Award claims. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Award title, e.g. \"CEO Award\"."
},
"date": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Date awarded as ISO 8601 with optional month/day."
},
"awarder": {
"description": "Who granted the award.",
"type": "string"
},
"summary": {
"description": "What the award was received for.",
"type": "string"
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"title"
],
"additionalProperties": false,
"description": "One award claim."
}
},
"publications": {
"description": "Publication claims (books, articles, papers, talks). Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Publication title, e.g. \"Scaling Payment Infrastructure in Practice\"."
},
"publisher": {
"description": "Publisher / venue, e.g. \"O'Reilly\".",
"type": "string"
},
"releaseDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Release date as ISO 8601 with optional month/day."
},
"url": {
"description": "URL to the publication.",
"type": "string",
"format": "uri"
},
"summary": {
"description": "Short free-text description of the publication.",
"type": "string"
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "One publication claim (an authored book, article, paper, or talk write-up)."
}
},
"projects": {
"description": "Project claims (OSS, side projects, notable engagements). Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Project name, e.g. \"matchwire\" or \"internal auth platform renewal\"."
},
"description": {
"description": "Short free-text summary of the project.",
"type": "string"
},
"highlights": {
"description": "Notable accomplishments on this project.",
"type": "array",
"items": {
"type": "string",
"description": "A single accomplishment."
}
},
"keywords": {
"description": "Keywords (technologies, themes) pertaining to this project.",
"type": "array",
"items": {
"type": "string",
"description": "A technology or theme related to this project."
}
},
"startDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Start date as ISO 8601 with optional month/day, e.g. \"2023\", \"2023-04\"."
},
"endDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "End date as ISO 8601 with optional month/day; absent while the project is ongoing."
},
"url": {
"description": "URL to the project (repository, product page, …).",
"type": "string",
"format": "uri"
},
"roles": {
"description": "Roles held on this project, e.g. [\"Maintainer\", \"Team Lead\"].",
"type": "array",
"items": {
"type": "string",
"description": "A role held on this project."
}
},
"entity": {
"description": "Entity the project belongs to, e.g. an employer or community name.",
"type": "string"
},
"type": {
"description": "Free-text project type, e.g. \"application\", \"library\", \"volunteering\".",
"type": "string"
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "One project claim (OSS, side project, or notable engagement)."
}
},
"volunteer": {
"description": "Volunteer-work claims, one per engagement. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"organization": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Organization name, e.g. \"Code for Japan\"."
},
"position": {
"description": "Role title, e.g. \"Organizer\".",
"type": "string"
},
"url": {
"description": "URL of the organization website.",
"type": "string",
"format": "uri"
},
"startDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Start date as ISO 8601 with optional month/day, e.g. \"2021\", \"2021-04\"."
},
"endDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "End date as ISO 8601 with optional month/day; absent while the engagement is current."
},
"summary": {
"description": "Free-text overview of the volunteer work.",
"type": "string"
},
"highlights": {
"description": "Notable accomplishments in this engagement.",
"type": "array",
"items": {
"type": "string",
"description": "A single accomplishment."
}
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"organization"
],
"additionalProperties": false,
"description": "One volunteer-work claim (an engagement at one organization)."
}
},
"interests": {
"description": "Interest claims (topics and causes). Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "Interest name, e.g. \"distributed systems\" or \"Generative AI\"."
},
"keywords": {
"description": "Free-form keywords pertaining to this interest.",
"type": "array",
"items": {
"type": "string",
"description": "A free-form keyword related to this interest."
}
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "One interest claim (a topic or cause the candidate cares about)."
}
},
"desiredSalaries": {
"description": "Desired-salary per-currency annual lower-bound rows (compiled currencies: min/max must sit on the currency's step grid). Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"type": "array",
"items": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$",
"description": "ISO 4217 currency code (exactly three uppercase letters). Required — no default."
},
"min": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "Desired annual lower bound in raw currency units (non-negative integer). Required — a row without a lower bound does not exist in the contract."
},
"max": {
"description": "Optional annual upper bound in raw currency units; the posting↔row match never reads it, while the shared internal candidate facet fold reads it as the row's upper bound. Must be >= min when present.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"unit": {
"default": "YEAR",
"description": "Salary period unit; rows are always annual (\"YEAR\").",
"type": "string",
"const": "YEAR"
}
},
"required": [
"currency",
"min"
],
"additionalProperties": false,
"description": "One per-currency desired-salary lower-bound row (annual): matching is strict against postings in this row's currency only — never converted, never compared across currencies."
}
},
"currentSalary": {
"description": "Current annual salary. Present = replace; null = clear the stored value. Omit this key to keep the stored value.",
"anyOf": [
{
"type": "object",
"properties": {
"currency": {
"default": "JPY",
"description": "ISO 4217 currency code (exactly three uppercase letters). Defaults to \"JPY\".",
"type": "string",
"pattern": "^[A-Z]{3}$"
},
"amount": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "Current annual salary as a non-negative integer in `currency`."
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"amount"
],
"additionalProperties": false,
"description": "Current annual salary: a non-negative integer amount in an ISO 4217 currency."
},
{
"type": "null"
}
]
},
"mobility": {
"description": "Mobility on the ordered 3-level vocabulary (\"not_looking\" < \"open_to_move\" < \"actively_looking\"). The side-job values are deprecated here — they belong on sideJobDesire, and the write path normalizes them onto that axis. Present = replace; null = clear the stored value. Omit this key to keep the stored value.",
"anyOf": [
{
"type": "string",
"enum": [
"not_looking",
"open_to_move",
"actively_looking"
]
},
{
"type": "null"
}
]
},
"sideJobDesire": {
"description": "Side-job desire. Present = replace; null is rejected — once set there is no way back to unset (an absent stored value already reads as \"not_open\"). Omit this key to keep the stored value.",
"type": "string",
"enum": [
"not_open",
"open"
]
},
"openToWork": {
"description": "Open-to-work — DERIVED from mobility in the write path; the derived value always wins over what is sent. Present = replace; null = clear the stored value. Omit this key to keep the stored value.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"availability": {
"description": "Availability window. Present = replace; null = clear the stored value. Omit this key to keep the stored value.",
"anyOf": [
{
"type": "object",
"properties": {
"earliestStartDate": {
"type": "string",
"pattern": "^[1-2]\\d{3}(-[0-1]\\d(-[0-3]\\d)?)?$",
"description": "Earliest start date as ISO 8601 with optional month/day, e.g. \"2026-10\" or \"2026-10-01\"."
},
"weeklyHours": {
"description": "Available hours per week as a positive integer.",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"additionalProperties": false,
"description": "Availability window: earliest start date and weekly available hours (both optional)."
},
{
"type": "null"
}
]
},
"desiredLocations": {
"description": "Desired locations: country (ISO 3166-1 alpha-2) and/or region (ISO 3166-2) codes, NON-EMPTY ([] is rejected — the axis has no clear path; absent stored = \"not yet set\", and setting it is one-way). Present = replace the whole stored array. Omit this key to keep the stored value.",
"minItems": 1,
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"pattern": "^[A-Z]{2}$",
"description": "ISO 3166-1 alpha-2 country code: exactly two uppercase letters, e.g. \"JP\". Three-letter codes (\"JPN\"), subdivision codes (\"JP-13\"), country names, and lowercase are rejected."
},
{
"type": "string",
"pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$",
"description": "ISO 3166-2 subdivision code: two uppercase letters, a hyphen, then 1-3 uppercase alphanumerics, e.g. \"JP-13\" (Tokyo). Country-only codes (\"JP\"), place names, and lowercase are rejected."
}
],
"description": "Desired-location entry: a whole country as an ISO 3166-1 alpha-2 code (e.g. \"US\") or one region as an ISO 3166-2 subdivision code (e.g. \"JP-13\"). Names, lowercase, and three-letter codes are rejected."
}
},
"desiredOccupations": {
"description": "Desired occupations: { id } references to occupation rows (a search_occupations hit's id; name may ride along and is not stored — reads return it in the person's language), or { name } alone for a word the vocabulary does not know — a row is created for it and its number stored. Unique by id. Present = replace the whole stored array (send [] to clear the section). Omit this key to keep the stored value.",
"maxItems": 20,
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The occupation's number (an `occupations` row) — the identity predicates count on."
},
"name": {
"description": "The row's display name in the reader's language, added when a read answers (trimmed, non-empty). Optional on a write and never stored — a stored reference carries the number alone.",
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$"
}
},
"required": [
"id"
],
"additionalProperties": false,
"description": "Occupation reference: { id, name? } — the row's number, plus the display name a read adds in the reader's language (a write may carry one; it is not stored)."
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 256,
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "A word the vocabulary does not know, as typed (trimmed, non-empty): the tool creates its occupation row and stores its number."
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "A bare typed word: { name } without a number — becomes a row on save."
}
]
}
},
"desiredOfficeFrequency": {
"description": "Desired office frequency (the accepted range). Present = replace; null = clear the stored value. Omit this key to keep the stored value.",
"anyOf": [
{
"type": "object",
"properties": {
"min": {
"type": "string",
"enum": [
"remote_only",
"office_monthly",
"office_1_2_days",
"office_3_4_days",
"office_daily_remote_ok",
"office_daily"
],
"description": "The most remote-leaning end of the accepted range (inclusive)."
},
"max": {
"type": "string",
"enum": [
"remote_only",
"office_monthly",
"office_1_2_days",
"office_3_4_days",
"office_daily_remote_ok",
"office_daily"
],
"description": "The most office-leaning end of the accepted range (inclusive)."
}
},
"required": [
"min",
"max"
],
"additionalProperties": false,
"description": "Desired office frequency: the accepted CONTIGUOUS range on the ordered 6-level office-frequency scale, given by its two ends — min = most remote-leaning, max = most office-leaning, both inclusive. Absent = no constraint on this axis."
},
{
"type": "null"
}
]
},
"desiredEmploymentTypes": {
"description": "Desired employment types over the shared vocabulary, unique and NON-EMPTY ([] is rejected — the axis has no clear path; \"not limiting\" is spelled by selecting every form). Present = replace the whole stored array. Omit this key to keep the stored value.",
"minItems": 1,
"maxItems": 5,
"type": "array",
"items": {
"type": "string",
"enum": [
"FULL_TIME",
"PART_TIME",
"CONTRACTOR",
"TEMPORARY",
"INTERN"
],
"description": "Employment type (schema.org vocabulary): \"FULL_TIME\", \"PART_TIME\", \"CONTRACTOR\", \"TEMPORARY\", or \"INTERN\". Other values are rejected."
}
}
},
"additionalProperties": false,
"description": "The CandidateProfile sections to change — a partial document. An omitted section keeps its stored value; a present array section replaces wholesale ([] clears, except desiredEmploymentTypes and desiredLocations, which must stay non-empty); null on a scalar/object section clears it (except sideJobDesire, which cannot return to unset). Unknown keys are rejected. A present basics replaces the stored basics and cannot drop a stored name: when the person already has a name, send it back."
},
"expectedVersion": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "The version you loaded (get_candidate_profile.version) — a stale value refuses with a version conflict; re-read and retry."
}
},
"required": [
"personId",
"profile",
"expectedVersion"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}Output schema
{
"type": "object",
"properties": {
"personId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "The newly appended profile version."
}
},
"required": [
"personId",
"version"
],
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false
}