Сценарий из mcp-everything. Актуально на 2026-10-24.
Размещать вакансии из своей ATS или карьерного сайта сразу на hh.ru.
curl -X POST https://api.hh.ru/vacancies \
-H "Authorization: Bearer $HH_TOKEN" \
-H 'HH-User-Agent: MyApp/1.0 (dev@example.ru)' \
-H 'Content-Type: application/json' \
-d '{
"name": "Python-разработчик",
"description": "<p>Разрабатываем сервисы для логистики.</p><ul><li>Python 3, FastAPI</li></ul>",
"area": {"id": "1"},
"professional_roles": [{"id": "96"}],
"salary_range": {"from": 200000, "to": 300000, "currency": "RUR", "gross": false, "mode": {"id": "MONTH"}, "frequency": {"id": "TWICE_PER_MONTH"}},
"key_skills": [{"name": "Python"}, {"name": "PostgreSQL"}]
}'
https://api.hh.ru?host=Тип: OAuth 2.0
OAuth 2.0. Токен передаётся в заголовке Authorization: Bearer {ACCESS_TOKEN}.
https://hh.ru/oauth/authorize?response_type=code&client_id={client_id}&state={state}&redirect_uri={redirect_uri}, затем authorization_code из редиректа обменивается на access_token и refresh_token запросом POST https://api.hh.ru/token. Поддерживается PKCE (code_challenge, code_challenge_method=S256).POST https://api.hh.ru/token с refresh_token; refresh-токен одноразовый и работает только после истечения access_token (срок — expires_in, в секундах).https://dev.hh.ru/admin.Параметры /oauth/authorize: skip_choose_account=true — не показывать выбор аккаунта, force_login=true — всегда показывать форму входа, role (applicant или employer) с force_role=true — требовать нужную роль.
В каждом запросе обязателен заголовок User-Agent или HH-User-Agent (при обоих учитывается HH-User-Agent); без него — 400 Bad Request.
User-Agent: MyApp/1.0 (my-app-feedback@example.com)
Тело — application/x-www-form-urlencoded. Набор полей зависит от grant_type (получение токена пользователя, обновление пары токенов, токен приложения). Ниже — поля для обмена authorization_code.
В ответе: access_token, token_type (bearer), expires_in, refresh_token.
| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
HH-User-Agent |
header | string | да | Название приложения и почта разработчика |
grant_type |
body | string | да | authorization_code |
client_id |
body | string | да | Идентификатор приложения |
client_secret |
body | string | да | Секретный ключ приложения |
code |
body | string | да | Полученный authorization_code |
redirect_uri |
body | string | да | URI перенаправления (если не указан — из настроек приложения) |
code_verifier |
body | string | нет | Верификатор PKCE; обязателен, если передавался code_challenge |
В ответе: auth_type, id, email, first_name, last_name, is_applicant, is_employer, employer, manager, counters и др.
| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
HH-User-Agent |
header | string | да | Название приложения и почта разработчика |
При успешной публикации списываются услуги работодателя; конкретный пакет задаётся employer_service_id, иначе выбирается автоматически. Все вакансии проходят ручную модерацию и появляются в поиске через несколько минут. Успех — 201.
| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
ignore_duplicates |
query | boolean | нет | Принудительно добавить дубликат |
name |
body | string | да | Название |
description |
body | string | да | Описание в HTML |
area |
body | object | да | Регион |
professional_roles |
body | array | да | Профессиональные роли |
vacancy_properties |
body | object | нет | Свойства публикации (заменяет устаревшие type и billing_type) |
employer_service_id |
body | string | нет | Пакет услуг из suitable_packages[].employer_service_id |
salary_range |
body | object | нет | Зарплата (поле salary устарело) |
address |
body | object | нет | Адрес |
experience |
body | object | нет | Опыт работы |
employment_form |
body | object | нет | Тип занятости |
work_format |
body | array | нет | Форматы работы |
work_schedule_by_days |
body | array | нет | Графики работы |
working_hours |
body | array | нет | Рабочие часы в день |
key_skills |
body | array | нет | Ключевые навыки |
contacts |
body | object | нет | Контакты; при использовании нужен атрибут phones |
code |
body | string | нет | Внутренний код вакансии |
department |
body | object | нет | Департамент работодателя |
manager |
body | object | нет | Менеджер вакансии |
previous_id |
body | string | нет | ID архивной вакансии для связи с новой |
response_letter_required |
body | boolean | нет | Обязательно сопроводительное письмо |
test |
body | object | нет | Тест для вакансии |
Изменяет переданные поля. Составные поля (salary_range, contacts, professional_roles) передаются целиком. billing_type и manager меняются отдельным запросом.
| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
vacancy_id |
path | string | да | Идентификатор вакансии |
ignore_duplicates |
query | boolean | нет | Игнорировать появление дубликата (по умолчанию false) |
ignore_replacement_warning |
query | boolean | нет | Игнорировать ошибку о значительном изменении (по умолчанию true, есть риск блокировки) |
name |
body | string | нет | Название |
description |
body | string | нет | Описание в HTML |
salary_range |
body | object | нет | Зарплата (целиком) |
contacts |
body | object | нет | Контакты (целиком) |
professional_roles |
body | array | нет | Профессиональные роли (целиком) |
Успех — 204.
| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
employer_id |
path | string | да | Идентификатор работодателя |
vacancy_id |
path | string | да | Идентификатор вакансии |
page=N&per_page=M, нумерация с нуля; ответ — found, per_page, pages, page, items./cors (HEAD, GET, POST, PUT, DELETE), для JSONP — ?callback=callback_name.2xx или 409 для дубликата (определяется по id). Без ответа за 5 секунд колбэк отправляется повторно; доставка не гарантирована. При долгих сбоях подписка блокируется, при отзыве доступа удаляется./negotiations/{nid}/messages устарели — переписка ведётся через /common/chats.hidden_fields.Если этого недостаточно — официальная документация: https://api.hh.ru/openapi/redoc Вся интеграция одним документом: https://mcp-everything.ru/integrations/hh-api.md