# Turkey Jobs Aggregator – Kariyer, SecretCV, Isbul, Eleman.net (`openharvest/turkey-jobs-aggregator`) Actor

Turkish job postings from SecretCV, Isbul.net, Eleman.net and Kariyer.net (best-effort) in one deduplicated feed with English keys: title, company, city, district, remote/hybrid, salary, dates and description. Filter by city, keyword and posting date.

- **URL**: https://apify.com/openharvest/turkey-jobs-aggregator.md
- **Developed by:** [Enes Bulanık](https://apify.com/openharvest) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 job postings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Turkey Jobs Aggregator – Kariyer, SecretCV, Isbul, Eleman.net

Collects Turkish job postings from **SecretCV.com, Isbul.net, Eleman.net and Kariyer.net** into one deduplicated dataset with English field names: title, company, city, district, work model (on-site / remote / hybrid), employment type, salary, dates and the full description. Use it instead of separate single-site scrapers when you need **one normalized feed of the Turkish job market** filtered by city, keyword and posting date.

**Price: $1.00 per 1,000 jobs.** Failed boards, unknown cities and "no results" rows are free.

### What data do you get?

One row per job posting with the same keys on every board:

- **Job** – title, standardized position (`occupation`), seniority (`positionLevel`), department, sector
- **Company** – name, profile URL and logo
- **Location** – `city` (il), `district` (ilçe) and the location text as published
- **Work model** – `onsite`, `remote` or `hybrid`, plus the original Turkish label (İş Yerinde, Uzaktan, Hibrit)
- **Employment type** – `FULL_TIME`, `PART_TIME`, `INTERN`, `CONTRACTOR` or `TEMPORARY`, plus the original label
- **Salary** – min / max / currency / period when published. Isbul.net market estimates are marked with `salaryIsEstimate: true`
- **Requirements** – experience, education, number of openings, benefits (yemek, servis, özel sağlık sigortası...)
- **Dates** – posted, updated and application deadline (`validThrough`)
- **Description** – full plain text. **Phone numbers, e-mail addresses and recruiter names are always removed.**
- **Source** – board, job ID, URL and a `dedupeKey` (company | title | city)

The same job is often posted on several boards. Within a run the Actor keeps the first copy and skips the others (you are not charged for skipped duplicates).

#### Boards covered

| Board | How it is read | Fields |
|---|---|---|
| **Isbul.net** | Isbul's official public job API for AI agents + the public job page | All fields incl. work model, salary, level, department |
| **Eleman.net** | Public listing pages (all pages) + job pages (schema.org JobPosting) | Title, company, city/district, salary, experience, education, benefits, description |
| **SecretCV.com** | Public city, district, position and job-type landing pages + job pages | Title, company, city, sector, education, openings, description |
| **Kariyer.net** (best-effort) | First public listing page (and the city page) | Title, company, city, work model, employment type, position, sector, approximate date. No description |

Kariyer.net sometimes shows a bot check. When that happens you get a free `error` row for Kariyer.net and the other boards still deliver. For deep Kariyer.net-only crawls, a dedicated Kariyer actor is the better choice; this Actor is for the **multi-board** view.

### Use cases

- **HR-tech and job-board startups** – seed or enrich a Turkish job database from several boards at once.
- **Recruiters and staffing agencies** – see which companies are hiring for a role in a city today.
- **Labor-market research** – track demand, remote share and published salaries by city, sector and position.
- **Sales prospecting (B2B)** – list the companies hiring in a sector and city.
- **Daily job alerts** – schedule the Actor with `postedWithinDays: 1` and send new postings to Slack, Sheets or e-mail.

### How to use

1. Click **Try for free**.
2. Pick the **job boards** (all four by default).
3. Optionally enter a **city** (`istanbul`, `ankara`, `izmir`, `bursa`... Turkish letters are fine), a **keyword** (`muhasebe`, `yazılım`, `satış temsilcisi`) and **posted within (days)**.
4. Set **Max jobs** and click **Start**. Download the data as JSON, CSV, Excel or HTML, or use the API and integrations (Make, Zapier, n8n, Google Sheets, webhooks).

### Input

| Field | Type | Description |
|---|---|---|
| `sources` | array | Boards: `secretcv`, `isbul`, `eleman`, `kariyer`. Default: all four. |
| `city` | string | Optional city (il), e.g. `istanbul`, `ankara`, `izmir`. Empty = all of Turkey. |
| `keyword` | string | Optional. Only jobs whose title or standardized position contains all words. Accent-insensitive (`satis` = `satış`). |
| `maxItems` | integer | Maximum jobs in total, split evenly across the selected boards. Default `50`. |
| `postedWithinDays` | integer | Optional. Skip postings older than N days. |
| `includeDescription` | boolean | Include the full description (default `true`). |
| `proxyConfiguration` | object | Optional. Not needed in normal use. |

Example input:

```json
{
    "sources": ["secretcv", "isbul", "eleman", "kariyer"],
    "city": "ankara",
    "keyword": "muhasebe",
    "maxItems": 100,
    "postedWithinDays": 30
}
```

### Output

Real sample from a run on 2026-10-08 (description shortened):

```json
{
    "type": "job",
    "source": "isbul",
    "sourceName": "Isbul.net",
    "jobId": "b3f2c91b-4279-4042-8f61-4cb5ae0f4e4c",
    "url": "https://www.isbul.net/is-ilani/azunlar-aksesuar-muhasebe-elemani-100371",
    "title": "Muhasebe elemanı",
    "company": "AZUNLAR AKSESUAR",
    "companyUrl": "https://www.isbul.net/firma/azunlar-aksesuar",
    "city": "Ankara",
    "district": "Çankaya",
    "location": "Ankara - Çankaya",
    "country": "TR",
    "workModel": "onsite",
    "workModelRaw": "İş Yerinde",
    "employmentType": "FULL_TIME",
    "employmentTypeRaw": "Tam Zamanlı",
    "positionLevel": "Yeni Mezun",
    "occupation": "Ön Muhasebe",
    "sector": "Telekomünikasyon",
    "department": "Finans",
    "education": "high school",
    "salaryMin": 25000,
    "salaryMax": 80000,
    "salaryCurrency": "TRY",
    "salaryPeriod": "MONTH",
    "salaryIsEstimate": true,
    "benefits": "Yemek",
    "datePosted": "2026-10-06T13:06:57.000Z",
    "validThrough": "2026-12-05T13:06:57.000Z",
    "description": "MUHASEBE ELEMANI alınacaktır.\nAzunlar Aksesuar bünyesinde görevlendirilmek üzere, Logo programını bilen ...",
    "detailsEnriched": true,
    "dedupeKey": "azunlar-aksesuar|muhasebe-elemani|ankara",
    "scrapedAt": "2026-10-08T18:51:04.677Z"
}
```

A Kariyer.net row (listing card, no description):

```json
{
    "type": "job",
    "source": "kariyer",
    "sourceName": "Kariyer.net",
    "jobId": "4574371",
    "url": "https://www.kariyer.net/is-ilani/deha-harita-insaat-teknik-cihazlar-ve-muhendislik-on-muhasebe-elemani-4574371",
    "title": "Ön Muhasebe Elemanı",
    "company": "DEHA HARİTA İNŞAAT TEKNİK CİHAZLAR VE MÜHENDİSLİK HİZMETLERİ TİCARET LİMİTED ŞİRKETİ",
    "city": "Ankara",
    "workModel": "onsite",
    "employmentType": "FULL_TIME",
    "occupation": "Ön Muhasebe Elemanı",
    "sector": "Harita - Planlama",
    "datePosted": "2026-10-08T14:51:04.203Z",
    "detailsEnriched": false
}
```

The Kariyer.net sample above is shortened; every row has all keys and missing values are `null`. Error rows (free) look like this:

```json
{
    "type": "error",
    "source": "kariyer",
    "sourceName": "Kariyer.net",
    "errorCode": "SOURCE_BLOCKED",
    "error": "Kariyer.net returned HTTP 403 with no job cards. Kariyer.net support is best-effort (first listing page only). You were not charged."
}
```

Possible `errorCode` values: `CITY_NOT_FOUND`, `LISTING_FAILED`, `SOURCE_BLOCKED`, `SOURCE_FAILED`, `NO_RESULTS`.

The dataset has three views in Apify Console: **Overview**, **Details** and **Errors (free)**. A `RUN_SUMMARY` record in the key-value store shows per-board counts and skipped duplicates.

### Pricing

Pay per event – you only pay for job postings saved to the dataset.

| Event | Price | When |
|---|---|---|
| `job` | **$0.001** per job ($1.00 / 1,000) | Each job posting saved |
| Errors, duplicates, "no results" | **Free** | Not charged |

| Job | Cost |
|---|---|
| 50 latest jobs from 4 boards | **$0.05** |
| 1,000 jobs | **$1.00** |
| Daily alert, ~200 new jobs/day for a month | **~$6** |

Set **Max cost per run** in the run options – the Actor stops cleanly at your budget.

### Use with AI agents (MCP)

This Actor works as a tool for AI agents through the Apify MCP server (`https://mcp.apify.com/?actors=openharvest/turkey-jobs-aggregator`) in Claude, ChatGPT, Cursor or n8n. The input is small and typed and the output is flat JSON. Example tool input:

```json
{
    "city": "istanbul",
    "keyword": "yazılım",
    "postedWithinDays": 7,
    "maxItems": 40
}
```

Typical prompts: *"Which companies posted accounting jobs in Ankara this week, and what salaries do they offer?"*, *"What share of new sales jobs in İzmir are remote or hybrid?"*

### FAQ

**Why not Yenibiris.com?**
Yenibiris blocks requests from cloud servers, so it cannot be scraped reliably from Apify. We only ship boards that work.

**Why is the keyword not sent to the boards' search?**
The boards' `robots.txt` files disallow their search URLs (`?k=`, `?q=`, `?query=`, `?t=`). The Actor respects that: it reads public listing, city and position pages and filters locally (Isbul.net offers an official agent API that supports keywords). A rare keyword in a small city can therefore return few jobs.

**How many jobs can I get?**
Eleman.net and Isbul.net have thousands / hundreds of active postings and are paginated. SecretCV.com is read through its landing pages (about 20 jobs each). Kariyer.net gives up to ~50 jobs per run (first page).

**Which jobs are these boards strongest in?**
Eleman.net, Isbul.net and SecretCV.com are strongest in retail, sales, accounting, customer service, hospitality, logistics, production and other blue-collar and mid-level office roles – the Turkish SME market. Software and senior corporate roles are rarer there; a keyword such as `yazılım` may return only a few rows (mostly from Kariyer.net).

**Are salaries real?**
`salaryMin`/`salaryMax` come from the employer when published. Isbul.net also publishes its own market estimate for many jobs; those rows have `salaryIsEstimate: true`.

**Why do I see another city when I filter by city?**
Some postings cover several cities ("Aydın, Balıkesir, İzmir, ...") or all of Turkey. The board lists them on your city's page, so they are included. `city` holds the first city the posting names (or `null` for nationwide postings), and `location` holds the full text.

**Is the date exact?**
Yes for SecretCV, Isbul and Eleman. Kariyer.net only shows "3 saat", "2 gün" on its cards, so its `datePosted` is approximate.

**Can I run it every day?**
Yes. Create a schedule with `postedWithinDays: 1` and connect the dataset to Google Sheets, Slack or a webhook.

### Is it legal?

The Actor only reads job postings that companies publish for the public and for search engines. It does not log in, does not collect candidate data and removes recruiters' names, phone numbers and e-mail addresses from descriptions. It follows the boards' `robots.txt` (no search URLs, no disallowed pagination) and crawls politely. You are responsible for using the data in line with KVKK/GDPR and the boards' terms – do not use it for spam or unsolicited messages.

### Related actors by the same developer

- **Greenhouse, Lever, Ashby & Workday Jobs Scraper – 10 ATS** – jobs straight from company career pages.
- **MyJobMag, Jobberman, BrighterMonday & Careers24 Jobs Scraper** – African job boards in one feed.
- **TED, SAM.gov, UK & Brazil Tenders Scraper – Public Procurement** – public tenders for B2B prospecting.
- **GLEIF LEI Lookup – Legal Entity Identifier & Parent Companies** – verify the companies behind the postings.

### Support

Found a bug or a missing field? Open an issue in the **Issues** tab. Feature requests (new Turkish boards, more fields) are welcome.

# Actor input Schema

## `sources` (type: `array`):

Turkish job boards to collect from. The limit below is split evenly between them. Kariyer.net is best-effort: only its first listing page is read, and it sometimes shows a bot check.

## `city` (type: `string`):

Optional Turkish city, e.g. "istanbul", "ankara", "izmir", "bursa", "kocaeli". Turkish letters are fine ("İzmir"). Leave empty for all of Turkey.

## `keyword` (type: `string`):

Optional. Only jobs whose title or standardized position contains all words, e.g. "muhasebe", "yazılım", "satış temsilcisi". Matching ignores Turkish accents. Boards' own search pages are blocked by robots.txt, so the keyword filters listing pages; a rare keyword returns fewer jobs.

## `maxItems` (type: `integer`):

Maximum number of job postings in total (split evenly across the selected boards). You pay only for jobs saved.

## `postedWithinDays` (type: `integer`):

Optional. Skip postings older than this many days (e.g. 1 for today's jobs, 7 for the last week).

## `includeDescription` (type: `boolean`):

Include the full description text. Phone numbers, e-mails and recruiter names are always removed.

## `proxyConfiguration` (type: `object`):

Optional. Not needed in normal use.

## Actor input object example

```json
{
  "sources": [
    "secretcv",
    "isbul",
    "eleman",
    "kariyer"
  ],
  "city": "istanbul",
  "keyword": "muhasebe",
  "maxItems": 40,
  "postedWithinDays": 7,
  "includeDescription": true
}
```

# Actor output Schema

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

All job postings (and free error rows) in the default dataset (JSON, CSV, Excel and more via the dataset export).

## `files` (type: `string`):

Records saved in the default key-value store, e.g. RUN_SUMMARY with per-board counts.

# 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 = {
    "sources": [
        "secretcv",
        "isbul",
        "eleman",
        "kariyer"
    ],
    "maxItems": 40
};

// Run the Actor and wait for it to finish
const run = await client.actor("openharvest/turkey-jobs-aggregator").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 = {
    "sources": [
        "secretcv",
        "isbul",
        "eleman",
        "kariyer",
    ],
    "maxItems": 40,
}

# Run the Actor and wait for it to finish
run = client.actor("openharvest/turkey-jobs-aggregator").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "sources": [
    "secretcv",
    "isbul",
    "eleman",
    "kariyer"
  ],
  "maxItems": 40
}' |
apify call openharvest/turkey-jobs-aggregator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,openharvest/turkey-jobs-aggregator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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