Skip to main content

CV DeepMatch position config

Every CV DeepMatch submission carries a config object whose requirements block tells the matching engine what a good candidate looks like for this position. The endpoint reference (CvDeepMatchRequirements) lists every field and its type. This guide explains the conventions — the things that aren't obvious from the schema alone and that, if you get them wrong, produce a config that validates but scores badly.

If you only read one thing: every importance is an integer 1–5, and each kind of requirement has exactly one correct home. The rest is detail.

The 1–5 importance scale

importance appears throughout the config — on the work-experience dimension, on each skill, on each industry, on education, and more. It is always an integer from 1 to 5:

ValueMeaning
1Barely matters / nice-to-have
3Moderately important
5Critical to the role

Internally the engine divides the value by 5 to get a 0–1 weight, so 5 → 1.0, 3 → 0.6, 1 → 0.2. That has consequences:

  • 0 is not "off". A 0 produces a zero weight — the dimension silently contributes nothing. To switch education off, use is_enabled: false (below), not importance: 0.
  • Values above 5 overweight. importance: 7 yields a weight of 1.4, which can push scores out of the expected range.
  • Fractions are not the contract. 4.5 happens to arithmetic-work but is not accepted — send whole integers 1–5.

The submit endpoint rejects out-of-range or non-integer importance values with INVALID_INPUT, so you'll catch most mistakes at submit time rather than in a silently-wrong score. Still, choose deliberately: making everything 5 is the same as making everything 1 — nothing is prioritised relative to anything else.

Field routing — what goes where

Each requirement you extract from a job description has exactly one correct place. Putting it elsewhere doesn't error, but it asks the engine the wrong question.

RequirementGoes inNever in
A language (e.g. "English B2")skills.language_skills_confighard_skills, soft_skills, qualifications
Years / months of experienceworkExperience.from / .toqualifications
Degree or field of studyeducation.academicskills or qualifications
A tool / system / method visible on a CVskills_config.hard_skillsqualifications
A behavioural / interpersonal traitskills_config.soft_skillsqualifications
A related job titleworkExperience.relevant_rolesskills
A relevant industryworkExperience.relevant_industries (+ industries_config)skills
An essential broad competency not reducible to a skillminimal_qualificationshard/soft skills (if it is a skill)
A nice-to-have broad competencypreferable_qualificationssame
Employment conditions (contract, onsite/hybrid, shift, location, availability)Not scored — keep it out of the configanywhere scored

Languages are never skills

This is the single most common routing mistake. A language requirement goes only in skills.language_skills_config, and the language names must be plain — no proficiency suffix:

✗ Wrong✓ Correct
"English (B2+)""English"
"English - C1""English"
"Spanish (native)""Spanish"

A proficiency suffix is matched literally against the CV and almost never hits, so language scoring collapses to zero. The submit endpoint rejects language strings containing (), [], or /. Capture the required level in your own explanations block instead.

Two more language gotchas worth knowing:

  • The preferred-languages field is spelled prefered_languages — one r. It's a historical spelling the engine reads exactly; the natural-looking preferred_languages is silently ignored.
  • target_countries are countries where the language is spoken (proof of real-world use), not the job's location. For English you'd list "United States", "United Kingdom", etc. Leave it empty if the JD doesn't value it.

Minimal vs preferable qualifications

minimal_qualifications (essential) and preferable_qualifications (advantageous) are for broad competencies that can't be reduced to a single hard/soft skill label and that describe capability depth. They must be realistically inferable from a CV.

Good: "Demonstrated experience managing high-volume customer interactions with measurable performance outcomes." — describes measurable capability depth.

Bad: "Ability to consistently deliver customer support over the phone while identifying opportunities to recommend products." — that's a task description; express it as soft skills (Customer-Centric Communication, Sales Orientation) plus relevant_roles.

Keep out of qualifications:

  • Employment conditions (contract length, onsite/hybrid, shift, schedule).
  • Willingness / availability statements ("willing to travel", "open to relocation").
  • Time-based requirements — those belong in workExperience.from / .to.
  • Long JD task sentences rewritten as "Ability to…".

