---
slug: "hh-api"
name: "HeadHunter API (hh.ru)"
vendor: "HeadHunter"
industry: "hr"
docsUrl: "https://api.hh.ru/openapi/redoc"
version: 2
updatedAt: "2026-10-24"
---

# HeadHunter API (hh.ru)

Отрасль: HR и рекрутинг. Актуально на 2026-10-24.

REST API сайтов группы HeadHunter (hh.ru, rabota.by, hh1.az, hh.uz, hh.kz, headhunter.ge, headhunter.kg). Позволяет искать вакансии, резюме и работодателей, публиковать и архивировать вакансии, работать с откликами и приглашениями, вести переписку в чатах, получать справочники и подписываться на вебхуки. Данные передаются только в JSON по HTTPS, даты — в формате ISO 8601 (`YYYY-MM-DDThh:mm:ss±hhmm`).

## Сценарии

### Найти вакансии по запросу

Поиск вакансий hh.ru для своего сайта, бота или аналитики зарплат.

1. Передавай в каждом запросе заголовок HH-User-Agent с названием приложения и почтой разработчика — без него придёт 400.
2. Узнай ID региона: GET /areas (1 — Москва, 2 — Санкт-Петербург). Значения фильтров (опыт, тип занятости, сортировка) — в GET /dictionaries.
3. Ищи: GET /vacancies с text, area, salary, experience, per_page (до 100) и page (с нуля). Только с указанной зарплатой — label = with_salary.
4. В ответе found, pages и items. Глубина выдачи — не больше 2000 вакансий: для полного охвата сужай запрос по регионам или датам (date_from, date_to).
5. Без токена после первого запроса может потребоваться капча (ответ 403) — для массовых запросов используй токен приложения.

```bash
curl -G https://api.hh.ru/vacancies \
  -H 'HH-User-Agent: MyApp/1.0 (dev@example.ru)' \
  --data-urlencode 'text=python разработчик' \
  -d area=1 -d salary=200000 -d only_with_salary=true \
  -d per_page=50 -d page=0
```

### Опубликовать вакансию от имени работодателя

Размещать вакансии из своей ATS или карьерного сайта сразу на hh.ru.

1. Зарегистрируй приложение на dev.hh.ru. Отправь менеджера работодателя на https://hh.ru/oauth/authorize с response_type = code, client_id и redirect_uri.
2. Обменяй код на токены: POST /token с grant_type = authorization_code, client_id, client_secret, code и redirect_uri (тело — form-urlencoded). Обновить пару — тот же метод с refresh_token, но только после истечения access_token.
3. Узнай ID работодателя: GET /me — поле employer.id.
4. Опубликуй: POST /vacancies с name, description (HTML), area, professional_roles и при необходимости salary_range, experience, work_format, key_skills. Ответ 201. Услуги списываются с пакета работодателя; все вакансии проходят модерацию и появляются в поиске через несколько минут.
5. Изменить вакансию — PUT /vacancies/{vacancy_id} (составные поля вроде salary_range передавай целиком). Снять с публикации — PUT /employers/{employer_id}/vacancies/archived/{vacancy_id}.

```bash
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"}]
      }'
```

### Разобрать отклики на вакансию

Забирать откликнувшихся кандидатов в свою систему и приглашать или отказывать без захода на hh.ru.

1. Получи отклики: GET /negotiations с vacancy_id (обязателен для работодателя) и, например, has_updates = true — только с непросмотренным.
2. Открой отклик: GET /negotiations/{id} — адрес берётся из items[].url. Резюме кандидата смотри через ссылку из отклика.
3. Чтобы пригласить или отказать, возьми из actions[] нужное действие и вызови PUT /negotiations/{collection_name}/{nid} с аргументами из actions[].arguments (form-urlencoded). Успех — 204.
4. Не составляй адреса действий вручную: доступные действия зависят от состояния отклика и приходят в ответе.

```bash
curl -G https://api.hh.ru/negotiations \
  -H "Authorization: Bearer $HH_TOKEN" -H 'HH-User-Agent: MyApp/1.0 (dev@example.ru)' \
  -d vacancy_id=123456789 -d has_updates=true -d per_page=50
```

### Переписываться с кандидатом в чате

Отправлять кандидатам сообщения из своей системы и читать ответы.

