# eJobs.ro Scraper — Romania Job Ads & Company Leads (`logiover/ejobs-ro-scraper`) Actor

Scrape job ads from eJobs.ro, Romania's largest job board: title, hiring company with verified flag and open-position count, cities and counties, industry, department, languages, coordinates and dates. Keyless. JSON, CSV or Excel.

- **URL**: https://apify.com/logiover/ejobs-ro-scraper.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 4 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

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

## eJobs.ro Scraper — Romania Job Ads & Company Leads

Export job ads from **eJobs.ro**, Romania's largest job board — hiring company, cities and counties, industry, department and dates — to JSON, CSV or Excel. Keyless, no login.

### What does eJobs.ro Scraper do?

eJobs.ro answers a public JSON API with no key, no account and no cookie. Roughly **15 000 ads** are live at any time.

Two details decide how this Actor is built. First, the list endpoint stops returning rows past about page 20, so a single query can never reach the whole board — the Actor sweeps the site by replaying every department and industry name as a search term and de-duplicating on job ID. Second, list rows carry taxonomy **IDs**, not names: city `16`, industry `8`. The Actor loads the city, county, industry, department and language reference tables once and resolves them locally, so every row ships readable values instead of raw integers.

Each row identifies the hiring company with its verified badge and its total number of open positions — the signal that separates a one-off vacancy from an employer worth prospecting.

### Who is it for?

- **Recruitment agencies** mapping which Romanian companies are hiring and in which county.
- **B2B sales teams** using hiring volume as a growth signal for account targeting.
- **Job boards and aggregators** that need a Romanian feed without a data licence.
- **Market analysts** tracking demand by industry, department and city.
- **HR-tech vendors** prospecting employers who publish roles continuously.

### Use cases

- Build a list of every verified company hiring in IT across Bucharest and Cluj.
- Rank employers by open-position count to find the fastest-growing accounts.
- Track how many logistics roles appear per county, month over month.
- Feed a niche Romanian job board with fresh listings and direct ad links.
- Spot the moment a target company posts its first sales role.

### Why use this Actor?

- **Keyless** — no account, no token, no login.
- **28 structured fields**, with taxonomy IDs already resolved to names.
- **Sweeps past the paging ceiling** by replaying department and industry terms.
- **Company signal included** — verified employer flag, plus total open positions when detail fetch is on.
- **Coordinates included** where eJobs publishes them, ready for mapping.
- **Optional requirements text** — one extra request per ad, off by default.

### What data can you extract?

| Field | Type | Description |
|---|---|---|
| `jobId` | string | eJobs ad ID |
| `title` | string | Job title |
| `slug` | string | URL slug |
| `jobUrl` | string | Public ad page |
| `companyName` | string | Hiring company |
| `companyId` | string | Company ID |
| `companySlug` | string | Company page slug |
| `companyVerified` | boolean | eJobs verified employer |
| `companyLogoUrl` | string | Company logo |
| `companyOpenPositions` | number | Total openings at the company (detail fetch only) |
| `positions` | number | Positions in this ad |
| `cities` | string | City names, comma-separated |
| `counties` | string | County names (detail fetch only) |
| `industries` | string | Industry names |
| `departments` | string | Department names |
| `languages` | string | Required languages |
| `latitude` / `longitude` | number | Coordinates where published |
| `jobType` | string | Ad status, e.g. `active` |
| `creationDate` | string | First published |
| `expirationDate` | string | Expiry |
| `republishDate` | string | Last republished |
| `lastModified` | string | Last edit |
| `requirements` | string | Requirements text (only when detail fetch is on) |
| `presentationImageUrl` | string | Employer presentation image |
| `country` | string | Romania |
| `source` | string | Always `ejobs_ro` |
| `scrapedAt` | string | Run timestamp (ISO 8601) |

#### Example output

```json
{
  "jobId": "1977725",
  "title": "Team Leader (f/m/d)",
  "jobUrl": "https://www.ejobs.ro/user/locuri-de-munca/team-leader-f-m-d/1977725",
  "companyName": "MODIVO ROMANIA S.A.",
  "companyVerified": true,
  "positions": 8,
  "cities": "București, Craiova, Brăila",
  "industries": "Retail / Comerț",
  "creationDate": "2026-08-07T19:13:11Z",
  "expirationDate": "2026-09-06T00:00:00Z",
  "jobType": "active",
  "source": "ejobs_ro"
}
```

