{
  "openapi": "3.0.1",
  "info": {
    "title": "HeadHunter RU $1💰 URL | Filters | Enriched Job Data",
    "description": "From $1/1K. Scrape hh.ru job listings with 50+ fields including salary, experience, schedule, employment, and role. Search by filters or use URLs. Detail enrichment adds full descriptions, key skills, contact info, and employer logos.",
    "version": "1.0",
    "x-build-id": "y7UKKny6q07pjZsf6"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~hh-ru-jobs-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-hh-ru-jobs-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/abotapi~hh-ru-jobs-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-hh-ru-jobs-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/abotapi~hh-ru-jobs-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-hh-ru-jobs-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "1. Search mode",
            "enum": [
              "search",
              "url",
              "vacancy"
            ],
            "type": "string",
            "description": "Search mode = type your keywords + area + filters and let the scraper build URLs. URL mode = paste any hh.ru search URL already refined in a browser (recommended for complex filters or saved searches). Vacancy mode = paste a list of specific vacancy URLs or IDs and get the full detail card for each (no search performed).",
            "default": "search"
          },
          "queries": {
            "title": "Search keywords (Search mode)",
            "type": "array",
            "description": "One or more keywords. Each keyword runs as a separate search. Examples: 'python', 'AI engineer', 'data scientist', 'Java middle'. Russian keywords are fine.",
            "items": {
              "type": "string"
            }
          },
          "searchField": {
            "title": "Where to match the keyword (Search mode)",
            "enum": [
              "name",
              "everywhere",
              "company_name",
              "description"
            ],
            "type": "string",
            "description": "Controls WHERE hh.ru looks for your keyword. Vacancy title only (default) returns the roles whose TITLE matches your keyword — the relevant results you expect when you search by job title. Everywhere is hh.ru's own default: it matches the keyword anywhere in the vacancy (title, description, or company) and mixes in loosely-related roles, so a search for 'Продуктовый аналитик' also returns marketing directors and sales managers — switch to it only if you deliberately want that broad reach. 'Company name' and 'Description' restrict the match to those fields.",
            "default": "name"
          },
          "areas": {
            "title": "Areas / regions to search (Search mode, optional)",
            "type": "array",
            "description": "Optional. One or more hh.ru area IDs. Leave empty to search all of Russia (defaults to 113 = whole country). Common values: 1=Moscow, 2=Saint Petersburg, 113=Russia (whole country), 4=Novosibirsk, 88=Kazan, 1438=Yekaterinburg, 5=Krasnodar, 76=Rostov-on-Don, 78=Voronezh, 66=Nizhny Novgorod. Full list: https://api.hh.ru/areas",
            "default": [
              "113"
            ],
            "items": {
              "type": "string"
            }
          },
          "experience": {
            "title": "Work experience (Search mode)",
            "enum": [
              "any",
              "noExperience",
              "between1And3",
              "between3And6",
              "moreThan6"
            ],
            "type": "string",
            "description": "Filter candidates by required experience.",
            "default": "any"
          },
          "employment": {
            "title": "Employment type (Search mode)",
            "type": "array",
            "description": "Multi-select. Leave empty to get all types.",
            "items": {
              "type": "string",
              "enum": [
                "full",
                "part",
                "project",
                "volunteer",
                "probation"
              ],
              "enumTitles": [
                "Full-time",
                "Part-time",
                "Project / contract",
                "Volunteer",
                "Probation"
              ]
            }
          },
          "schedule": {
            "title": "Work schedule (Search mode)",
            "type": "array",
            "description": "Multi-select. Leave empty for all schedules.",
            "items": {
              "type": "string",
              "enum": [
                "fullDay",
                "shift",
                "flexible",
                "remote",
                "flyInFlyOut"
              ],
              "enumTitles": [
                "Full day",
                "Shift",
                "Flexible",
                "Remote",
                "Fly-in / fly-out"
              ]
            }
          },
          "salaryMin": {
            "title": "Minimum salary (Search mode)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum monthly salary in RUB. Listings without a salary are still returned unless you also enable 'Only with salary'."
          },
          "onlyWithSalary": {
            "title": "Only listings with salary (Search mode)",
            "type": "boolean",
            "description": "If on, only listings that publish a salary range are returned.",
            "default": false
          },
          "orderBy": {
            "title": "Sort order (Search mode)",
            "enum": [
              "relevance",
              "publication_time",
              "salary_desc",
              "salary_asc",
              "distance"
            ],
            "type": "string",
            "description": "How to order results. Default = relevance (hh.ru's own default).",
            "default": "relevance"
          },
          "professionalRole": {
            "title": "Professional role IDs (Search mode)",
            "type": "array",
            "description": "Optional. Numeric professional role IDs to filter by. Examples: 96=Programmer/Developer, 156=Software engineer, 165=Data Analyst, 10=Project Manager. Full taxonomy: https://api.hh.ru/professional_roles",
            "items": {
              "type": "string"
            }
          },
          "industry": {
            "title": "Industry IDs (Search mode)",
            "type": "array",
            "description": "Optional. Numeric industry IDs. Examples: 7=IT/Telecom, 9=Marketing/PR, 29=Finance. Full taxonomy: https://api.hh.ru/industries",
            "items": {
              "type": "string"
            }
          },
          "urls": {
            "title": "Search URLs (URL mode)",
            "type": "array",
            "description": "One or more full hh.ru search URLs. Tip: open hh.ru in your browser, pick keywords + area + filters, then paste the resulting URL here. Pagination starts at page in URL and walks forward.",
            "items": {
              "type": "string"
            }
          },
          "vacancyInput": {
            "title": "Vacancy URLs or IDs (Vacancy mode)",
            "type": "array",
            "description": "One entry per vacancy you want a full detail card for. Accepts full URLs (https://hh.ru/vacancy/123456789), mobile URLs (https://m.hh.ru/vacancy/123456789), or bare numeric IDs (123456789). Each entry fetches that vacancy's page directly — no search runs, so hh.ru's 2000-result cap does not apply. Duplicate IDs are removed. Removed or archived vacancies are omitted from the dataset (never charged); each skipped ID is named in the run log and summarised in the run status message.",
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 1,
            "maximum": 40,
            "type": "integer",
            "description": "How many result pages to walk per query / URL (Search and URL modes only; ignored in Vacancy mode). hh.ru returns 50 listings per page, so 2 pages ≈ 100 listings. Maximum is 40 pages — hh.ru's own hard cap is 2000 results per filter, so any single search beyond ~2000 matches must be split into narrower slices (by area, salary band, or role) to capture the rest. The run logs a warning when a search exceeds what's reachable.",
            "default": 2
          },
          "maxListings": {
            "title": "Max total listings",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap across the whole run. 0 = unlimited (bounded only by Max pages).",
            "default": 0
          },
          "fetchDetails": {
            "title": "Visit each listing's detail page",
            "type": "boolean",
            "description": "Adds the most valuable fields: full HTML description + plain-text version, keySkills array, employer logos, validThroughTime, hr-brand status, work format details, and metro station list. Turn off for a faster run with just the SERP-level fields. Note on contact info: hh.ru hides phone / email / advertiser name behind a login wall, so contactInfo.phones / .email / .name will be empty for non-authenticated scrapes. The actor returns contactInfo.contactsHidden=true for those listings. Some employers paste their contact details into the descriptionText (search the description if you need it).",
            "default": true
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a large pull without returning or charging for vacancies already collected there. Use this after an interrupted run, or to keep extending one walk-all pull across separate runs. For recurring daily monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns all matching vacancies as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED vacancies. Turn on \"Emit unchanged\" or \"Emit expired\" only when you also want those vacancies returned (and billed). State is kept separately per mode + search/URL/vacancy-list configuration; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the mode + search/URL/vacancy settings — different searches then never mix state with each other."
          },
          "emitUnchanged": {
            "title": "Emit unchanged vacancies (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return vacancies that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired vacancies (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return vacancies that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search — not when Max listings capped it or when Resume was used. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Default = Apify Proxy (datacenter). hh.ru works fine on the free tier. For higher reliability or geo-pinned views, switch to Residential RU."
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}