Оформление
Приём откликов
POST /integration/v1/applicationsОбласть доступа applications:write. Метод создаёт карточку кандидата на доске рекрутёра, который ведёт вакансию — там, где её ждут.
Запрос
bash
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
"https://api.odamiai.uz/api/integration/v1/applications" \
-d '{
"externalId": "portal-12345",
"vacancyId": "clx7k2p0000abc",
"source": "career-portal",
"candidate": {
"name": "Иванов Иван",
"email": "ivan@example.com",
"phone": "+7 777 000 00 00",
"location": "Алматы"
},
"coverLetter": "Здравствуйте! Хочу к вам, потому что…",
"resume": {
"role": "Frontend-разработчик",
"summary": "5 лет на React",
"experienceYears": 5,
"skills": ["React", "TypeScript"],
"experience": [
{
"company": "ТОО «Пример»",
"role": "Разработчик",
"period": "2020-01 — наст. время",
"description": "Витрина и личный кабинет"
}
],
"education": [
{ "institution": "КазНУ", "degree": "Бакалавр", "period": "2017" }
],
"expectedSalary": 900000,
"expectedSalaryCurrency": "KZT"
}
}'Обязательны только три вещи: externalId, vacancyId и candidate.name. Всё остальное необязательно намеренно — отклик без резюме лучше потерянного отклика, а недостающее рекрутёр допишет руками.
vacancyId — наш идентификатор, тот же, что приходит в выгрузке вакансий.
Ответ
json
{ "id": "clx9m4r0000def", "status": "created" }201 — карточка создана. 200 со status: "duplicate" — такой отклик мы уже принимали, и это тоже успех.
Идемпотентность
externalId — идентификатор отклика в вашей системе. Повторный запрос с тем же значением вернёт идентификатор ранее созданной карточки и не создаст вторую.
Это не удобство, а необходимость: сеть рвётся, таймауты случаются, и клиент обязан иметь право повторить запрос. Без идемпотентности каждый повтор был бы новым человеком на доске у рекрутёра.
Уникальность считается в пределах вашей компании, поэтому годится любой ваш внутренний идентификатор — номер записи, uuid отклика.
Рефералы
Реферал — тот же отклик, но с блоком referral:
json
{
"externalId": "referral-777",
"vacancyId": "clx7k2p0000abc",
"source": "referral-form",
"candidate": { "name": "Сидоров Пётр", "phone": "+7 777 222 22 22" },
"referral": {
"name": "Петров Пётр",
"email": "petrov@example.com",
"phone": "+7 777 111 11 11",
"company": "Teez",
"relationship": "Бывший коллега"
}
}Отдельного признака «это реферал» в контракте нет: реферал — это отклик, у которого есть рекомендатель. Заполненный блок и есть признак, и обратно в выгрузке кандидатов он приезжает тем же блоком.
В интерфейсе платформы такая карточка помечена как реферал, и рекрутёр видит, кто человека привёл.
Что происходит после
Карточка встаёт в первую колонку доски этой вакансии и попадает в аналитику найма наравне с откликами из других источников.
Автоматический скоринг при этом не запускается — так же, как он не запускается при импорте с hh.ru. Рекрутёр решает сам.
Особенности, о которых лучше знать заранее
Дубли людей мы не склеиваем. Каждый отклик создаёт новое резюме, даже если человек с такой почтой у компании уже есть. Это осознанное решение: досье человека видно всей компании, и автоматическая склейка по почте позволила бы чужой системе подшить произвольный отклик — и произвольного «рекомендателя» — в карточку реального человека. Опечатка в адресе делала бы то же самое молча.
Отклик принимается на вакансию в любом статусе. Позицию могли закрыть между тем, как человек увидел её у вас, и тем, как нажал кнопку. Терять из-за этой гонки чьи-то данные неправильно — фильтруйте показ на своей стороне.
Чужая вакансия даёт 404, а не 403. Ответ одинаков для «не существует» и «принадлежит другой компании»: по коду ответа не должно быть возможности перебирать чужие идентификаторы.