If a requirement can reasonably be a hard or soft skill, put it there instead. Use qualifications sparingly — 0 is fine when skills cover the role. Whether qualifications are scored at all is controlled by the required skills_config.requirements toggle block (both minimal_qualifications and preferable_qualifications booleans must be present).

Education ON vs OFF

education is optional at submit — omit it and we auto-fill a safe, disabled default. But if you send the block, send all of it, and disable education by toggling, not by deleting:

  • To disable education scoring: send the full education block with is_enabled: false. The engine reads the block's structure either way; a partial or missing block when education is otherwise expected causes a failure downstream.
  • To enable it: set is_enabled: true and fill in academic / non_academic.

Inside academic, study_status is case-sensitive and must be one of Both, Undergraduate, Graduate. A value like "Graduated" is rejected and, if it slipped through, would short-circuit academic scoring.

Convention for weighting: when a degree isn't genuinely critical to the role (e.g. degree_level: "High School" with no specific field), keep education.importance and academic.importance at 1–2. Reserve 4–5 for roles where the degree truly matters.

Cardinality limits

The engine doesn't crash if you exceed these, but match scores degrade — over-long lists force every candidate to match an impossibly long specification, and scores collapse across the board. The submit endpoint enforces the caps, so over-long lists return INVALID_INPUT:

ListMax itemsWhy
hard_skills5Forces prioritising technical/tool requirements
soft_skills5Forces prioritising behavioural requirements
hard_skills + soft_skills combined10Beyond this the reasoning gets noisy
minimal_qualifications3Only the few real non-skill competencies
preferable_qualifications3Only the most meaningful nice-to-haves
relevant_industries3 (and ≥ 1)More dilutes industry-correlation scoring
industries_config3Must mirror relevant_industries one-for-one

relevant_industries and industries_config must each contain 1–3 entries and mirror each otherindustries_config carries the per-industry weight, relevant_industries is the plain list the reasoning step reads. An empty relevant_industries is rejected.

Minimal valid config

This is the smallest config the submit endpoint accepts — education and language_skills_config are omitted and auto-filled:

{
"name": "Senior Backend Engineer",
"requirements": {
"workExperience": {
"from": 5,
"to": 10,
"importance": 5,
"time_importance": 3,
"transferable_skills": true,
"minimum_job_experience_duration": 4,
"threshold_for_one_exp_relevance": 84,
"relevant_roles": ["Backend Engineer"],
"relevant_companies": [],
"relevant_industries": ["SaaS", "Fintech"],
"industries_config": [
{ "name": "SaaS", "importance": 5 },
{ "name": "Fintech", "importance": 4 }
]
},
"skills": {
"importance": 5,
"skills_config": {
"hard_skills": [
{ "name": "Node.js", "importance": 5 },
{ "name": "TypeScript", "importance": 4 },
{ "name": "PostgreSQL", "importance": 4 }
],
"soft_skills": [
{ "name": "Communication", "importance": 4 }
],
"minimal_qualifications": [],
"preferable_qualifications": [],
"requirements": {
"minimal_qualifications": true,
"preferable_qualifications": true
}
}
}
}
}

Pre-flight checklist

Before submitting, verify:

  • name (or position_name) — non-empty string.
  • workExperience.from ≤ workExperience.to — integer years.
  • workExperience.relevant_industries — 1–3 items, non-empty.
  • workExperience.industries_config — same count, mirrors the above.
  • skills.skills_config.requirements — present, both booleans.
  • Every importance — integer 1–5 (no zeros, fractions, or out-of-range).
  • No language inside hard_skills / soft_skills / qualifications.
  • No proficiency suffix in language names.
  • Cardinality caps respected (industries ≤ 3, hard ≤ 5, soft ≤ 5, hard+soft ≤ 10, qualifications ≤ 3 each).
  • If you send education, send the full block (use is_enabled: false to disable, not omission).

See also