# Jobgether Jobs | Normalized (`jobatlas/normalized-jobgether-jobs-scraper`) Actor

Unofficial independent Actor for bounded public Jobgether job searches. Returns strict normalized records with source links, descriptions, dates, locations, compensation when published, and application details.

- **URL**: https://apify.com/jobatlas/normalized-jobgether-jobs-scraper.md
- **Developed by:** [Job Atlas](https://apify.com/jobatlas) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

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

## Jobgether Jobs | Normalized

Search Jobgether jobs with complete original descriptions, optional owner-funded AI enrichment, optional English display text, and advanced filters. This independent Actor is not affiliated with Jobgether.

### How it works

This Actor searches available Jobgether job postings with complete original descriptions.

Only postings with verified complete descriptions are available. Snippets, truncated bodies, and unverified historical records are withheld. If job data is unavailable or stale, the run fails instead of falling back to website scraping. Coverage can therefore be smaller than the current website listing.

When requested, AI enrichment fills supported unknown fields and records provenance in `llm`. It cannot overwrite known source facts. Jobs whose requested enrichment fails are withheld. Optional translation converts selected human-readable fields into English, while `raw.description` and `raw.descriptionHtml` preserve the original source content. Without enrichment, `llm.status` is `not_requested`.

### First run

```json
{
  "schemaVersion": "nomad-agent-inventory-search-v1",
  "maxItems": 5,
  "postedWithin": "any",
  "keyword": "",
  "aiEnrichment": {"enabled": false, "accuracy": "silver"},
  "translateToEnglish": false,
  "dedupe": {"enabled": false, "key": ""}
}
```

`maxItems` is an upper bound of 200; zero also means 200. Filtering, repeat suppression, and failed enrichment can produce fewer results. A keyword is a case-insensitive phrase matched against the title, employer, and complete original description.

`postedWithin` accepts `any` or a positive duration such as `7d`. When Jobgether has no reliable original posting date, the reported date is the job's first observation. Later refreshes do not make the posting appear new.

### Advanced filters

`workArrangements` accepts `remote`, `hybrid`, and `onsite`. For other normalized fields, use the shared `nomad-agent-job-filter-v1` expression contract:

```json
{
  "schemaVersion": "nomad-agent-job-filter-v1",
  "expression": {
    "field": "data.compensation.minimum",
    "operator": "gte",
    "value": 50000
  }
}
```

Place that object under the input's `filters` field. With AI disabled, filters evaluate source facts only; unknown values do not satisfy ordinary comparisons. With AI enabled, known source mismatches are removed before AI calls and unknown enrichable values are checked again after enrichment. Filters operate on normalized values before English display translation. Compare compensation only with the appropriate currency and period filters.

### Output and repeat delivery

Every dataset item follows `nomad-agent-job-v1`, with six roots: `schemaVersion`, `identity`, `data`, `llm`, `raw`, and `custom`. Missing facts remain `null`; a known empty collection is `[]`. Original identity and complete description evidence remain stable across enrichment and translation. The rich format is intended for v3 scoring and advanced filtering.

The default key-value store contains `RUN-SUMMARY`, including data freshness, candidates, withheld enrichment failures, delivery counts, and terminal status. `OWNER-USAGE` separates actual provider costs from unpriced token counts when enrichment runs. Diagnostic receipts are not inserted into the jobs dataset.

Repeat suppression is enabled by default. It uses a persistent ledger scoped to the Apify user, Actor, and search. Set `dedupe.enabled` to `false` for a stateless run. A nonempty `dedupe.key` deliberately shares delivery history within that user's scope. Ambiguous delivery or ledger failures fail the run rather than claiming successful delivery.

### Owner-funded processing

AI enrichment and translation are independent opt-ins, both off by default. Enable `aiEnrichment.enabled` for extraction and `translateToEnglish` for English display text. You do not supply API keys. Only when enabled, the owner sends description text to OpenRouter for extraction or selected display text to DeepL for translation. The configured routes deny provider data collection but do not guarantee zero retention or EU-only processing. Sanitized extracted facts and translations may be cached by the owner. V3 callers can explicitly request the processing they need.

The existing Apify pricing configuration is preserved by this migration. This Actor is unmonetized; platform compute or storage charges can still apply. No new per-result, enrichment, or translation price is introduced.

Use `nomad-agent-inventory-search-v1` for this job-search release. The previous release used different source-specific search inputs. Old inputs fail with migration guidance. Replace them with `keyword` or supported normalized `filters`. Original descriptions are always included.

The top-level `accuracy` field remains a compatibility override for `aiEnrichment.accuracy`; it never enables enrichment by itself.

Relative posting-age windows are limited to 36500 days. Use `any` for an unrestricted search. AI enrichment and translation remain independent opt-ins, both off by default.

Source-specific facts are the `custom` extension; its identifier is `custom.schemaId`.

### Migrating from the previous release

`identity.externalId` is the source's own posting ID as represented in this output. It may be spelled differently from earlier previous releases. The stable posting key is the pair `(identity.source, identity.externalId)`. Update any stored comparison keys when migrating; existing delivery history may permit a one-time repeat. Source URLs and original descriptions remain available.

The `custom` extension now carries source-supplied facts under a new `custom.schemaId` (earlier releases used `nomad-jobgether-source-v1` with a different shape). Read `custom.schemaId` before interpreting `custom.data`. The other five roots keep the `nomad-agent-job-v1` contract.

### Fast setup and source code

[Public repository](https://github.com/Exdenta/jobatlas) · [Agent setup skill](https://github.com/Exdenta/OinkAIJobSearch/blob/main/.agents/skills/public-apify-actors/SKILL.md).

Use the Actor’s current input form for filters, or start with its documented API example. Select `latest` for `normalized-jobgether-jobs-scraper` and record the immutable build ID and number returned by your run. Inspect the dataset and any run summary the Actor documents together; a successful status alone does not establish complete source coverage.

Restrictive filters or repeat-delivery suppression can produce zero results. Diagnostics and demo records are not source records. Optional AI or translation stays explicit where supported.

### Job Atlas

Explore the Job Atlas job-data and matching Actors. Use `latest` and retain the immutable build ID returned by each run.

- [Linkedin](https://apify.com/jobatlas/linkedin-enrich-translate-normalize-scraper)
- [Euraxess](https://apify.com/jobatlas/euraxess-enrich-translate-normalize-scraper)
- [YC](https://apify.com/jobatlas/ycombinator-enrich-translate-normalize-scraper)
- [Scorer](https://apify.com/jobatlas/ai-job-fit-scorer)

[Product guide](https://github.com/Exdenta/jobatlas/blob/main/docs/job-actor-input-examples.md) | [Source and client examples](https://github.com/Exdenta/jobatlas) | [Setup skill](https://github.com/Exdenta/jobatlas/blob/main/.agents/skills/public-apify-actors/SKILL.md) | [Setup guide](https://github.com/Exdenta/jobatlas/blob/main/docs/public-actors-setup.md)

### Product guides and related tools

- [Product overview and public links](https://jobatlas.dev/actors/directory/normalized-jobs#jobatlas-normalized-jobgether-jobs-scraper)
- [Public setup guide](https://github.com/Exdenta/jobatlas/blob/main/docs/public-actors-setup.md)
- [Job Atlas job-data tools](https://jobatlas.dev/actors)
- [Oink personal job alerts](https://oinkjobsearch.com/)

# Actor input Schema

## `schemaVersion` (type: `string`):

Version marker for database-only normalized job search.

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

Maximum returned jobs. Zero means 200. Enrichment and filters may produce fewer matches.

## `postedWithin` (type: `string`):

Filter by the stored posting date. When Jobgether publishes no original date, this is the first inventory admission date; later refreshes do not reset it. Positive durations are limited to 36500 days; use any for an unrestricted search.

## `workArrangements` (type: `array`):

Optional remote, hybrid, or onsite filter; empty means all.

## `dedupe` (type: `object`):

Suppress confirmed repeat deliveries for the same Apify user and search. Disable it for a stateless run.

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

Case-insensitive phrase matched against the stored title, employer, and complete original description.

## `accuracy` (type: `string`):

Compatibility override for aiEnrichment.accuracy. Prefer the accuracy field inside aiEnrichment; when this field is explicitly supplied, it takes precedence.

## `filters` (type: `object`):

Versioned filters over normalized fields. With enrichment off, only stored source facts are evaluated; unknown values do not satisfy ordinary comparisons.

## `aiEnrichment` (type: `object`):

Optional owner-funded enrichment fills unknown fields. Disabled by default. No customer API key is required.

## `translateToEnglish` (type: `boolean`):

Translate selected display fields using the owner service. Original descriptions remain unchanged. Independent of AI enrichment; disabled by default.

## Actor input object example

```json
{
  "schemaVersion": "nomad-agent-inventory-search-v1",
  "maxItems": 5,
  "postedWithin": "any",
  "workArrangements": [],
  "dedupe": {
    "enabled": false,
    "key": ""
  },
  "keyword": "",
  "aiEnrichment": {
    "enabled": false,
    "accuracy": "silver"
  },
  "translateToEnglish": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (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 = {
    "schemaVersion": "nomad-agent-inventory-search-v1",
    "maxItems": 5,
    "postedWithin": "any",
    "workArrangements": [],
    "dedupe": {
        "enabled": false,
        "key": ""
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("jobatlas/normalized-jobgether-jobs-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 = {
    "schemaVersion": "nomad-agent-inventory-search-v1",
    "maxItems": 5,
    "postedWithin": "any",
    "workArrangements": [],
    "dedupe": {
        "enabled": False,
        "key": "",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("jobatlas/normalized-jobgether-jobs-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 '{
  "schemaVersion": "nomad-agent-inventory-search-v1",
  "maxItems": 5,
  "postedWithin": "any",
  "workArrangements": [],
  "dedupe": {
    "enabled": false,
    "key": ""
  }
}' |
apify call jobatlas/normalized-jobgether-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jobatlas/normalized-jobgether-jobs-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/e3L8nyjTnjbJ5ZiV4/builds/R8KKvZ7xg2z2gq2ZF/openapi.json
