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
string
default:"all"
Filter matches by source type. Options:
all, direct, scrapedstring
Full-text search across title, description, company name, and skills
enum
Filter by job type. Options:
FULL_TIME, PART_TIME, CONTRACT, FREELANCE, INTERNSHIPstring
Filter by location (partial match, case-insensitive)
enum
Work preference filter (direct jobs only). Options:
REMOTE, ONSITE, HYBRIDenum
Experience level filter (direct jobs only). Options:
ENTRY, JUNIOR, MID, SENIOR, LEAD, MANAGERnumber
Minimum salary filter (direct jobs only)
number
Maximum salary filter (direct jobs only)
string
Scraped job source filter (scraped only). e.g.
LinkedIn, Indeednumber
Minimum match score threshold (0-100)
number
default:"1"
Page number for pagination
number
default:"10"
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
array
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)
Show Direct Job Extra Fields (type: direct)
Show Direct Job Extra Fields (type: direct)
number
Total number of matches available.
number
Current page number.
number
Number of items per page.
number
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
string
Unique job identifier (UUID).
string
Always
"direct" for this source.string
Job title.
string
Full job description.
string
Job requirements.
string
Job responsibilities.
string
Job location.
number
Minimum salary.
number
Maximum salary.
enum
FULL_TIME, PART_TIME, CONTRACT, etc.enum
REMOTE, ONSITE, HYBRID.enum
JUNIOR, MID, SENIOR, etc.string
Publication date (ISO 8601).
object
Company details:
id, name, logoUrl, industry.array
List of required skills with
skillId and name.number
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
string
Unique scraped job identifier (prefixed with
scr_).string
Always
"scraped" for this source.string
Job title.
string
Job description.
string
Job location.
string
Salary as a raw string from the source (not structured).
enum
FULL_TIME, PART_TIME, CONTRACT, etc.string
Company name (no structured company object).
string
Original URL of the job posting.
string
Posting date from the source (ISO 8601).
string
Platform the job was scraped from (e.g.
"LinkedIn").array
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.