### How to use it

1. Enter a keyword, or leave it empty to sweep the whole board.
2. Turn on **Fetch requirements text** only if you need the requirements block — it costs one extra request per ad.
3. Set **Maximum results**.
4. Run, then export JSON, CSV or Excel.

### Input example

```json
{
  "query": "",
  "maxResults": 5000
}
```

### Notes and limits

- eJobs honours only free-text search as a filter; city and industry filters are not exposed by the API. The Actor works around this by sweeping taxonomy terms, so a full-board run returns overlapping searches that are de-duplicated by job ID.
- A single search stops at roughly 2 000 rows. Deeper coverage comes from the sweep, not from paging.
- The API does not publish salary. Ads that mention pay do so inside the requirements text.
- `requirements`, `counties` and `companyOpenPositions` live on the ad detail, not the list feed. Switch on **Fetch requirements text** to populate them; with the option off they stay `null` by design rather than pretending to be data.
- You are responsible for how you use employer data, including under GDPR.

### FAQ

**Do I need an eJobs account?**
No. The API is public and this Actor needs nothing from you.

**Why are city and industry filters missing from the input?**
Because eJobs ignores them on the API. Filter the exported dataset instead — every row carries resolved city, county, industry and department names.

**Can I get more than 2 000 ads?**
Yes. Leave the keyword empty and the Actor sweeps department and industry terms to go deeper.

**Is salary included?**
No. eJobs does not expose a salary field; when pay is mentioned it sits inside the requirements text.

**How am I charged?**
Pay per result — you pay for the ads delivered.

# Actor input Schema

## `query` (type: `string`):

Free-text search across eJobs.ro listings, e.g. "developer", "vanzari" or "sofer". Leave empty to sweep the whole board across every department and industry.

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

Open each ad for its requirements text, county names and the company's total open-position count — these three are not present in the list feed. Adds one request per ad, so leave it off for the fastest bulk export.

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

Stop after this many ads. eJobs keeps roughly 15 000 ads live; the Actor sweeps taxonomy terms to reach beyond the API's ~2000-row paging ceiling.

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

eJobs answers a keyless public API; the default datacenter proxy is enough.

## Actor input object example

```json
{
  "query": "developer",
  "fetchDetails": false,
  "maxResults": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `jobId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `slug` (type: `string`):

No description

## `jobUrl` (type: `string`):

No description

## `companyName` (type: `string`):

No description

## `companyId` (type: `string`):

No description

## `companySlug` (type: `string`):

No description

## `companyVerified` (type: `string`):

No description

## `companyLogoUrl` (type: `string`):

No description

## `companyOpenPositions` (type: `string`):

No description

## `positions` (type: `string`):

No description

## `cities` (type: `string`):

No description

## `counties` (type: `string`):

No description

## `industries` (type: `string`):

No description

## `departments` (type: `string`):

No description

## `languages` (type: `string`):

No description

## `latitude` (type: `string`):

No description

## `longitude` (type: `string`):

No description

## `jobType` (type: `string`):

No description

## `creationDate` (type: `string`):

No description

## `expirationDate` (type: `string`):

No description

## `republishDate` (type: `string`):

No description

## `lastModified` (type: `string`):

No description

## `requirements` (type: `string`):

No description

## `presentationImageUrl` (type: `string`):

No description

## `country` (type: `string`):

No description

## `source` (type: `string`):

No description

## `scrapedAt` (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 = {
    "query": "developer",
    "fetchDetails": false,
    "maxResults": 1000,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/ejobs-ro-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 = {
    "query": "developer",
    "fetchDetails": False,
    "maxResults": 1000,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/ejobs-ro-scraper").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 '{
  "query": "developer",
  "fetchDetails": false,
  "maxResults": 1000,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call logiover/ejobs-ro-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,logiover/ejobs-ro-scraper"
        }
    }
}

```

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/XKJLkbf2cGicx1RbW/builds/8ZDBiGbvIBHIOszNd/openapi.json
