GetYourJob Matching API
The matching API from GetYourJob — 2 operation(s) for matching.
The matching API from GetYourJob — 2 operation(s) for matching.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/getyourjob-pro:getyourjob-pro-matching-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: MatchingAgent Matching API
description: 'AI-powered candidate-job matching API.
## Features
- **Match candidates against offers** - Get scored matches with detailed analysis
- **Explainable results** - Understand why a match is good or bad
- **Flexible input** - Accept various data formats
## MVP Endpoints
- `POST /v1/match` - Match a candidate against multiple offers
- `GET /v1/health` - Health check
## Coming Soon
- `POST /v1/enrich` - Enrich candidate profiles with external data
- `POST /v1/parse-document` - Parse CV/resume documents'
version: mvp-1.0.0
tags:
- name: matching
paths:
/v1/match-offers:
post:
tags:
- matching
summary: Match one candidate against multiple offers (max 20000)
description: 'Match a single candidate against one or more job offers.
**Fast mode**: Bypasses Pydantic validation on offers for large requests.
Accepts raw JSON body, validates only candidate and options.
**Pagination for large requests (> page_size offers):**
- Layer 1 quick sorting is applied to ALL offers (no LLM)
- Layer 2 deep analysis is run on the first page (page_size offers)
- A `matching_session_id` is returned for fetching additional pages
**Response type:**
- page_size offers: Returns `PaginatedMatchResultResponse` with session ID'
operationId: match_candidate_v1_match_offers_post
responses:
'200':
description: Successful match results
content:
application/json:
schema: {}
'400':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/v1/match-candidates:
post:
tags:
- matching
summary: Match multiple candidates against a single offer (max 5000)
description: 'Match multiple candidates (max 5000) against a single job offer.
**Input modes** (mutually exclusive):
- **Structured**: Provide candidate/offer fields directly (name, skills, experience_years, etc.)
- **Bulk**: Provide raw text/JSON in ''bulk'' field - we extract structured data automatically
**Pagination for large requests (> page_size candidates):**
- The `page_size` option (default 100, range: 5-100) controls pagination threshold
- Layer 1 quick sorting is applied to ALL candidates
- Layer 2 deep analysis is run on the first page (page_size candidates)
- A `matching_session_id` is returned for fetching additional pages
- Use `POST /v1/matching-session` with session_id and page number for more results
**Response type:**
- page_size candidates: Returns `PaginatedMatchResultResponse` with session ID'
operationId: match_candidates_to_offer_v1_match_candidates_post
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/BatchMatchRequest'
required: true
responses:
'200':
description: Successful batch match results
content:
application/json:
schema: {}
'400':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
CandidateMobilityRequest:
properties:
radius_km:
anyOf:
- type: number
- type: 'null'
title: Radius Km
description: Travel radius (km) for on-site / hybrid offers; null = none stated.
onsite_unlimited:
type: boolean
title: Onsite Unlimited
description: On-site / hybrid offers anywhere (« sans limite »).
default: false
remote_reach:
anyOf:
- type: string
enum:
- NATIONAL
- INTERNATIONAL
- type: 'null'
title: Remote Reach
description: 'Remote offers: NATIONAL (own country) or INTERNATIONAL (any country).'
accepted_work_types:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Accepted Work Types
description: Work types accepted (remote / hybrid / onsite).
type: object
title: CandidateMobilityRequest
description: 'The candidate''s declared reach (GetYourJob offerReach.ts): `radius_km` for
on-site / hybrid offers (or `onsite_unlimited`), `remote_reach` NATIONAL |
INTERNATIONAL for remote ones, `accepted_work_types` (remote / hybrid / onsite).
Read by the analysis prose and the Layer 2 distance multiplier. Lenient: an unknown value is dropped, never a 422
that would fail the whole match request.'
CandidateRequest:
properties:
bulk:
anyOf:
- type: string
maxLength: 100000
- type: 'null'
title: Bulk
description: Raw text or JSON blob to extract candidate data from. Can be a CV, LinkedIn profile text, or any unstructured data. Mutually exclusive with other fields - use bulk OR structured fields, not both.
external_id:
anyOf:
- type: string
- type: 'null'
title: External Id
description: Customer's external ID for data reconciliation (any format). Always allowed.
name:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Name
description: Candidate name
headline:
anyOf:
- type: string
maxLength: 300
- type: 'null'
title: Headline
description: Professional headline
summary:
anyOf:
- type: string
maxLength: 5000
- type: 'null'
title: Summary
description: Bio/summary
experience_years:
anyOf:
- type: number
maximum: 50.0
minimum: 0.0
- type: 'null'
title: Experience Years
description: Total years of experience
current_role:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Current Role
description: Current job title
seniority:
anyOf:
- type: string
pattern: ^(junior|mid|senior|lead|principal)$
- type: 'null'
title: Seniority
description: 'Seniority level: junior, mid, senior, lead, or principal'
location:
anyOf:
- type: string
maxLength: 500
- type: 'null'
title: Location
description: Current location
location_lat:
anyOf:
- type: number
maximum: 90.0
minimum: -90.0
- type: 'null'
title: Location Lat
description: Location latitude (decimal degrees)
location_lng:
anyOf:
- type: number
maximum: 180.0
minimum: -180.0
- type: 'null'
title: Location Lng
description: Location longitude (decimal degrees)
willing_to_relocate:
anyOf:
- type: boolean
- type: 'null'
title: Willing To Relocate
description: Whether candidate is willing to relocate
preferred_remote:
anyOf:
- type: string
pattern: ^(remote|hybrid|onsite|flexible)$
- type: 'null'
title: Preferred Remote
description: Candidate's preferred remote work arrangement
salary_expectation_min:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Salary Expectation Min
description: Minimum expected salary (annual, in local currency)
salary_expectation_max:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Salary Expectation Max
description: Maximum expected salary (annual, in local currency)
salary_currency:
anyOf:
- type: string
maxLength: 3
- type: 'null'
title: Salary Currency
description: Currency code for salary (e.g., EUR, USD)
daily_rate_expectation:
anyOf:
- type: integer
minimum: 0.0
- type: 'null'
title: Daily Rate Expectation
description: Expected daily rate (freelance), compared only with a daily-rate offer
skills:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Skills
description: List of all skills (backward compat — use main_skills + secondary_skills when possible)
main_skills:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Main Skills
description: Primary/core technical skills (weighted higher in matching)
secondary_skills:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Secondary Skills
description: Secondary/tool skills (weighted lower in matching)
main_skills_ranked:
anyOf:
- items:
$ref: '#/components/schemas/RankedSkillRequest'
type: array
- type: 'null'
title: Main Skills Ranked
description: Primary skills with their priority order (1 = strongest). When provided, supersedes positional ordering of main_skills.
secondary_skills_rated:
anyOf:
- items:
$ref: '#/components/schemas/RatedSkillRequest'
type: array
- type: 'null'
title: Secondary Skills Rated
description: Secondary skills with self-reported proficiency 0-9. Layer 2 SkillsAgent scales each match by rating/9.
interested_roles:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Interested Roles
description: 'Candidate''s explicit role preferences as GetYourJob RoleType enum values (e.g. [''PRODUCT_OWNER'', ''CONSULTANT'', ''BACKEND'']; also ''PRODUCT_DESIGNER'' for product/UX/UI designers and ''BUSINESS_DEVELOPER'' for IT sales). When set, matches are biased toward these roles: a bonus on on-role offers, a penalty on off-role offers. Free strings: a value this service does not know is accepted and ignored (no bonus, no penalty). Default null preserves prior scoring behavior.'
mobility:
anyOf:
- $ref: '#/components/schemas/CandidateMobilityRequest'
- type: 'null'
description: 'Declared reach: travel radius / unlimited for on-site and hybrid offers, remote reach for remote ones. An offer inside it is never described as needing a relocation, and its Layer 2 distance penalty is halved (Layer 1 unchanged). Allowed next to bulk, like external_id.'
experience:
anyOf:
- items:
$ref: '#/components/schemas/ExperienceRequest'
type: array
- type: 'null'
title: Experience
description: Detailed experience history
education:
anyOf:
- items:
$ref: '#/components/schemas/EducationRequest'
type: array
- type: 'null'
title: Education
description: Education history
type: object
title: CandidateRequest
description: 'Candidate data in a match request.
Supports two mutually exclusive input modes:
1. **Structured mode**: Provide fields directly (name, skills, experience_years, etc.)
2. **Bulk mode**: Provide raw text/JSON in ''bulk'' field - we extract structured data
Cannot mix bulk with other fields. Use one mode or the other.'
examples:
- description: Structured mode - provide fields directly
value:
experience_years: 5
external_id: candidate-12345
headline: Senior Full-Stack Developer
name: John Doe
seniority: senior
skills:
- React
- Node.js
- TypeScript
- PostgreSQL
- AWS
- description: Bulk mode - raw CV text for extraction
value:
bulk: 'John Doe - Senior Full-Stack Developer
5 years experience with React, Node.js, TypeScript...'
external_id: candidate-12345
RankedSkillRequest:
properties:
technology:
type: string
maxLength: 100
title: Technology
description: Skill / technology name
order:
type: integer
maximum: 10.0
minimum: 1.0
title: Order
description: Priority order; 1 is strongest
type: object
required:
- technology
- order
title: RankedSkillRequest
description: A primary/main skill paired with its priority order (1 = strongest).
ExperienceRequest:
properties:
title:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Title
description: Job title
company:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Company
description: Company name
duration_months:
anyOf:
- type: integer
maximum: 600.0
minimum: 0.0
- type: 'null'
title: Duration Months
description: Duration in months
description:
anyOf:
- type: string
maxLength: 5000
- type: 'null'
title: Description
description: Role description
skills_used:
items:
type: string
type: array
title: Skills Used
description: Skills used in this role
type: object
title: ExperienceRequest
description: Experience entry in a candidate request.
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
RatedSkillRequest:
properties:
technology:
type: string
maxLength: 100
title: Technology
description: Skill / technology name
rating:
type: integer
maximum: 9.0
minimum: 0.0
title: Rating
description: Proficiency rating 0-9 (9 = expert)
type: object
required:
- technology
- rating
title: RatedSkillRequest
description: A secondary skill paired with the candidate's self-reported proficiency.
EducationRequest:
properties:
degree:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Degree
description: Degree name
school:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: School
description: School name
year:
anyOf:
- type: integer
maximum: 2100.0
minimum: 1950.0
- type: 'null'
title: Year
description: Graduation year
type: object
title: EducationRequest
description: Education entry in a candidate request.
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
input:
title: Input
ctx:
type: object
title: Context
type: object
required:
- loc
- msg
- type
title: ValidationError
OfferRequest:
properties:
bulk:
anyOf:
- type: string
maxLength: 100000
- type: 'null'
title: Bulk
description: Raw text or JSON blob to extract offer data from. Can be a job posting, job description text, or any unstructured data. Mutually exclusive with other fields - use bulk OR structured fields, not both.
external_id:
anyOf:
- type: string
- type: 'null'
title: External Id
description: Customer's external ID for data reconciliation (any format). Always allowed.
title:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Title
description: Job title
company:
anyOf:
- type: string
maxLength: 200
- type: 'null'
title: Company
description: Company name
description:
anyOf:
- type: string
maxLength: 10000
- type: 'null'
title: Description
description: Full job description
required_skills:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Required Skills
description: Must-have skills
nice_to_have_skills:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Nice To Have Skills
description: Bonus skills
primary_skill:
anyOf:
- type: string
maxLength: 100
- type: 'null'
title: Primary Skill
description: Explicit must-have skill that triggers the primary-skill-missing penalty. When None, the first non-sentinel required skill is used; the role-aware resolver (title/domain) applies only when `e1_primary_resolver_enabled` is on.
seniority_required:
anyOf:
- type: string
pattern: ^(junior|mid|senior|lead|principal)$
- type: 'null'
title: Seniority Required
description: 'Required seniority level: junior, mid, senior, lead, or principal'
experience_years_min:
anyOf:
- type: integer
maximum: 50.0
minimum: 0.0
- type: 'null'
title: Experience Years Min
description: Minimum years of experience
experience_years_max:
anyOf:
- type: integer
maximum: 50.0
minimum: 0.0
- type: 'null'
title: Experience Years Max
description: Maximum years of experience
location:
anyOf:
- type: string
maxLength: 500
- type: 'null'
title: Location
description: Job location
location_lat:
anyOf:
- type: number
maximum: 90.0
minimum: -90.0
- type: 'null'
title: Location Lat
description: Location latitude (decimal degrees)
location_lng:
anyOf:
- type: number
maximum: 180.0
minimum: -180.0
- type: 'null'
title: Location Lng
description: Location longitude (decimal degrees)
remote:
anyOf:
- type: string
pattern: ^(remote|hybrid|onsite)$
- type: 'null'
title: Remote
description: Remote work policy
contract_type:
anyOf:
- type: string
pattern: ^(freelance|cdi|both)$
- type: 'null'
title: Contract Type
description: 'Contract type: freelance, cdi, or both'
salary_min:
anyOf:
- type: number
minimum: 0.0
- type: 'null'
title: Salary Min
description: Minimum salary offered (annual, in local currency)
salary_max:
anyOf:
- type: number
minimum: 0.0
- type: 'null'
title: Salary Max
description: Maximum salary offered (annual, in local currency)
salary_currency:
anyOf:
- type: string
maxLength: 3
- type: 'null'
title: Salary Currency
description: Currency code for salary (e.g., EUR, USD)
salary_period:
anyOf:
- type: string
- type: 'null'
title: Salary Period
description: '''daily'' when the offer pays a day rate (daily_rate_min/max); ''both'' when it states a day rate AND an annual salary (salary_min/max + daily_rate_min/max, compared in the candidate''s unit); annual otherwise'
daily_rate_min:
anyOf:
- type: number
minimum: 0.0
- type: 'null'
title: Daily Rate Min
description: Day rate, low end
daily_rate_max:
anyOf:
- type: number
minimum: 0.0
- type: 'null'
title: Daily Rate Max
description: Day rate, high end
industry:
anyOf:
- type: string
- type: 'null'
title: Industry
description: Industry/domain (e.g., fintech, healthtech, ecommerce)
company_size:
anyOf:
- type: string
pattern: ^(startup|smb|midmarket|enterprise)$
- type: 'null'
title: Company Size
description: Company size category
type: object
title: OfferRequest
description: 'Job offer data in a match request.
Supports two mutually exclusive input modes:
1. **Structured mode**: Provide fields directly (title, required_skills, etc.)
2. **Bulk mode**: Provide raw text/JSON in ''bulk'' field - we extract structured data
Cannot mix bulk with other fields. Use one mode or the other.'
examples:
- description: Structured mode - provide fields directly
value:
company: StartupXYZ
experience_years_max: 7
experience_years_min: 3
external_id: offer-67890
nice_to_have_skills:
- TypeScript
- AWS
required_skills:
- React
- Node.js
seniority_required: senior
title: Full-Stack Developer
- description: Bulk mode - raw job posting for extraction
value:
bulk: 'Full-Stack Developer at StartupXYZ
We''re looking for a senior developer with 3-7 years experience in React and Node.js...'
external_id: offer-67890
ErrorResponse:
properties:
success:
type: boolean
title: Success
description: Always false for errors
default: false
error:
additionalProperties: true
type: object
title: Error
description: Error details
type: object
required:
- error
title: ErrorResponse
description: Error response format.
example:
error:
code: VALIDATION_ERROR
details:
- error: At least one skill is required
field: candidate.skills
message: Invalid request format
success: false
BatchMatchRequest:
properties:
candidates:
items:
$ref: '#/components/schemas/CandidateRequest'
type: array
maxItems: 20000
minItems: 1
title: Candidates
description: Candidates to match against the offer (max 20000, paginated)
offer:
$ref: '#/components/schemas/OfferRequest'
description: Single offer to match candidates against
options:
$ref: '#/components/schemas/MatchingOptions'
description: Match options
type: object
required:
- candidates
- offer
title: BatchMatchRequest
description: 'Request body for the /match-candidates endpoint.
Contains multiple candidates (max 10000) and a single offer to match against.
For requests with > page_size candidates (page_size default 100, range: 5-100):
- Layer 1 quick sorting is applied to all candidates
- Layer 2 deep analysis is run on the first page (page_size candidates)
- A matching_session_id is returned for pagination
- Use POST /v1/matching-session with session_id and page for additional pages
Both candidates and offer support structured mode or bulk mode (mutually exclusive).'
examples:
- description: Structured mode for candidates and offer
value:
candidates:
- experience_years: 5
external_id: candidate-001
headline: Senior Full-Stack Developer
name: John Doe
seniority: senior
skills:
- React
- Node.js
- TypeScript
- experience_years: 3
external_id: candidate-002
name: Jane Smith
seniority: mid
skills:
- Python
- Django
- PostgreSQL
offer:
external_id: offer-123
required_skills:
- React
- Node.js
seniority_required: senior
title: Full-Stack Developer
options:
include_analysis: true
min_score_threshold: 5.0
- description: Bulk mode - raw CVs and job posting
value:
candidates:
- bulk: John Doe - 5 years React, Node.js developer...
external_id: candidate-001
- bulk: Jane Smith - Python backend engineer with 3 years...
external_id: candidate-002
offer:
bulk: We're hiring a senior Full-Stack Developer...
external_id: offer-123
MatchingOptions:
properties:
min_score_threshold:
type: number
maximum: 10.0
minimum: 0.0
title: Min Score Threshold
description: Minimum score to include in results
default: 0.0
max_results:
anyOf:
- type: integer
maximum: 100.0
minimum: 1.0
- type: 'null'
title: Max Results
description: Maximum number of results to return
include_analysis:
type: boolean
title: Include Analysis
description: Include detailed analysis in response
default: true
lang:
anyOf:
- type: string
maxLength: 5
minLength: 2
- type: 'null'
title: Lang
description: Target language code for analysis translation (e.g., 'fr', 'es', 'de', 'zh'). If not specified, analysis is returned in English.
page_size:
type: integer
maximum: 100.0
minimum: 5.0
title: Page Size
description: Number of items per page for pagination (5-100). If total items <= page_size, deep analysis runs on all items directly.
default: 100
location_scope:
anyOf:
- type: string
pattern: ^(local|national|international)$
- type: 'null'
title: Location Scope
description: 'Location scope: ''local'' (within max_distance_km), ''national'' (same country), ''international'' (all)'
max_distance_km:
anyOf:
- type: number
maximum: 1000.0
minimum: 0.0
- type: 'null'
title: Max Distance Km
description: Maximum distance in km for 'local' scope (only used when location_scope='local')
work_type_filter:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Work Type Filter
description: 'Work type filter: list of ''remote'', ''hybrid'', ''onsite''. Empty/None = all types'
role_filter:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Role Filter
description: RoleType enum values to prioritize in scoring (same vocabulary as candidate.interested_roles, incl. PRODUCT_DESIGNER and BUSINESS_DEVELOPER). Offers matching none of the known values get a reduced score. Unknown values are ignored; a filter made only of unknown values applies no penalty.
strict_location:
type: boolean
title: Strict Location
description: If true, hard-reject items outside location constraints instead of soft-penalizing
default: false
contract_type_filter:
anyOf:
- items:
type: string
type: array
- type: 'null'
title: Contract Type Filter
description: 'Contract type filter: list of ''freelance'', ''cdi''. Empty/None = all types'
ab_variant:
anyOf:
- type: string
- type: 'null'
title: Ab Variant
description: 'Experiment variant assigned upstream by GetYourJob (typical values: ''control'', ''treatment''). The server accepts any string for forward-compat and echoes it back in the response metadata. It DOES NOT branch matching behavior on this value — it''s logged for offline analysis only.'
type: object
title: MatchingOptions
description: Shared options for match requests (match-offers and match-candidates).