# Hh Uz Scraper (`unfenced-group/hh-uz-scraper`) Actor

Scrape hh.uz for structured Uzbekistan job listings with salary, location, skills, and full descriptions. No API key needed.

- **URL**: https://apify.com/unfenced-group/hh-uz-scraper.md
- **Developed by:** [Unfenced Group](https://apify.com/unfenced-group) (community)
- **Categories:** Jobs
- **Stats:** 3 total users, 2 monthly users, 97.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 1,000 job listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## HH.UZ Scraper — Uzbekistan Jobs

![Banner](https://api.apify.com/v2/key-value-stores/lJlifu6C8YQfZMPKE/records/hh-uz-scraper.png)

Extract structured job listings from [hh.uz](https://hh.uz) — Uzbekistan's largest job board with tens of thousands of active vacancies. Returns up to 2,000 results per run across all cities and industries. No API key required.

***

### Why this scraper?

#### 📋 26 structured fields per vacancy

Vacancy ID, title, employer name and ID, city, salary range with currency and gross/net flag, experience level, employment type, work schedule, work format, key skills, full description in HTML/text/Markdown, publication date, and more.

#### 💰 Salary in Uzbekistani som (UZS) and major currencies

Captures salary minimum, maximum, currency (UZS, USD, EUR, RUB), gross/net indicator, and payment frequency (monthly, bi-weekly, weekly).

#### 🔍 Powerful filtering

Filter by keyword, city/region, experience level, employment type, work schedule (including remote), salary presence, and date range. Combine filters freely.

#### 📄 Full job descriptions

Enable `fetchDetails` to retrieve the complete vacancy text in HTML, plain text, and Markdown — plus key skills, exact street address, work format details, and application deadline.

#### 🔄 Repost detection

Enable `skipReposts` to deduplicate across runs. The scraper remembers every vacancy ID for 90 days and skips anything already seen — ideal for daily feeds.

#### 🎯 Direct URL mode

Supply a list of hh.uz vacancy URLs via `startUrls` to scrape specific postings directly, bypassing search entirely.

***

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQuery` | string | `""` | Keywords to search (job title, skill, etc.). Empty = all vacancies. |
| `areaId` | string | `"97"` | Area code. `97` = all of Uzbekistan. Use city codes for narrower results (e.g. `2603` = Tashkent). |
| `experience` | select | `""` | Experience level: `noExperience`, `between1And3`, `between3And6`, `moreThan6`. |
| `employment` | select | `""` | Employment type: `full`, `part`, `project`, `volunteer`, `probation`. |
| `schedule` | select | `""` | Work schedule: `fullDay`, `shift`, `flexible`, `remote`, `flyInFlyOut`. |
| `workFormat` | select | `""` | Work format: `onsite`, `remote`, `hybrid`. |
| `onlyWithSalary` | boolean | `false` | Return only vacancies with a published salary range. |
| `orderBy` | select | `""` | Sort order: `relevance`, `publication_time`, `salary_desc`, `salary_asc`. |
| `fetchDetails` | boolean | `false` | Fetch full description and all structured fields from each vacancy page. |
| `skipReposts` | boolean | `false` | Skip vacancies already seen in previous runs (90-day memory). |
| `maxResults` | integer | `5` | Maximum results to return. `0` = unlimited (platform cap: 2,000). |
| `daysOld` | integer | — | Only return vacancies posted within this many days. |
| `dateFrom` | string | `""` | Return vacancies posted on or after this date (YYYY-MM-DD). |
| `dateTo` | string | `""` | Return vacancies posted on or before this date (YYYY-MM-DD). |
| `startUrls` | array | `[]` | Specific hh.uz vacancy URLs to scrape directly. Bypasses search. |

***

### Output schema

#### Always present

| Field | Type | Description |
|-------|------|-------------|
| `vacancyId` | string | Unique hh.uz vacancy identifier. |
| `title` | string | Job title as listed by the employer. |
| `url` | string | Direct URL to the vacancy on hh.uz. |
| `employerName` | string|null | Employer or company name. |
| `employerLogoUrl` | string|null | URL to employer logo thumbnail. |
| `isTrusted` | boolean | Whether the employer has a trusted employer badge. |
| `city` | string|null | City extracted from the location field. |
| `country` | string | Always `"UZ"`. |
| `locationRaw` | string|null | Raw location text (e.g. `"Ташкент, улица Кирк-Киз, 10"`). |
| `salaryFrom` | number|null | Minimum salary (null if not published by employer). |
| `salaryTo` | number|null | Maximum salary (null if not published by employer). |
| `salaryCurrency` | string|null | Salary currency: `UZS`, `USD`, `EUR`, `RUB`, or null. |
| `salaryGross` | boolean|null | `true` = gross (before tax), `false` = net, `null` = unspecified. |
| `salaryRaw` | string|null | Raw salary string as displayed (e.g. `"от 8 000 000 до 13 000 000 so'm"`). |
| `salaryFrequency` | string|null | Payment frequency: `MONTHLY`, `TWICE_PER_MONTH`, `WEEKLY`, or null. |
| `experienceBadge` | string|null | Experience badge from listing: `noExperience`, `between1And3`, `between3And6`, `moreThan6`. |
| `isRemote` | boolean | Whether the vacancy is remote-eligible (from listing label or work format). |
| `isRepost` | boolean | `true` if this vacancy was seen in a previous run (requires `skipReposts: true`). |
| `originalPublishDate` | string|null | First publication date if repost; null otherwise. |
| `originalUrl` | string|null | Original vacancy URL if repost; null otherwise. |
| `source` | string | Always `"hh.uz"`. |
| `scrapedAt` | string | ISO 8601 timestamp of when this record was scraped. |
| `contentHash` | string | MD5 fingerprint of vacancy ID + title for change detection. |

#### With `fetchDetails: true`

| Field | Type | Description |
|-------|------|-------------|
| `employerId` | string|null | hh.uz internal employer ID. |
| `publishedAt` | string|null | Publication datetime ISO 8601. |
| `publishDate` | string|null | Publication date YYYY-MM-DD. |
| `validThrough` | string|null | Application deadline ISO 8601. |
| `streetAddress` | string|null | Full street address of the workplace. |
| `addressLocality` | string|null | City from the structured address schema. |
| `addressCountry` | string | Country code from structured address (usually `"UZ"`). |
| `experienceRaw` | string|null | Experience requirement as displayed (e.g. `"1–3 года"`). |
| `employmentRaw` | string|null | Employment type as displayed (e.g. `"Полная занятость"`). |
| `scheduleRaw` | string|null | Work schedule as displayed (e.g. `"График: 5/2"`). |
| `workFormatRaw` | string|null | Work format as displayed (e.g. `"на месте работодателя"`). |
| `hiringFormatRaw` | string|null | Hiring format details from vacancy page. |
| `workingHours` | string|null | Daily working hours (e.g. `"8"`). |
| `applicantLocReq` | array | Countries eligible to apply (e.g. `["Узбекистан"]`). |
| `descriptionHtml` | string|null | Full job description in raw HTML. |
| `descriptionText` | string|null | Full job description as plain text. |
| `descriptionMarkdown` | string|null | Full job description in Markdown. |
| `keySkills` | array | List of required skills (e.g. `["Python", "Django", "PostgreSQL"]`). |

#### JSON example

```json
{
  "vacancyId": "134750046",
  "title": "Middle Back-end разработчик",
  "url": "https://hh.uz/vacancy/134750046",
  "employerName": "OOO UZGPS",
  "employerId": "8820311",
  "employerLogoUrl": "https://img.hhcdn.ru/employer-logo/8820311.png",
  "isTrusted": false,
  "city": "Ташкент",
  "country": "UZ",
  "locationRaw": "Ташкент, улица Кирк-Киз, 10",
  "streetAddress": "улица Кирк-Киз, 10",
  "addressLocality": "Ташкент",
  "addressCountry": "UZ",
  "salaryFrom": 8000000,
  "salaryTo": 13000000,
  "salaryCurrency": "UZS",
  "salaryGross": true,
  "salaryRaw": "от 8 000 000 до 13 000 000 so'm за месяц до вычета налогов",
  "salaryFrequency": "MONTHLY",
  "experienceBadge": "between1And3",
  "experienceRaw": "1–3 года",
  "employmentRaw": "Полная занятость",
  "scheduleRaw": "График: 5/2",
  "workFormatRaw": "на месте работодателя",
  "hiringFormatRaw": null,
  "workingHours": "8",
  "isRemote": false,
  "applicantLocReq": ["Узбекистан"],
  "publishedAt": "2026-07-01T13:13:07.200+03:00",
  "validThrough": "2026-07-31T13:13:07.219+03:00",
  "publishDate": "2026-07-01",
  "descriptionHtml": "<strong>Обязанности:</strong><ul><li>Проектирование и разработка API...</li></ul>",
  "descriptionText": "Обязанности: Проектирование и разработка API...",
  "descriptionMarkdown": "**Обязанности:**\n\n- Проектирование и разработка API...",
  "keySkills": ["Python", "Django", "PostgreSQL", "Docker", "REST API"],
  "isRepost": false,
  "originalPublishDate": null,
  "originalUrl": null,
  "source": "hh.uz",
  "scrapedAt": "2026-07-01T14:22:00.000Z",
  "contentHash": "a3f9d12e4c7b8e91"
}
```

***

### Examples

**Search for IT vacancies in Tashkent:**

```json
{
  "searchQuery": "разработчик",
  "areaId": "2603",
  "fetchDetails": true,
  "maxResults": 100
}
```

**Remote jobs with salary, sorted by pay:**

```json
{
  "schedule": "remote",
  "onlyWithSalary": true,
  "orderBy": "salary_desc",
  "fetchDetails": true,
  "maxResults": 50
}
```

**Scrape specific vacancies by URL:**

```json
{
  "startUrls": [
    { "url": "https://hh.uz/vacancy/134750046" },
    { "url": "https://hh.uz/vacancy/134663723" }
  ],
  "fetchDetails": true
}
```

**Daily feed — new postings only, no reposts:**

```json
{
  "daysOld": 1,
  "skipReposts": true,
  "fetchDetails": false,
  "maxResults": 0
}
```

***

### 💰 Pricing

**$0.99 per 1,000 results** — you only pay for successfully retrieved listings. Failed retries and filtered reposts are never charged.

| Results | Cost |
|---------|------|
| 100 | ~$0.10 |
| 1,000 | ~$0.99 |
| 10,000 | ~$9.90 |
| 2,000 (max) | ~$1.98 |

> Flat-rate alternatives typically charge $29–$49/month regardless of usage.

Use the **Max results** cap in the input to control your spend exactly.

***

### Performance

| Run size | Estimated time |
|----------|---------------|
| 100 results (list only) | ~30 seconds |
| 500 results (list only) | ~2 minutes |
| 100 results (with fetchDetails) | ~3 minutes |
| 500 results (with fetchDetails) | ~12 minutes |
| 2,000 results (platform max, list only) | ~8 minutes |

***

### Known limitations

- Maximum 2,000 results per search (hh.uz platform limit — 100 pages × 20 results). Use filters or multiple targeted searches to cover broader datasets.
- `publishDate` and full structured fields are only available with `fetchDetails: true`.
- Salary is null when the employer chooses not to disclose it (roughly 40–60% of listings).
- Employer logo URLs may expire or become unavailable over time.

***

### Technical details

- **Source:** hh.uz — Uzbekistan's leading job board (part of the hh.ru network)
- **Memory:** 256 MB
- **Repost storage:** KeyValueStore `hh-uz-scraper-job-dedup`, 90-day TTL
- **Retry:** Automatic retry on network errors and server errors, exponential backoff, 3 attempts per request

***

### Related scrapers

- [HH.KZ Scraper — Kazakhstan Jobs](https://apify.com/unfenced-group/hh-kz-scraper)
- [Headhunter.ru Scraper — Russia Jobs](https://apify.com/unfenced-group/headhunter-ru-scraper)
- [SEEK.com.au Scraper — Australia Jobs](https://apify.com/unfenced-group/seek-com-au-scraper)
- [Naukri.com Scraper — India Jobs](https://apify.com/unfenced-group/naukri-com-scraper)
- [Bayt.com Scraper — Middle East Jobs](https://apify.com/unfenced-group/bayt-scraper)

***

### Need a custom scraper?

**[Unfenced Group](https://www.unfencedgroup.nl)** builds Apify actors for any website — for free.

If the site you need isn't in our portfolio yet, just ask. We scope, build, and publish it at no cost to you. You only pay for results — we absorb the compute and proxy costs ourselves. Same pay-per-result pricing, same quality, same standards as every actor in this portfolio.

**Get in touch:** [www.unfencedgroup.nl](https://www.unfencedgroup.nl)

# Actor input Schema

## `searchQuery` (type: `string`):

Job title, keyword, or skill to search for. Leave empty to return all vacancies in Uzbekistan.

## `areaId` (type: `string`):

Uzbekistan area code. Default: 97 (all of Uzbekistan). Use city-level IDs for targeted results (e.g. 2603 = Tashkent). Full list at api.hh.ru/areas.

## `experience` (type: `string`):

Filter by required experience level. Leave empty for all levels.

## `employment` (type: `string`):

Filter by employment type. Leave empty for all types.

## `schedule` (type: `string`):

Filter by work schedule. Leave empty for all schedules.

## `workFormat` (type: `string`):

Filter by work format. Leave empty for all formats.

## `onlyWithSalary` (type: `boolean`):

Return only vacancies that include a salary range.

## `orderBy` (type: `string`):

Sort results by relevance or publication date.

## `fetchDetails` (type: `boolean`):

Fetch the full job description and all structured fields from each vacancy's detail page. Increases data richness significantly (adds description, key skills, exact salary with gross/net, street address, etc.) at the cost of additional requests.

## `skipReposts` (type: `boolean`):

Skip vacancies already seen in previous runs (90-day memory). Useful for scheduled daily feeds.

## `maxResults` (type: `integer`):

Maximum number of results to return. Set to 0 for unlimited (up to the 2,000 result platform limit).

## `daysOld` (type: `integer`):

Only return vacancies posted within this many days. Leave empty to return all.

## `dateFrom` (type: `string`):

Return only vacancies posted on or after this date. Format: YYYY-MM-DD.

## `dateTo` (type: `string`):

Return only vacancies posted on or before this date. Format: YYYY-MM-DD.

## `startUrls` (type: `array`):

List of specific hh.uz vacancy URLs to scrape directly (e.g. https://hh.uz/vacancy/12345678). Bypasses search when provided.

## Actor input object example

```json
{
  "searchQuery": "developer",
  "areaId": "97",
  "experience": "",
  "employment": "",
  "schedule": "",
  "workFormat": "",
  "onlyWithSalary": false,
  "orderBy": "",
  "fetchDetails": false,
  "skipReposts": false,
  "maxResults": 100,
  "dateFrom": "",
  "dateTo": "",
  "startUrls": []
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQuery": "developer",
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("unfenced-group/hh-uz-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQuery": "developer",
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("unfenced-group/hh-uz-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQuery": "developer",
  "maxResults": 100
}' |
apify call unfenced-group/hh-uz-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=unfenced-group/hh-uz-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/gNpqksGWYH8CRuw1m/builds/x5IwXltV11azwYTLF/openapi.json
