CvdsSearchRequest
JSON body for POST /api/v1/cvds/search.
Beyond corpus_id, one cross-field rule applies (EPIC-035 saved-job
references): at least one of position_id / job_id is
required. position_metadata is optional when the reference resolves
to a saved job (its stored content supplies the metadata).
The corpus to search. Mandatory + fail-closed.
Possible values: non-empty
acme-eng-poolYour job identifier. The planner caches a plan per position_id —
reuse the same id across searches for the same role. When it names
a job saved in the Jobs catalog it doubles
as the saved-job reference. Optional when job_id is sent (at
least one of the two is required).
Possible values: non-empty
eng-backend-2026Optional saved-job reference by the platform-assigned job id
(jobs.id). An alternative to position_id — at least one of
the two is required; when both are sent they must resolve to the
same saved job, and job_id wins for resolution. An unresolvable
reference (no inline position_metadata) returns
400 JOB_NOT_FOUND.
Possible values: non-empty and <= 255 characters
6f0d5c2e-1b7a-4c3d-9e8f-2a1b3c4d5e6fposition_metadata object
The position-config object a search plans against (the
position_metadata field on POST /api/v1/cvds/search). This is the
same shape CV DeepMatch consumes as its requirements config — see
the
CvDeepMatchRequirements
schema and the
Position config reference for
the complete field-by-field contract (the 1–5 importance scale, where
each requirement belongs, education ON/OFF, the language-config quirks,
and the cardinality limits).
For an inline, unsaved search the API requires only that
position_metadata be a non-empty object — the inner shape is
the matching/search engine's contract, not validated field-by-field
at this layer. With saveJob: true, however, the blob is decomposed
(job_description key → JD prose, remainder → config) and the config
is strictly validated before anything is saved. A saved job
composes back to exactly this shape: {...config, job_description}.
Typically it carries a name and a requirements block:
{
"name": "Senior Backend Engineer",
"requirements": {
"workExperience": { "from": 5, "to": 10, "importance": 5, "relevant_industries": ["SaaS"], "industries_config": [{ "name": "SaaS", "importance": 5 }] },
"skills": { "importance": 5, "skills_config": { "hard_skills": [{ "name": "Node.js", "importance": 5 }], "requirements": { "minimal_qualifications": true, "preferable_qualifications": true } } }
}
}
The position-config object a search plans against (the
position_metadata field on POST /api/v1/cvds/search). This is the
same shape CV DeepMatch consumes as its requirements config — see
the
CvDeepMatchRequirements
schema and the
Position config reference for
the complete field-by-field contract (the 1–5 importance scale, where
each requirement belongs, education ON/OFF, the language-config quirks,
and the cardinality limits).
For an inline, unsaved search the API requires only that
position_metadata be a non-empty object — the inner shape is
the matching/search engine's contract, not validated field-by-field
at this layer. With saveJob: true, however, the blob is decomposed
(job_description key → JD prose, remainder → config) and the config
is strictly validated before anything is saved. A saved job
composes back to exactly this shape: {...config, job_description}.
Typically it carries a name and a requirements block:
{
"name": "Senior Backend Engineer",
"requirements": {
"workExperience": { "from": 5, "to": 10, "importance": 5, "relevant_industries": ["SaaS"], "industries_config": [{ "name": "SaaS", "importance": 5 }] },
"skills": { "importance": 5, "skills_config": { "hard_skills": [{ "name": "Node.js", "importance": 5 }], "requirements": { "minimal_qualifications": true, "preferable_qualifications": true } } }
}
}
{"name":"Senior Backend Engineer","requirements":{"workExperience":{"from":5,"to":10,"importance":5,"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}],"requirements":{"minimal_qualifications":true,"preferable_qualifications":true}}}}}When true, saves the inline position_metadata as a job in the
Jobs catalog before running: the reserved
job_description key becomes the job's JD prose (required,
non-empty string), the remainder its config (strictly validated
with the save-time position-config contract). On failure the
search returns 400 INVALID_INPUT with per-field detail —
nothing is saved, no run is started. An existing job under the
reference is updated, otherwise a new one is created under
position_id (a job_id alone never creates).
falseInline (unsaved) searches only: true rebuilds the cached
plan for this position (the role's requirements changed); false
reuses the cached plan and re-ranks. For a run whose content
comes from a saved job, this value is ignored — the
platform derives it from the job's updated_at vs the latest
search of that job against the same corpus.
falseHow many best-first candidates to return. Values above the server cap (1000) are clamped.
Possible values: >= 1
10050Optional HTTPS callback URL for completion delivery. Must be
https:// and not resolve to a private / loopback / link-local
address.
https://example.com/cvds/callbackOptional. Replays the existing run for the same key instead of starting a new search.
Possible values: non-empty and <= 255 characters
metadata object
Optional {key:value} correlation data attached to the run.
Optional tags attached to the run for your own correlation/filtering.
["batch-3"]{
"corpus_id": "acme-eng-pool",
"position_id": "eng-backend-2026",
"job_id": "6f0d5c2e-1b7a-4c3d-9e8f-2a1b3c4d5e6f",
"position_metadata": {
"name": "Senior Backend Engineer",
"requirements": {
"workExperience": {
"from": 5,
"to": 10,
"importance": 5,
"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
}
],
"requirements": {
"minimal_qualifications": true,
"preferable_qualifications": true
}
}
}
}
},
"saveJob": false,
"job_updated": false,
"top_n": 50,
"webhook_url": "https://example.com/cvds/callback",
"idempotency_key": "string",
"metadata": {
"batch": "q2",
"team": "emea"
},
"tags": [
"batch-3"
]
}