Get My Matches
curl --request GET \
--url https://api.example.com/api/v1/job-seekers/me/matchesimport requests
url = "https://api.example.com/api/v1/job-seekers/me/matches"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/job-seekers/me/matches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/job-seekers/me/matches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/job-seekers/me/matches"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/job-seekers/me/matches")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/job-seekers/me/matches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"matches": [
{
"id": "<string>",
"type": {},
"title": "<string>",
"description": "<string>",
"location": "<string>",
"jobType": {},
"skills": [
{}
],
"matchScore": 123,
"requirements": {},
"responsibilities": {},
"salaryMin": 123,
"salaryMax": 123,
"workPreference": {},
"experienceLevel": {},
"publishedAt": "<string>",
"applicants": 123,
"company": {},
"salary": {},
"companyName": "<string>",
"sourceUrl": "<string>",
"source": "<string>",
"postedAt": "<string>"
}
],
"total": 123,
"page": 123,
"limit": 123,
"totalPages": 123
}Matching
Get My Matches
Retrieve job matches for the authenticated job seeker with filtering and pagination
GET
/
api
/
v1
/
job-seekers
/
me
/
matches
Get My Matches
curl --request GET \
--url https://api.example.com/api/v1/job-seekers/me/matchesimport requests
url = "https://api.example.com/api/v1/job-seekers/me/matches"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/job-seekers/me/matches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/job-seekers/me/matches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/job-seekers/me/matches"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/job-seekers/me/matches")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/job-seekers/me/matches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"matches": [
{
"id": "<string>",
"type": {},
"title": "<string>",
"description": "<string>",
"location": "<string>",
"jobType": {},
"skills": [
{}
],
"matchScore": 123,
"requirements": {},
"responsibilities": {},
"salaryMin": 123,
"salaryMax": 123,
"workPreference": {},
"experienceLevel": {},
"publishedAt": "<string>",
"applicants": 123,
"company": {},
"salary": {},
"companyName": "<string>",
"sourceUrl": "<string>",
"source": "<string>",
"postedAt": "<string>"
}
],
"total": 123,
"page": 123,
"limit": 123,
"totalPages": 123
}Endpoint
GET /api/v1/job-seekers/me/matches
http://localhost:3000/api/v1
This endpoint requires authentication and Job Seeker role.
Authentication
Include the access token in the Authorization header:Authorization: Bearer YOUR_ACCESS_TOKEN
Query Parameters
Filter matches by source type. Options:
all, direct, scrapedFull-text search across title, description, company name, and skills
Filter by job type. Options:
FULL_TIME, PART_TIME, CONTRACT, FREELANCE, INTERNSHIPFilter by location (partial match, case-insensitive)
Work preference filter (direct jobs only). Options:
REMOTE, ONSITE, HYBRIDExperience level filter (direct jobs only). Options:
ENTRY, JUNIOR, MID, SENIOR, LEAD, MANAGERMinimum salary filter (direct jobs only)
Maximum salary filter (direct jobs only)
Scraped job source filter (scraped only). e.g.
LinkedIn, IndeedMinimum match score threshold (0-100)
Page number for pagination
Number of items per page
Examples
Scraped Matches
# All scraped matches
GET /api/v1/job-seekers/me/matches?type=scraped
# Search keyword
GET /api/v1/job-seekers/me/matches?type=scraped&search=react
# Search + location
GET /api/v1/job-seekers/me/matches?type=scraped&search=python&location=remote
# Job type filter
GET /api/v1/job-seekers/me/matches?type=scraped&jobType=FULL_TIME
# By source website
GET /api/v1/job-seekers/me/matches?type=scraped&source=LinkedIn
# Min score only
GET /api/v1/job-seekers/me/matches?type=scraped&minScore=80
# Combined: search + jobType + minScore
GET /api/v1/job-seekers/me/matches?type=scraped&search=devops&jobType=CONTRACT&minScore=60
# Paginated (page 3, 20 per page)
GET /api/v1/job-seekers/me/matches?type=scraped&page=3&limit=20
Direct Matches
# All direct matches
GET /api/v1/job-seekers/me/matches?type=direct
# Search keyword (title, desc, company, skills)
GET /api/v1/job-seekers/me/matches?type=direct&search=typescript
# Search + location
GET /api/v1/job-seekers/me/matches?type=direct&search=senior&location=new+york
# Job type
GET /api/v1/job-seekers/me/matches?type=direct&jobType=FULL_TIME
# Work preference
GET /api/v1/job-seekers/me/matches?type=direct&workPreference=REMOTE
# Experience level
GET /api/v1/job-seekers/me/matches?type=direct&experienceLevel=SENIOR
# Salary range
GET /api/v1/job-seekers/me/matches?type=direct&salaryMin=80000&salaryMax=150000
# Min score
GET /api/v1/job-seekers/me/matches?type=direct&minScore=90
# Location + jobType + experienceLevel + salary
GET /api/v1/job-seekers/me/matches?type=direct&location=remote&jobType=FULL_TIME&experienceLevel=MID&salaryMin=60000
# Everything combined
GET /api/v1/job-seekers/me/matches?type=direct&search=react&jobType=FULL_TIME&workPreference=REMOTE&experienceLevel=SENIOR&salaryMin=100000&salaryMax=200000&minScore=70&page=1&limit=20
All (merged)
# Search across both sources
GET /api/v1/job-seekers/me/matches?search=python&jobType=FULL_TIME&location=remote&minScore=70
Response
Success Response (200 OK)
{
"success": true,
"data": {
"matches": [
{
"id": "acecb886-2c2d-4e5b-9b5d-49d1e4c5ca7b",
"type": "scraped",
"title": "Junior Full Stack Developer",
"description": "We are looking for a junior full stack developer...",
"location": "Bournemouth, England, United Kingdom",
"salary": null,
"jobType": "FULL_TIME",
"companyName": "Haystack",
"sourceUrl": "https://uk.linkedin.com/jobs/view/junior-full-stack-developer-at-haystack-4407798645",
"source": "LinkedIn",
"postedAt": "2026-05-04T23:43:55.307Z",
"skills": [
{ "skillId": "uuid1", "name": "TypeScript" },
{ "skillId": "uuid2", "name": "React" },
{ "skillId": "uuid3", "name": "Next.js" }
],
"matchScore": 88
},
{
"id": "d86db67d-451b-4189-a49f-7c3bca8c6a99",
"type": "direct",
"title": "Mid-Level Backend Developer",
"description": "We are looking for a motivated backend developer...",
"requirements": null,
"responsibilities": null,
"location": "Alexandria, Egypt",
"salaryMin": 12000,
"salaryMax": 20000,
"jobType": "FULL_TIME",
"workPreference": "REMOTE",
"experienceLevel": "MID",
"company": {
"id": "4ea0d345-f379-4d02-8b89-db49b62abdcc",
"name": "Tech Corp",
"logoUrl": null,
"industry": "Technology"
},
"publishedAt": "2026-04-18T19:16:22.638Z",
"applicants": 0,
"skills": [
{ "skillId": "uuid1", "name": "Node.js" },
{ "skillId": "uuid2", "name": "Docker" }
],
"matchScore": 64
}
],
"total": 2,
"page": 1,
"limit": 10,
"totalPages": 1
},
"message": "Job seeker matches retrieved successfully",
"meta": {
"timestamp": "2026-06-03T18:09:04.738Z",
"path": "/job-seekers/me/matches",
"method": "GET"
}
}
Response Fields
List of job matches sorted by match score (highest first). Each object contains the full job
details with
matchScore as a flat field. The shape differs based on type.Show Common Fields (all types)
Show Common Fields (all types)
Unique job identifier (UUID).
"direct" or "scraped".Job title.
Job description.
Job location.
FULL_TIME, PART_TIME, CONTRACT, etc.List of required skills with
skillId and name.Match score percentage (0–100). Higher scores indicate better compatibility.
Show Direct Job Extra Fields (type: direct)
Show Direct Job Extra Fields (type: direct)
Job requirements.
Job responsibilities.
Minimum salary.
Maximum salary.
REMOTE, ONSITE, HYBRID.JUNIOR, MID, SENIOR, etc.Publication date (ISO 8601).
Number of applicants so far.
Company details:
id, name, logoUrl, industry.Show Scraped Job Extra Fields (type: scraped)
Show Scraped Job Extra Fields (type: scraped)
Total number of matches available.
Current page number.
Number of items per page.
Total number of pages available.
Job Details Response by Source
When fetching details for a specific match, the shape of the
data object differs depending on
the jobSource.Direct Job (jobSource: "DIRECT")
{
"success": true,
"data": {
"id": "6cc9f0af-10c0-4998-b252-fc6c52394759",
"type": "direct",
"title": "Senior Backend Engineer",
"description": "We are looking for an experienced backend engineer...",
"requirements": "5+ years experience in Node.js",
"responsibilities": "Design and implement APIs, mentor junior developers",
"location": "Cairo, Egypt",
"salaryMin": 15000,
"salaryMax": 25000,
"jobType": "FULL_TIME",
"workPreference": "REMOTE",
"experienceLevel": "SENIOR",
"publishedAt": "2026-02-22T14:51:00.000Z",
"company": {
"id": "uuid",
"name": "Tech Corp",
"logoUrl": null,
"industry": "Technology"
},
"source": "direct",
"skills": [
{ "skillId": "uuid1", "name": "Node.js" },
{ "skillId": "uuid2", "name": "TypeScript" },
{ "skillId": "uuid3", "name": "PostgreSQL" }
],
"applicants": 1
}
}
Show Direct Job Fields
Show Direct Job Fields
Unique job identifier (UUID).
Always
"direct" for this source.Job title.
Full job description.
Job requirements.
Job responsibilities.
Job location.
Minimum salary.
Maximum salary.
FULL_TIME, PART_TIME, CONTRACT, etc.REMOTE, ONSITE, HYBRID.JUNIOR, MID, SENIOR, etc.Publication date (ISO 8601).
Company details:
id, name, logoUrl, industry.List of required skills with
skillId and name.Number of applicants so far.
Scraped Job (jobSource: "SCRAPED")
{
"success": true,
"data": {
"id": "scr_1234567890",
"type": "scraped",
"title": "Senior Software Engineer",
"description": "We are looking for a senior software engineer...",
"location": "Remote",
"salary": "$120,000 - $150,000 per year",
"jobType": "FULL_TIME",
"companyName": "Tech Corp",
"sourceUrl": "https://example.com/jobs/123",
"postedAt": "2024-01-15T10:00:00Z",
"source": "LinkedIn",
"skills": [{ "skillId": "uuid1", "name": "TypeScript" }]
}
}
Show Scraped Job Fields
Show Scraped Job Fields
Unique scraped job identifier (prefixed with
scr_).Always
"scraped" for this source.Job title.
Job description.
Job location.
Salary as a raw string from the source (not structured).
FULL_TIME, PART_TIME, CONTRACT, etc.Company name (no structured company object).
Original URL of the job posting.
Posting date from the source (ISO 8601).
Platform the job was scraped from (e.g.
"LinkedIn").List of required skills with
skillId and name.Error Responses
401 Unauthorized
{
"success": false,
"error": {
"message": "Unauthorized",
"statusCode": 401,
"timestamp": "2026-04-23T20:00:00.000Z",
"path": "/job-seekers/me/matches",
"method": "GET",
"details": "Unauthorized"
}
}
403 Forbidden
{
"success": false,
"error": {
"message": "Forbidden resource",
"statusCode": 403,
"timestamp": "2026-04-23T20:00:00.000Z",
"path": "/job-seekers/me/matches",
"method": "GET",
"details": "Forbidden"
}
}
400 Bad Request - Validation Error
{
"success": false,
"error": {
"message": ["type must be one of: all, direct, scraped"],
"statusCode": 400,
"timestamp": "2026-04-23T20:00:00.000Z",
"path": "/job-seekers/me/matches",
"method": "GET",
"details": "Bad Request"
}
}
Notes
Match Score Calculation: Matches are sorted by match score in descending order. Jobs with
higher scores appear first in the results.
Keyword Search: Use the
search parameter to find matches across title, description, company
name, and skills. Direct job searches also include requirements and responsibilities.Direct Job Filters: Parameters
workPreference, experienceLevel, salaryMin, and
salaryMax only apply to direct job matches. Scraped jobs do not have these structured fields.Scraped Source Filter: Use
source=LinkedIn (or Indeed, etc.) with type=scraped to
narrow results to a specific job board.⌘I