1. Получи чаты: GET /common/chats — с filter_unread = true только непрочитанные, с filter_with_vacancy_ids — по нужным вакансиям.
2. Прочитай сообщения: GET /common/chats/{chat_id}/messages с limit (до 50) и start_message_id для постраничного чтения.
3. Отправь сообщение: POST /common/chats/{chat_id}/messages с idempotency_key (UUID) и text. Повтор с тем же ключом вернёт 409 и не создаст дубль.
4. Старые методы /negotiations/{nid}/messages устарели — переписку веди через /common/chats.

```bash
curl -X POST https://api.hh.ru/common/chats/<chat_id>/messages \
  -H "Authorization: Bearer $HH_TOKEN" -H 'HH-User-Agent: MyApp/1.0 (dev@example.ru)' \
  -H 'Content-Type: application/json' \
  -d "{\"idempotency_key\": \"$(uuidgen)\", \"text\": \"Добрый день! Приглашаем на собеседование в четверг в 15:00.\"}"
```

### Получать уведомления о новых откликах

Узнавать о новых откликах и сообщениях сразу, без опроса.

1. Подпишись: POST /webhook/subscriptions с url своего обработчика и actions — списком нужных событий (типы событий — в документации вебхуков). Доступно только работодателю; на приложение — один URL.
2. Колбэк приходит POST-запросом с action_type, id и payload (vacancy_id, resume_id, chat_id и др.). Отвечай 2xx в течение 5 секунд, на повтор с тем же id — 409.
3. Доставка не гарантирована: раз в несколько часов сверяй отклики через GET /negotiations.
4. Список подписок — GET /webhook/subscriptions, удалить — DELETE /webhook/subscriptions/{subscription_id}.

```bash
curl -X POST https://api.hh.ru/webhook/subscriptions \
  -H "Authorization: Bearer $HH_TOKEN" -H 'HH-User-Agent: MyApp/1.0 (dev@example.ru)' \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.ru/hh/webhook", "actions": [{"type": "<тип события>"}]}'
```

## Базовые URL

- Боевой: `https://api.hh.ru`
- Запросы ко всем сайтам группы идут на один адрес; нужный сайт задаётся параметром  (по умолчанию ), локаль: `?host=`

## Авторизация

Тип: OAuth 2.0

OAuth 2.0. Токен передаётся в заголовке `Authorization: Bearer {ACCESS_TOKEN}`.

- Токен пользователя (authorization code): пользователь открывает `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`, в секундах).
- Токен приложения (client credentials): срок жизни не ограничен, при повторном запросе прежний отзывается; запрашивать не чаще раза в 5 минут. Актуальный токен виден владельцу на `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)
```

## Методы

### POST /token — Получение access-токена

