Creates new access and refresh tokens
Request format:
{
"refresh_token": "9ea7b7aa7f7225794..."
}
Returns all users.
Returns user.
Returns current user
Empty body
Creates a user via email and password
Request format:
{
"email": "string",
"username": "string",
"password": "string",
"role" : "ROLE_EMPLOYER" ***(optional parameter, logs in as EMPLOYER)***
}
Logs in / Creates a user via social media
Request format:
{
"id": int,
"media": "string", ***('google' or 'facebook' value only)***
"username": "string",
"role" : "ROLE_EMPLOYER" ***(optional parameter, logs in as EMPLOYER)***
}
Logs in a user via email and password
Request format:
{
"email": "string",
"password": "string",
"role" : "ROLE_EMPLOYER" ***(optional parameter, logs in as EMPLOYER)***
}
Deletes a user (current user will be deleted)
Updates email and password
Request format:
{
"email": "string",
"newPassword": "string",
"password": "string" ***((old password) optional parameter, needed only if user already has email and password)***
}
Updates name and surname
Request format:
{
"name": "string",
"surname": "string" ***(optional parameter)***
}
Connects social media to current user
Request format:
{
"id": int,
"media": "string" ***('google' or 'facebook' value only)***
}
Creates user's avatar
Request format: form-data
"image": file
Sets notifications settings
Request format:
{
"key": "string", ***('website_notifications', 'email_notifications' or 'email_subscription' value only)***
"value": boolean
}
Logs in / Creates a user via telegram. Optional parameter ?role=ROLE_EMPLOYER
Request format:
Redirect user to this route: /login/telegram
After, user will be redirected to '/' with tokens inside cookies
Adds telegram to social media connections
After, user will be redirected to '/'
Request format:
{
"connect": boolean ***(true to connect, false to disconnect)***
}
Returns employee-application teasers
Possible filters:
Press for details
?localization=Poland,Krakow,Warsaw
&language=en,pl
&minExperience={int} // days of experience
&maxExperience={int} // days of experience
&minAge={int} // years (age)
&maxAge={int} // years (age)
&age=20-25,40-55 // years (age)
&specialization=building,it
&skill=building%201
&maxSalary=25
&minSalary=25
&jobType=regular
&education=high
&gender=sp,male,female
&s=asc / desc
Returns full Application
Request format: json
Press for details
{
"applicationId": {int}
}
Create employee-application
Request format: formData
Press for details
HTML ( changed '<>' to '{}' )
{form id="create-product" enctype="application/json"}
{label for="avatar"}Upload Avatar{/label}
{input type="file" name="avatar" id="avatar">
{label for="portfolio"}Upload Portfolio{/label}
{input type="file" id="portfolio" name="portfolio[]" multiple accept="image/*"}
{label for="relatedAvatar"}Upload Related Avatar{/label}
{input type="file" name="relatedAvatar" id="relatedAvatar"}
{label for="relatedPortfolio"}Upload Related Portfolio{/label}
{input type="file" id="relatedPortfolio" name="relatedPortfolio[]" multiple accept="image/*"}
{button type="submit"}Submit{/button}
{/form}
{script}
const experience = [
{
name: 'name_1',
start: '2025-01-01',
end: '2025-02-01'
},
{
name: 'name_2',
start: '2025-03-01',
end: 'now'
}
];
const relatedApplication = {
name: 'related name',
surname: 'related surname',
birthday: '2025-03-24',
annotation: 'related annotation',
videoLink: 'https://www.youtube.com/watch=iy5ig4trkfd',
gender: 'female',
localization: ['Warsaw', 'Poland'],
specialization: ['building', 'it'],
skills: ['building 1', 'it 1'],
education: 'high',
jobType: 'regular',
experience: JSON.stringify(experience),
language: ['en', 'ua'],
salary: 60,
aboutUser: 'about related user',
showContacts: false,
phone: 'phone',
email: 'email',
telegram: 'telegram',
facebook: 'facebook',
}
const language = ['en', 'ua']
const localization = ['Warsaw', 'Poland']
const specialization = ['building', 'it']
const skills = ['building 1', 'it 1']
const createProductForm = document.getElementById('create-product');
createProductForm.addEventListener("submit", async (event) => {
event.preventDefault();
const imageFile = createProductForm.querySelector('#avatar').files[0];
const relatedImageFile = createProductForm.querySelector('#relatedAvatar').files[0];
const formData = new FormData();
formData.append("name", 'user name');
formData.append("surname", 'user surname');
formData.append("birthday", '2025-03-24');
formData.append("annotation", 'user annotation');
formData.append("videoLink", 'https://www.youtube.com/watch=iy...');
formData.append("gender", 'sssp');
formData.append("localization", localization);
formData.append("specialization", specialization);
formData.append("skills", skills);
formData.append("education", 'high');
formData.append("jobType", 'regular');
formData.append("experience", JSON.stringify(experience));
formData.append("language", language);
formData.append("relatedApplication", JSON.stringify(relatedApplication));
formData.append("salary", 23);
formData.append("aboutUser", 'about user text');
formData.append("needHousing", false);
formData.append("lookingUrgently", false);
formData.append("showContacts", true);
formData.append("phone", 'user phone');
formData.append("email", 'user email');
formData.append("telegram", 'user telegram');
formData.append("facebook", 'user facebook');
formData.append("status", true);
formData.append("visibility", true);
formData.append("avatar", imageFile);
formData.append("relatedAvatar", relatedImageFile);
const portfolioFiles = document.getElementById('portfolio').files;
for (let i = 0; i < portfolioFiles.length; i++) {
formData.append('portfolio[]', portfolioFiles[i]);
}
const relatedPortfolioFiles = document.getElementById('relatedPortfolio').files;
for (let i = 0; i < relatedPortfolioFiles.length; i++) {
formData.append('relatedPortfolio[]', relatedPortfolioFiles[i]);
}
try {
const response = await fetch("/api/create-employee-application", {
method: "POST",
headers: {
'Authorization': 'Bearer ' + 'eyJ0eXAiOiJK...'
},
body: formData
});
if (!response.ok) {
throw new Error("error");
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("error:", error);
}
});
{/script}
Edit employee-application
Request format: formData
Press for details
HTML ( changed '<>' to '{}' )
{form id="create-product" enctype="application/json"}
{label for="avatar"}Upload Avatar{/label}
{input type="file" name="avatar" id="avatar">
{label for="portfolio"}Upload Portfolio{/label}
{input type="file" id="portfolio" name="portfolio[]" multiple accept="image/*"}
{label for="relatedAvatar"}Upload Related Avatar{/label}
{input type="file" name="relatedAvatar" id="relatedAvatar"}
{label for="relatedPortfolio"}Upload Related Portfolio{/label}
{input type="file" id="relatedPortfolio" name="relatedPortfolio[]" multiple accept="image/*"}
{button type="submit"}Submit{/button}
{/form}
{script}
const experience = [
{
name: 'name_1',
start: '2025-01-01',
end: '2025-02-01'
},
{
name: 'name_2',
start: '2025-03-01',
end: 'now'
}
];
const relatedApplication = {
name: 'related name',
surname: 'related surname',
birthday: '2025-03-24',
annotation: 'related annotation',
videoLink: 'https://www.youtube.com/watch=iy5ig4trkfd',
gender: 'female',
localization: ['Warsaw', 'Poland'],
specialization: ['building', 'it'],
skills: ['building 1', 'it 1'],
education: 'high',
jobType: 'regular',
experience: JSON.stringify(experience),
language: ['en', 'ua'],
salary: 60,
aboutUser: 'about related user',
showContacts: false,
phone: 'phone',
email: 'email',
telegram: 'telegram',
facebook: 'facebook',
avatar: "/uploads/user/employee_application/avatar/67f74668e9c96.svg",
portfolio: ["/uploads/user/employee_application/avatar/67f74668e9c96.svg", "/uploads/user/employee_application/avatar/67f74668e9c96.svg"] // empty array [] to delete images
}
const language = ['en', 'ua']
const localization = ['Warsaw', 'Poland']
const specialization = ['building', 'it']
const skills = ['building 1', 'it 1']
const createProductForm = document.getElementById('create-product');
createProductForm.addEventListener("submit", async (event) => {
event.preventDefault();
const imageFile = createProductForm.querySelector('#avatar').files[0];
const relatedImageFile = createProductForm.querySelector('#relatedAvatar').files[0];
const formData = new FormData();
formData.append("id", 1);
formData.append("name", 'user name');
formData.append("surname", 'user surname');
formData.append("birthday", '2025-03-24');
formData.append("annotation", 'user annotation');
formData.append("videoLink", 'https://www.youtube.com/watch=iy...');
formData.append("gender", 'sp');
formData.append("localization", localization);
formData.append("specialization", specialization);
formData.append("skills", skills);
formData.append("education", 'high');
formData.append("jobType", 'regular');
formData.append("experience", JSON.stringify(experience));
formData.append("language", language);
formData.append("relatedApplication", JSON.stringify(relatedApplication));
formData.append("salary", 23);
formData.append("aboutUser", 'about user text');
formData.append("needHousing", false);
formData.append("lookingUrgently", false);
formData.append("showContacts", true);
formData.append("phone", 'user phone');
formData.append("email", 'user email');
formData.append("telegram", 'user telegram');
formData.append("facebook", 'user facebook');
formData.append("status", true);
formData.append("visibility", true);
formData.append("avatar", imageFile);
formData.append("relatedAvatar", relatedImageFile);
formData.append("avatar", '/uploads/user/employee_application/avatar/67f88154be200.svg');
formData.append("portfolio", ["/uploads/user/employee_application/avatar/67f74668e9c96.svg", "/uploads/user/employee_application/avatar/67f74668e9c96.svg"]); // empty array [] to delete images
const portfolioFiles = document.getElementById('portfolio').files;
for (let i = 0; i < portfolioFiles.length; i++) {
formData.append('portfolio[]', portfolioFiles[i]);
}
const relatedPortfolioFiles = document.getElementById('relatedPortfolio').files;
for (let i = 0; i < relatedPortfolioFiles.length; i++) {
formData.append('relatedPortfolio[]', relatedPortfolioFiles[i]);
}
try {
const response = await fetch("/api/edit-employee-application", {
method: "POST",
headers: {
'Authorization': 'Bearer ' + 'eyJ0eXAiOiJK...'
},
body: formData
});
if (!response.ok) {
throw new Error("error");
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("error:", error);
}
});
{/script}
Deletes Application
Request format: json
Press for details
{
"applicationId": {int}
}
returns applications of the current user
Empty body
Returns application of the user (for spectators)
Request format: json
Press for details
{
"applicationId": {int}
}
Returns current user company-application
Empty body
Creates company application
Request format: formData
Press for details
{form id="create-company-employee" enctype="application/json"}
{label for="create-company-employee-avatar"}Upload Avatar{/label}
{input type="file" name="create-company-employee-avatar" id="create-company-employee-avatar"}
{label for="create-company-employee-avatar2"}Upload Avatar{/label}
{input type="file" name="create-company-employee-avatar2" id="create-company-employee-avatar2"}
{button type="submit"}Submit{/button}
{/form}
{script>
const companyName = 'company name'
const description = 'company description'
const addressCity = 'company addressCity'
const addressStreet = 'company addressStreet'
const phone = 'company phone'
const email = 'company email'
const telegram = 'company telegram'
const name = 'company name'
const surname = 'company surname'
const birthday = '2000-01-01'
const gender = 'male'
const status = 'success'
const createProductForms = document.getElementById('create-company-employee');
createProductForms.addEventListener("submit", async (event) => {
event.preventDefault();
const imageFiles = createProductForms.querySelector('#create-company-employee-avatar').files[0];
const formData = new FormData();
formData.append("applicationId", 4);
formData.append("avatar", imageFiles);
formData.append("companyName", companyName);
formData.append("description", description);
formData.append("addressCity", addressCity);
formData.append("addressStreet", addressStreet);
formData.append("phone", phone);
formData.append("email", email);
formData.append("telegram", telegram);
formData.append("name", name);
formData.append("surname", surname);
formData.append("birthday", birthday);
formData.append("gender", gender);
formData.append("status", status);
try {
const response = await fetch("/api/create-company-applications", {
method: "POST",
headers: {
'Authorization': 'Bearer ' + 'eyJ0eXAi...'
},
body: formData
});
if (!response.ok) {
throw new Error("Помилка під час надсилання даних");
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("Помилка:", error);
}
})
{/script>
Edits company application
Request format: formData
Press for details
{form id="create-company-employee" enctype="application/json"}
{label for="create-company-employee-avatar"}Upload Avatar{/label}
{input type="file" name="create-company-employee-avatar" id="create-company-employee-avatar"}
{label for="create-company-employee-avatar2"}Upload Avatar{/label}
{input type="file" name="create-company-employee-avatar2" id="create-company-employee-avatar2"}
{button type="submit"}Submit{/button}
{/form}
{script>
const companyName = 'company name'
const description = 'company description'
const addressCity = 'company addressCity'
const addressStreet = 'company addressStreet'
const phone = 'company phone'
const email = 'company email'
const telegram = 'company telegram'
const name = 'company name'
const surname = 'company surname'
const birthday = '2000-01-01'
const gender = 'male'
const status = 'success'
const createProductForms = document.getElementById('create-company-employee');
createProductForms.addEventListener("submit", async (event) => {
event.preventDefault();
const imageFiles = createProductForms.querySelector('#create-company-employee-avatar').files[0];
const formData = new FormData();
formData.append("applicationId", 4);
formData.append("avatar", imageFiles);
formData.append("companyName", companyName);
formData.append("description", description);
formData.append("addressCity", addressCity);
formData.append("addressStreet", addressStreet);
formData.append("phone", phone);
formData.append("email", email);
formData.append("telegram", telegram);
formData.append("name", name);
formData.append("surname", surname);
formData.append("birthday", birthday);
formData.append("gender", gender);
formData.append("status", status);
formData.append("avatar", "/uploads/user/employee_application/avatar/67f8aae1058c5.webp");
try {
const response = await fetch("/api/edit-company-applications", {
method: "POST",
headers: {
'Authorization': 'Bearer ' + 'eyJ0eXAi...'
},
body: formData
});
if (!response.ok) {
throw new Error("Помилка під час надсилання даних");
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("Помилка:", error);
}
})
{/script>
Deletes company application
Request format: json
Press for details
{
"applicationId": {int}
}
Creates Vacancy
Request format: formData
Press for details
{form id="create-vacancy" enctype="application/json">
{div>create vacancy Images{/div>
{label for="vacancyAvatar">Upload vacancy Avatar{/label>
{input type="file" name="vacancyAvatar" id="vacancyAvatar">
{label for="create-vacancy-portfolio">Upload vacancy images{/label>
{input type="file" id="create-vacancy-portfolio" name="create-vacancy-portfolio[]" multiple accept="image/*">
{button type="submit">Submit{/button>
{/form>
{script>
const vacancyName = 'vacancy name'
const vacancyType = 'vacancy'
const vacancyDescription = 'company addressStreet'
const vacancyLocalization = ['Warsaw', 'Krakow']
const vacancySpecialization = ['building', 'it']
const minAge = 20
const maxAge = 30
const vacancyGender = ['male', 'female']
const shift = 3
const vacancySalary = 25
const workHours = 40
const vacancyJobType = 'jobType 1'
const vacancyEducation = ['high', 'medium']
const vacancyLanguage = ['en', 'pl']
const visibleContacts = true
const isOpen = true
const vacancyStatus = 'success'
const housing = {
rooms: 2,
area: 34,
videoLinks: ['link1']
}
const latitude = "1234567890.123456"
const longitude = "1234567890.123456"
const createVacancy = document.getElementById('create-vacancy');
createVacancy.addEventListener("submit", async (event) => {
event.preventDefault();
const vacancyAvatar = createVacancy.querySelector('#vacancyAvatar').files[0];
const formData = new FormData();
formData.append("avatar", vacancyAvatar);
formData.append("name", vacancyName);
formData.append("vacancyType", vacancyType);
formData.append("description", vacancyDescription);
formData.append("localization", vacancyLocalization);
formData.append("specialization", vacancySpecialization);
formData.append("minAge", minAge);
formData.append("maxAge", maxAge);
formData.append("gender", vacancyGender);
formData.append("shift", shift);
formData.append("salary", vacancySalary);
formData.append("workHours", workHours);
formData.append("jobType", vacancyJobType);
formData.append("education", vacancyEducation);
formData.append("language", vacancyLanguage);
formData.append("visibleContacts", visibleContacts);
formData.append("isOpen", isOpen);
formData.append("status", vacancyStatus);
formData.append("housing", JSON.stringify(housing));
formData.append("latitude", latitude);
formData.append("longitude", longitude);
const vacancyFiles = document.getElementById('create-vacancy-portfolio').files;
for (let i = 0; i < vacancyFiles.length; i++) {
formData.append('portfolio[]', vacancyFiles[i]);
}
try {
const response = await fetch("/api/create-vacancy", {
method: "POST",
headers: {
'Authorization': 'Bearer ' + 'eyJ0eX...'
},
body: formData
});
if (!response.ok) {
throw new Error("error");
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("error:", error);
}
})
{/script>
edits Vacancy
Request format: formData
Press for details
{form id="create-vacancy" enctype="application/json">
{div>create vacancy Images{/div>
{label for="vacancyAvatar">Upload vacancy Avatar{/label>
{input type="file" name="vacancyAvatar" id="vacancyAvatar">
{label for="create-vacancy-portfolio">Upload vacancy images{/label>
{input type="file" id="create-vacancy-portfolio" name="create-vacancy-portfolio[]" multiple accept="image/*">
{button type="submit">Submit{/button>
{/form>
{script>
const vacancyName = 'vacancy name'
const vacancyType = 'vacancy'
const vacancyDescription = 'company addressStreet'
const vacancyLocalization = ['Warsaw', 'Krakow']
const vacancySpecialization = ['building', 'it']
const minAge = 20
const maxAge = 30
const vacancyGender = ['male', 'female']
const shift = 3
const vacancySalary = 25
const workHours = 40
const vacancyJobType = 'jobType 1'
const vacancyEducation = ['high', 'medium']
const vacancyLanguage = ['en', 'pl']
const visibleContacts = true
const isOpen = true
const vacancyStatus = 'success'
const housing = {
rooms: 2,
area: 34,
videoLinks: ['link1']
portfolio: ["/uploads/user/employee_application/portfolio/67f8aa0c609d6.svg", "/uploads/user/employee_application/portfolio/67f8aa0c60d8d.webp"] // empty array [] to delete images
}
const latitude = "1234567890.123456"
const longitude = "1234567890.123456"
const createVacancy = document.getElementById('create-vacancy');
createVacancy.addEventListener("submit", async (event) => {
event.preventDefault();
const vacancyAvatar = createVacancy.querySelector('#vacancyAvatar').files[0];
const formData = new FormData();
formData.append("applicationId", 5);
formData.append("avatar", vacancyAvatar);
formData.append("name", vacancyName);
formData.append("vacancyType", vacancyType);
formData.append("description", vacancyDescription);
formData.append("localization", vacancyLocalization);
formData.append("specialization", vacancySpecialization);
formData.append("minAge", minAge);
formData.append("maxAge", maxAge);
formData.append("gender", vacancyGender);
formData.append("shift", shift);
formData.append("salary", vacancySalary);
formData.append("workHours", workHours);
formData.append("jobType", vacancyJobType);
formData.append("education", vacancyEducation);
formData.append("language", vacancyLanguage);
formData.append("visibleContacts", visibleContacts);
formData.append("isOpen", isOpen);
formData.append("status", vacancyStatus);
formData.append("housing", JSON.stringify(housing));
formData.append("latitude", latitude);
formData.append("longitude", longitude);
formData.append("avatar", '/uploads/user/employee_application/avatar/67f8aa0c615ea.svg');
const vacancyFiles = document.getElementById('create-vacancy-portfolio').files;
for (let i = 0; i < vacancyFiles.length; i++) {
formData.append('portfolio[]', vacancyFiles[i]);
}
try {
const response = await fetch("/api/edit-vacancy", {
method: "POST",
headers: {
'Authorization': 'Bearer ' + 'eyJ0eX...'
},
body: formData
});
if (!response.ok) {
throw new Error("error");
}
const result = await response.json();
console.log(result);
} catch (error) {
console.error("error:", error);
}
})
{/script>
Deletes vacancy
Request format: json
Press for details
{
"vacancyId": {int}
}
returns current user vacancy (
Request format: json
Press for details
{
"vacancyId": {int}
}
returns user vacancy
Request format: json
Press for details
{
"vacancyId": {int}
}
returns user vacancies
empty body
returns vacancies (with filters)
possible filters
Press for details
?localization=Poland,Krakow,Warsaw
®ion=region1,region2
&district=district1,district2
&language=en,pl
&needHousing=true
&minAge={int} // years (age)
&maxAge={int} // years (age)
&specialization=building,it
&minSalary=25
&jobType=vacancy
&education=high
&gender=sp,male,female
&s=asc / desc
&q=word1+word2%20word3
sends an Application to Employer
Press for details
{
"vacancyId": {int}
"applicationId": {int}
"message": {string} // optional
}
invites an Application
Press for details
{
"vacancyId": {int}
"applicationId": {int}
"message": {string} // optional
}
cancels sending an Application to Employer
Press for details
{
"vacancyId": {int}
}
cancels sending an Invitation to Employee
Press for details
{
"applicationId": {int}
}
approves an Application sent to Employer
Press for details
{
"applicationId": {int}
}
rejects an Application sent to Employer
Press for details
{
"applicationId": {int}
}
approves an Invitation sent to Employee
Press for details
{
"vacancyId": {int}
}
rejects an Invitation sent to Employee
Press for details
{
"vacancyId": {int}
}
sends proposition to Employer to end the job / ends the job
Press for details
{
"vacancyId": {int}
}
sends proposition to Employee to end the job / ends the job
Press for details
{
"applicationId": {int}
}
endpoint for Employee: returns status of interaction with Vacancy
Press for details
{
"vacancyId": {int}
}
endpoint for Employer: returns status of interaction with Application
Press for details
{
"applicationId": {int}
}
endpoint for testing. ( vacancyApplicationId - (int)id of interaction, can be found here: /api/vacancy-connections or /api/employee-connections )
deletes interaction between application and vacancy
empty body
returns interactions of the Employee
Press for details
{
"s": asc / desc
}
returns interactions of the Employer
Press for details
{
"s": asc / desc
}
returns interactions with the Application
Press for details
{
"applicationId": int
"s": asc / desc // optional
}
returns interactions with the Vacancy
Press for details
{
"vacancyId": int
"s": asc / desc // optional
}
endpoint for Employer: returns status of interaction with Application
Press for details
{
"target_user": int
"content": string
"rating": int // 1 - 5
}
возвращает количество анкет в конкретном городе
Press for details
{
"localization": string
}
возвращает количество вакансий по категориям в конкретном городе
Press for details
{
"localization": string
}
помечает взаимодействия прочитанными
Press for details
{
"interactionIds": [1,2]
}
создает отзыв
Press for details
{
"targetUserId": int
"content": string
"rating": int // 1 - 5
}
возвращает отзывы юзера
Press for details
{
"targetUserId": int
}
взвращает мои чатыо
empty body
помечает сообщения прочитанными
Press for details
{
"messagesIds": [1,2,3]
}
Press for details
{input type="text" id="message" placeholder="enter message">
{button onclick="sendMessage()">send{/button>
{input type="file" id="imageInput">
{button onclick="sendImage()">send image{/button>
{script>
const token = "eyJ0eXAi...";
const recipientId = 5;
const ws = new WebSocket(`wss://mrowkibeckend.website/chat?token=${token}&recipient_id=${recipientId}`);
ws.onopen = () => console.log("connected to WebSocket-server");
ws.onmessage = (event) => {
console.log(event.data)
};
ws.onclose = () => console.log("connection closed");
function sendMessage() {
const msg = document.getElementById("message").value;
const payload = {
type: 'message',
content: msg
};
ws.send(JSON.stringify(payload));
document.getElementById("message").value = "";
}
function sendImage() {
const fileInput = document.getElementById('imageInput');
const file = fileInput.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function (event) {
const base64Image = event.target.result;
const payload = {
type: 'image',
content: base64Image,
filename: file.name
};
ws.send(JSON.stringify(payload));
};
reader.readAsDataURL(file);
}
{/script>
возвращает отзывы юзера
Press for Request details
{
"date": "2025-04-11" // optional
}
Press for Response details
{
"vacancies": {
"statusCounters": {
"pending": 0,
"success": 8,
"rejected": 0,
"requires_editing": 0
},
"localizationCounters": {
"Poland": 0,
"Warsaw": 8,
"Krakow": 8
}
},
"companyApplications": {
"statusCounters": {
"pending": 0,
"success": 0,
"rejected": 0,
"requires_editing": 0
}
},
"employeeApplications": {
"statusCounters": {
"pending": 0,
"success": 0,
"rejected": 0,
"requires_editing": 0
},
"localizationCounters": {
"Poland": 0,
"Warsaw": 0,
"Krakow": 0
}
}
}
возвращает список анкет
Список фильтров:
Press for Request details
?status=success,rejected,requiresEditing,pending
&s=asc / desc
&q=word1+word2%20word3
Press for Response details
{
"totalPages": 1,
"data": [
{
"id": 1,
"name": "user name",
"specialization": [
"building",
"it"
],
"avatar": "/uploads/user/employee_application/avatar/67f88154be200.svg",
"status": "success",
"rating": "4.25"
},
]
}
возвращает анкету
Press for Request details
{
"applicationId": "int
}
Press for Response details
{
"id": 1,
"avatar": "/uploads/user/employee_application/avatar/67f88154be200.svg",
"rating": "4.25",
"name": "user name",
"surname": "user surname dsadasdas",
"birthday": "2025-03-24",
"annotation": "user annotation",
"videoLink": "https://www.youtube.com/watch=iy5ig4trk",
"gender": "sp",
"education": "high",
"jobType": "regular",
"experience": [
{
"end": "2025-02-01",
"name": "name_1",
"start": "2025-01-01"
},
{
"end": "now",
"name": "name_2",
"start": "2025-03-01"
}
],
"salary": 24,
"aboutUser": "about user text",
"needHousing": false,
"lookingUrgently": false,
"showContacts": false,
"contacts": {
"phone": "user phone",
"email": "user email",
"telegram": "user telegram",
"facebook": "user facebook"
},
"portfolio": [
"/uploads/user/employee_application/portfolio/67f74668e9fd1.svg",
"/uploads/user/employee_application/portfolio/67f74668ea206.jpg"
],
"relatedApplication": {
"name": "related name",
"email": "email",
"phone": "phone",
"avatar": "/uploads/user/employee_application/avatar/67f74668e9c96.svg",
"gender": "male",
"salary": 60,
"skills": [
"building 1",
"it 1"
],
"jobType": "regular",
"surname": "related surname",
"birthday": "2025-03-24",
"facebook": "facebook",
"language": [
"en",
"ua"
],
"telegram": "telegram",
"aboutUser": "about related user",
"education": "high",
"portfolio": [
"/uploads/user/employee_application/portfolio/67f74668e9fd1.svg",
"/uploads/user/employee_application/portfolio/67f74668ea206.jpg"
],
"videoLink": "https://www.youtube.com/watch=iy5ig4trkfd",
"annotation": "related annotation",
"experience": [
{
"end": "2025-02-01",
"name": "name_1",
"start": "2025-01-01"
},
{
"end": "now",
"name": "name_2",
"start": "2025-03-01"
}
],
"localization": [
"Warsaw",
"Poland"
],
"showContacts": false,
"specialization": [
"building",
"it"
],
"totalExperience": 72
},
"visibility": true,
"languages": [
"en",
"pl",
"ua"
],
"localizations": [
"Poland",
"Warsaw",
"Krakow"
],
"specializations": [
"building",
"it"
],
"skills": [
"building 1",
"it 1"
],
"status": "success",
"createdAt": null
}
изменяет статус анкеты
Press for Request details
{
"applicationId": "int
"status": string // ('success', 'rejected', 'requiresEditing', 'pending')
"message": string // optional
}
возвращает список вакансий
Список фильтров:
Press for Request details
?status=success,rejected,requiresEditing,pending
&localization=Warsaw,Krakow
&minSalary=10
&maxSalary=20
&s=asc / desc
&q=word1+word2%20word3
Press for Response details
{
"totalPages": 5,
"data": [
{
"id": 3,
"vacancyName": "vacancy name",
"vacancyAvatar": "/uploads/user/employee_application/portfolio/67f74668e9fd1.svg",
"status": "success",
"ownerName": "company name company surname",
"localization": [
"Warsaw",
"Krakow"
]
},
]
}
возвращает вакансию
Press for Request details
{
"vacancyId": "int
}
Press for Response details
{
"id": 11,
"name": "vacancy name 1",
"vacancyType": "regular",
"description": "company addressStreet",
"minAge": 20,
"maxAge": 30,
"salary": 25,
"shift": 3,
"workHours": 40,
"jobType": "regular",
"housing": [],
"status": "success",
"visibleContacts": true,
"isOpen": true,
"needHousing": false,
"avatar": "/uploads/user/employee_application/avatar/67f900d03d55d.svg",
"createdAt": {
"date": "2025-04-11 11:45:20.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"applicationsCount": 1,
"views": 0,
"localizations": [
"Warsaw",
"Krakow"
],
"gender": [
"male",
"female"
],
"educations": [
"high",
"medium"
],
"languages": [
"en",
"pl"
],
"specializations": [
"building",
"it"
]
}
изменяет статус вакансии
Press for Request details
{
"vacancyId": "int
"status": string // ('success', 'rejected', 'requiresEditing', 'pending')
"message": string // optional
}
возвращает список компаний
Список фильтров:
Press for Request details
?status=success,rejected,requiresEditing,pending
&s=asc / desc
&q=word1+word2%20word3
Press for Response details
{
"totalPages": 5,
"data": [
{
"id": 6,
"name": "company 6",
"avatar": "/uploads/user/employee_application/avatar/67f6fcabd5a29.svg",
"status": null,
"description": "company description"
},
]
}
возвращает компанию
Press for Request details
{
"companyId": "int
}
Press for Response details
{
"id": 8,
"avatar": "/uploads/user/employee_application/avatar/67f8aae1058c5.webp",
"companyName": "company 8",
"status": "success",
"description": "company description",
"addressCity": "company addressCity",
"phone": "company phone",
"email": "company email",
"telegram": "company telegram",
"name": "company name",
"surname": "company surname",
"birthday": "2000-01-01",
"gender": "male"
}
изменяет статус компании
Press for Request details
{
"companyId": "int
"status": string // ('success', 'rejected', 'requiresEditing', 'pending')
"message": string // optional
}
возвращает список отзывов
Список фильтров:
Press for Request details
?status=success,rejected,blocked,pending
&q=word1+word2%20word3
Press for Response details
{
"totalPages": int,
"data": [
{
"id": int,
"name": ?string,
"surname": ?string,
"content": string,
"applicationId": ?int,
"vacancyId": ?int,
"targetUserId": ?int,
"status": string,
"createdAt": {
"date": "2025-05-16 16:21:25.000000",
"timezone_type": 3,
"timezone": "UTC"
}
},
]
}
возвращает отзыв
Press for Request details
{
"reviewId": "int
}
Press for Response details
"id": int,
"name": ?string,
"surname": ?string",
"content": string,
"applicationId": ?int,
"vacancyId": ?int,
"targetUserId": ?int,
"status": string,
"createdAt": {
"date": "2025-05-16 16:21:25.000000",
"timezone_type": 3,
"timezone": "UTC"
}
изменяет статус отзыва
Press for Request details
{
"companyId": int
"status": string // ('success', 'rejected', 'blocked')
"message": string // optional
}
возвращает историю модерации
Список фильтров:
Press for Request details
?status=success,rejected,requiresEditing,pending
&s=asc / desc
&sortBy=id / username / type / action
Press for Response details
{
"totalPages": 2,
"data": [
{
"id": 4,
"date": {
"date": "2025-05-15 00:28:10.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"moderator": {
"id": 1,
"username": "admin",
"email": "admin@gmail.com"
},
"data": {
"type": "application",
"id": 1
},
"action": "rejected",
"message": "kadfkadbkfbadlbgflaglbvfalgbafjlgblfgb"
},
]
}
возвращает список администраторов
Press for Response details
{
"totalPages": 2,
"data": [
{
"id": 5,
"username": "testsuser",
"email": "testa@example.com",
"access": [
"application",
"company",
"vacancy"
]
},
]
}
создаёт нового администратора
после создания на почту суперАдмина будет отправлен пароль
Press for Request details
{
"username": string
"phone": string
"email": string
"access": ["application", "company", "vacancy", "review"]
}
создаёт новый пароль для администратора
после создания на почту суперАдмина будет отправлен пароль
Press for Request details
{
"userId": int
}
сбрасывает пароль админа по почте и отправляет новый пароль суперадмину на почту
Press for Request details
{
"email": string
}
возвращает уведомления юзера
Cуществуют 3 вида уведомлений: moderation, interaction, review
У каждого вида свой интерфейс
Press for Response details
{
"totalPages": int,
"data": [
// moderation //
{
"id": int,
"type": "moderation",
"title": string (application / company / vacancy)
"details": {
"status": string
"message": ?string
"vacancyId": int
},
"createdAt": {
"date": "2025-05-16 16:16:28.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"isViewed": bool
},
// interaction //
{
"id": int,
"type": "interaction",
"title": string // interaction status (sent / you_approved / candidate...)
"details": {
"status": string // interaction status (sent / you_approved / candidate...)
"vacancyId": int,
"applicationId": int
"vacancyName": string // отображается у стороны соискателя
"applicationName": string // отображается у стороны работодателя
т.е. если я (Работодатель) приглашаю соискателя, ему придет уведомление с полем "vacancyName" о том что ему предложили работу
а мне (Работодателю) придет уведомление с полем "applicationName", что я пригласил соискателя на работу
и наоборот, если я (Соискатель) подаю анкету, то работодателю придет уведомление с полем "applicationName", что я прошусь на работу
а мне (Соискателю) придет уведомление с полем "vacancyName", о том что я отправил заявку
},
"createdAt": {
"date": "2025-05-16 15:52:54.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"isViewed": bool
},
// review //
{
"id": int, // notification id
"type": "review",
"title": "review",
"details": {
"id": int // review id
"author": int // user id
"rating": int
"content": string
"createdAt": "2025-04-27 03:35:29"
},
"createdAt": {
"date": "2025-04-27 03:35:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"isViewed": bool
},
]
}
Помечает уведомления пользователя прочитанными
Press for Request details
{
"notificationsIds": [1,2,3] // id уведомлений
}
возвращает количество непрочитанных уведомлений
сюда указывать почту юзера, для которого нужно сбросить пароль
Press for Request details
{
"email": string
}
сюда указывать новый пароль и токен для сброса пароля
Press for Request details
{
"password": string,
"token": string
}
creates new region
Press for Request details
{
"region": string
}
edits region
Press for Request details
{
"regionId": int,
"newName": string
}
deletes region
Press for Request details
{
"regionId": int
}
returns all regions
Press for Response details
{
"regionId": int,
"regionName": string,
}
creates new district
Press for Request details
{
"regionId": int,
"district": string
}
edits district
Press for Request details
{
"districtId": int
"newName": string,
}
deletes district
Press for Request details
{
"districtId": int
}
returns districts by region
Press for Request details
{
"regionId": int
}
returns districts
Press for Response details
{
"districtId": int,
"districtName": string,
"regionId": int,
"regionName": string,
}
creates localization
Press for Request details
{
"districtId": int,
"localization": string,
"latitude": "1234567890.123456",
"longitude": "1234567890.123456"
}
creates localization
Press for Request details
{
"localizationId": int
"districtId": int,
"newName": string,
"latitude": "1234567890.123456",
"longitude": "1234567890.123456"
}
deletes localization
Press for Request details
{
"localizationId": int
}
returns localizations by district
Press for Request details
{
"districtId": int
}
returns districts
Press for Response details
{
"localizationId": int,
"localizationName": string,
"districtId": int,
"districtName": string,
"latitude": "1234567890.123456"
"longitude": "1234567890.123456"
}
creates filter-localization
Press for Request details
{
"localizationId": int,
"sortOrder": smallInt
}
edits filter-localization
Press for Request details
{
"localizationId": int,
"sortOrder": smallInt
}
deletes filter-localization
Press for Request details
{
"localizationId": int
}
returns filter-localizations
Press for Response details
{
"filterLocalizationId": int,
"localizationId": int,
"localizationName": string,
"sortOrder": smallInt
}