Тело — `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 |

### DELETE /token — Инвалидация токена

Работает только для действующего токена пользователя; токен приложения так инвалидировать нельзя. После инвалидации нужно авторизоваться заново. Успех — `204`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `HH-User-Agent` | header | string | да | Название приложения и почта разработчика |

### GET /me — Информация о текущем пользователе

В ответе: `auth_type`, `id`, `email`, `first_name`, `last_name`, `is_applicant`, `is_employer`, `employer`, `manager`, `counters` и др.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `HH-User-Agent` | header | string | да | Название приложения и почта разработчика |

### GET /vacancies — Поиск по вакансиям

Неизвестные параметры игнорируются. Без токена после первого запроса может потребоваться капча. Глубина выдачи — не больше 2000 (`per_page=10&page=199` можно, `page=200` — ошибка). Параметры, где указано «можно несколько», передаются как `key=value&key=value`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `text` | query | string | нет | Поисковая фраза (поддерживается язык запросов) |
| `search_field` | query | string | нет | Область поиска из vacancy_search_fields в /dictionaries; можно несколько |
| `area` | query | string | нет | Регион из /areas; можно несколько |
| `metro` | query | string | нет | Ветка или станция метро из /metro; можно несколько |
| `professional_role` | query | string | нет | Профессиональная роль из /professional_roles |
| `industry` | query | string | нет | Индустрия компании из /industries; можно несколько |
| `employer_id` | query | string | нет | Работодатель; можно несколько |
| `experience` | query | string | нет | Опыт из experience в /dictionaries; можно несколько |
| `employment_form` | query | string | нет | Тип занятости из vacancy_search_employment_form; можно несколько |
| `work_format` | query | string | нет | Формат работы из work_format; можно несколько |
| `work_schedule_by_days` | query | string | нет | График работы; можно несколько |
| `working_hours` | query | string | нет | Рабочие часы в день; можно несколько |
| `salary` | query | number | нет | Размер зарплаты; валюта по умолчанию RUR |
| `currency` | query | string | нет | Код валюты из currency в /dictionaries (только вместе с salary) |
| `label` | query | string | нет | Метки вакансий из vacancy_label (например, with_salary); можно несколько |
| `excluded_text` | query | string | нет | Исключить вакансии с этими словами (через запятую) |
| `education` | query | string | нет | not_required_or_not_specified, special_secondary, higher |
| `period` | query | number | нет | Поиск за последние N дней |
| `date_from` | query | string | нет | Нижняя граница даты публикации (ISO 8601); нельзя вместе с period |
| `date_to` | query | string | нет | Верхняя граница даты публикации; нельзя вместе с period |
| `top_lat` | query | number | нет | Верхняя граница широты (передавать все четыре гео-параметра) |
| `bottom_lat` | query | number | нет | Нижняя граница широты |
| `left_lng` | query | number | нет | Левая граница долготы |
| `right_lng` | query | number | нет | Правая граница долготы |
| `order_by` | query | string | нет | Сортировка из vacancy_search_order; для distance нужны sort_point_lat, sort_point_lng |
| `clusters` | query | boolean | нет | Вернуть кластеры поиска (по умолчанию false) |
| `describe_arguments` | query | boolean | нет | Вернуть описание применённых параметров (arguments) |
| `no_magic` | query | boolean | нет | Отключить автоматическое преобразование текстового запроса в параметры |
| `responses_count_enabled` | query | boolean | нет | Добавить поле counters с числом откликов |
| `page` | query | number | нет | Номер страницы, по умолчанию 0 |
| `per_page` | query | number | нет | Элементов на странице, по умолчанию 10, максимум 100 |

### GET /vacancies/{vacancy_id} — Просмотр вакансии

Коды: `403` — нужна капча, `404` — вакансия не существует или нет прав, `429` — слишком много запросов.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `vacancy_id` | path | string | да | Идентификатор вакансии |
| `HH-User-Agent` | header | string | да | Название приложения и почта разработчика |

### GET /vacancies/{vacancy_id}/similar_vacancies — Похожие вакансии

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `vacancy_id` | path | string | да | Идентификатор вакансии |

### POST /vacancies — Публикация вакансии

При успешной публикации списываются услуги работодателя; конкретный пакет задаётся `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 | нет | Тест для вакансии |

### PUT /vacancies/{vacancy_id} — Редактирование вакансии

Изменяет переданные поля. Составные поля (`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 | нет | Профессиональные роли (целиком) |

### GET /employers/{employer_id}/vacancies/active — Опубликованные вакансии работодателя

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `employer_id` | path | string | да | Идентификатор работодателя |
| `manager_ids` | query | string | нет | ID менеджеров через запятую, например manager_ids=1,2,3 |
| `all_accessible` | query | boolean | нет | Вакансии текущего пользователя и менеджеров, к которым есть доступ |
| `text` | query | string | нет | Поиск по названию |
| `area` | query | string | нет | Регион вакансии |
| `department_id` | query | string | нет | Департамент работодателя |
| `resume_id` | query | string | нет | Только вакансии, подходящие резюме (без других параметров) |
| `order_by` | query | string | нет | Сортировка из employer_active_vacancies_order |
| `page` | query | number | нет | Номер страницы, с 0 |
| `per_page` | query | number | нет | Элементов на странице, по умолчанию 20, максимум 50 |

### PUT /employers/{employer_id}/vacancies/archived/{vacancy_id} — Архивация вакансии

Успех — `204`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `employer_id` | path | string | да | Идентификатор работодателя |
| `vacancy_id` | path | string | да | Идентификатор вакансии |

### GET /resumes — Поиск резюме

Результаты группируются по соискателю (одно резюме на соискателя). Глубина выдачи — не больше 2000. Для тонкой настройки `text` передаётся вся триада `text.logic`, `text.field`, `text.period`.

Пример:

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `text` | query | string | нет | Поисковая фраза; можно несколько |
| `text.logic` | query | string | нет | Логика поиска из resume_search_logic |
| `text.field` | query | string | нет | Где искать, из resume_search_fields (через запятую) |
| `text.period` | query | string | нет | Период опыта работы |
| `area` | query | string | нет | Регион; можно несколько |
| `relocation` | query | string | нет | Готовность к переезду (вместе с area) |
| `age_from` | query | string | нет | Возраст от |
| `age_to` | query | string | нет | Возраст до |
| `salary_from` | query | number | нет | Желаемая зарплата от |
| `salary_to` | query | number | нет | Желаемая зарплата до |
| `currency` | query | string | нет | Код валюты |
| `experience` | query | string | нет | Опыт работы; можно несколько |
| `skill` | query | string | нет | ID ключевых навыков |
| `professional_role` | query | string | нет | Профессиональная роль; можно несколько |
| `language` | query | string | нет | Язык в формате language.level, например ita.c2 |
| `label` | query | string | нет | Доп. фильтр из resume_search_label; можно несколько |
| `period` | query | number | нет | Резюме, опубликованные за N дней |
| `date_from` | query | string | нет | Дата начала поиска; нельзя с period |
| `date_to` | query | string | нет | Дата окончания (только с date_from) |
| `vacancy_id` | query | string | нет | Поиск резюме, похожих на вакансию |
| `search_in_responses` | query | boolean | нет | Искать только среди откликнувшихся на вакансии компании |
| `folder` | query | string | нет | Папки с отобранными резюме, например folder=111&folder=222 |
| `order_by` | query | string | нет | Сортировка из resume_search_order |
| `page` | query | number | нет | Номер страницы, с 0 |
| `per_page` | query | number | нет | По умолчанию 20, максимум 100 |

Пример запроса:

```
GET /resumes?text=программист&text=java
```

### GET /resumes/{resume_id} — Просмотр резюме

Требуется платный доступ. Если полные данные недоступны, часть полей придёт `null`, `can_view_full_info` = `false`, `contact_view_status` = `NONE`. Ссылки на просмотр с контактами и скачивание (PDF, RTF) приходят в поле `actions`; переход по ним списывает контакт.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `resume_id` | path | string | да | Идентификатор резюме |
| `with_negotiations_history` | query | boolean | нет | Добавить negotiations_history.vacancies (до трёх вакансий) |
| `with_creds` | query | boolean | нет | Добавить поле creds |
| `with_job_search_status` | query | boolean | нет | Добавить статус поиска работы |

### GET /negotiations — Список откликов и приглашений

По умолчанию сортировка по дате обновления, от новых к старым. Активные отклики — `?status=active`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `vacancy_id` | query | string | да | ID вакансии (обязателен для работодателя) |
| `status` | query | string | нет | Статус из applicant_negotiation_status |
| `order_by` | query | string | нет | Сортировка из negotiations_order |
| `order` | query | string | нет | asc или desc |
| `has_updates` | query | boolean | нет | Только с непросмотренными сообщениями |
| `with_job_search_status` | query | boolean | нет | Вернуть статус поиска работы кандидата |
| `with_generated_collections` | query | boolean | нет | Вернуть сгенерированные коллекции |
| `page` | query | number | нет | Номер страницы |
| `per_page` | query | number | нет | По умолчанию 20 |

### GET /negotiations/{id} — Просмотр отклика или приглашения

URL берётся из `items[].url` списка откликов.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `id` | path | string | да | Идентификатор отклика |

### PUT /negotiations/{collection_name}/{nid} — Действие с откликом

Меняет работодательское (`employer_state`) или соискательское (`state`) состояние: отложить, пригласить на интервью, отказать. Доступные действия и их URL — в `actions[]` списка откликов; аргументы из `actions[].arguments` передаются как `application/x-www-form-urlencoded`. Успех — `204`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `collection_name` | path | string | да | Коллекция из collections[].id |
| `nid` | path | string | да | Идентификатор отклика |

### GET /common/chats — Список чатов

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `page` | query | integer | нет | Страница, 0–50 |
| `per_page` | query | integer | нет | Чатов на странице, 1–20 (по умолчанию 20) |
| `filter_unread` | query | boolean | нет | Только непрочитанные |
| `filter_has_text_message` | query | boolean | нет | Только с активной перепиской (для работодателя) |
| `vacancy_status` | query | string | нет | all (по умолчанию), with, without |
| `filter_with_vacancy_ids` | query | string | нет | Список ID вакансий, например [1,2,3] (до 100) |

### GET /common/chats/{chat_id}/messages — Сообщения чата

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `chat_id` | path | string | да | Идентификатор чата |
| `start_message_id` | query | string | нет | С какого сообщения выбирать |
| `limit` | query | integer | нет | 1–50, по умолчанию 10 |
| `order` | query | string | нет | next (по умолчанию) или prev |

### POST /common/chats/{chat_id}/messages — Отправка сообщения в чат

Вместе с ключом идемпотентности передаётся либо текст, либо ID загруженных файлов. Успех — `201`; `409` — повтор `idempotency_key`.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `chat_id` | path | string | да | Идентификатор чата |
| `idempotency_key` | body | string | да | Уникальный ключ сообщения (UUID) |
| `text` | body | string | нет | Текст сообщения |
| `file_upload_ids` | body | array | нет | upload_id загруженного файла (1 элемент) |

Пример запроса:

```
{
"idempotency_key": "8abcdef8-4abc-4edf-1234-1234567890ab",
"text": "Cъешь же ещё этих мягких французских булок, да выпей чаю"
}
```

### GET /employers — Поиск работодателей

Глубина выдачи — не больше 5000.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `text` | query | string | нет | Поиск по названию и описанию |
| `area` | query | string | нет | Регион; можно несколько |
| `type` | query | string | нет | Тип из employer_type; можно несколько |
| `only_with_vacancies` | query | boolean | нет | Только с открытыми вакансиями |
| `sort_by` | query | string | нет | by_name (по умолчанию) или by_vacancies_open |
| `page` | query | number | нет | Номер страницы, с 0 |
| `per_page` | query | number | нет | По умолчанию 20, максимум 100 |

### GET /employers/{employer_id} — Информация о работодателе

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `employer_id` | path | string | да | Идентификатор работодателя |

### GET /dictionaries — Справочники полей

Значения справочников могут меняться в любой момент.

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `locale` | query | string | нет | Локаль, по умолчанию RU |

### GET /areas — Дерево регионов

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `additional_case` | query | string | нет | prepositional — название в предложном падеже (только для русской локали) |

### GET /professional_roles — Справочник профессиональных ролей

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `locale` | query | string | нет | Локаль |

### POST /webhook/subscriptions — Подписка на уведомления

Успех — `201`, в ответе `id` подписки. Только для работодателя.

Пример колбэка:

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `actions` | body | array | да | Список событий |
| `url` | body | string | да | URL для POST-уведомлений |

Пример запроса:

```
{
"action_type": "string",
"id": "string",
"payload": {
"chat_id": "string",
"employer_id": "string",
"negotiation_date": "string",
"resume_id": "string",
"topic_id": "string",
"vacancy_id": "string"
},
"subscription_id": "string",
"user_id": "string"
}
```

### GET /webhook/subscriptions — Список подписок

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `HH-User-Agent` | header | string | да | Название приложения и почта разработчика |

### DELETE /webhook/subscriptions/{subscription_id} — Удаление подписки

| Параметр | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
| `subscription_id` | path | string | да | Идентификатор подписки |

## Нюансы

- Пагинация: `page=N&per_page=M`, нумерация с нуля; ответ — `found`, `per_page`, `pages`, `page`, `items`.
- Неизвестные и недокументированные параметры игнорируются; недокументированные поля в ответах не рекомендуется использовать.
- Длинные ответы сжимаются gzip.
- Поддерживается CORS; для отладки есть `/cors` (HEAD, GET, POST, PUT, DELETE), для JSONP — `?callback=callback_name`.
- Вебхуки: на одно приложение — один URL. Ваш сервер отвечает `2xx` или `409` для дубликата (определяется по `id`). Без ответа за 5 секунд колбэк отправляется повторно; доставка не гарантирована. При долгих сбоях подписка блокируется, при отзыве доступа удаляется.
- Методы `/negotiations/{nid}/messages` устарели — переписка ведётся через `/common/chats`.
- Просмотр резюме с контактами списывает контакт один раз на компанию; если контакты скрыты соискателем, просмотр всё равно спишется — проверяйте `hidden_fields`.

## Ошибки

| Код | Описание |
|---|---|
| `400` | Ошибка в параметрах запроса; нет заголовка User-Agent/HH-User-Agent |
| `403` | Ошибка авторизации, нет прав или требуется капча |
| `404` | Объект не найден или недоступен |
| `409` | Конфликт (например, повтор idempotency_key) |
| `429` | Слишком много запросов или превышен дневной лимит просмотра резюме |
| `500` | Внутренняя ошибка |
| `503` | Сбой сервиса |

## Ограничения

- Глубина выдачи поиска вакансий и резюме — 2000 элементов, работодателей — 5000.
- `per_page` не больше 100 для поиска.
- Токен приложения — не чаще раза в 5 минут.
- Дневной лимит просмотра резюме из поиска — проверяется методом `GET /employers/{employer_id}/managers/{manager_id}/limits/resume`.

## Источники

- [HeadHunter API — документация OpenAPI](https://api.hh.ru/openapi/redoc)

---

Если этого недостаточно — официальная документация: https://api.hh.ru/openapi/redoc
JSON: https://mcp-everything.ru/api/integrations/hh-api. MCP: https://mcp-everything.ru/mcp
