# Job Posting Age Anomaly Detector (`trovevault/job-posting-age-anomaly-detector`) Actor

Find job postings that have stayed open unusually long in a city and function area. Returns posting age, anomaly flag, hard-to-fill signal, salary when available, and job URL.

- **URL**: https://apify.com/trovevault/job-posting-age-anomaly-detector.md
- **Developed by:** [Trove Vault](https://apify.com/trovevault) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 job openings

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Job Posting Age Anomaly Detector

Find roles that have stayed open unusually long in a local hiring market.

Give the actor a city, a function area, and optional keywords. It returns a compact job table with posting age, a hard-to-fill signal, and the evidence needed to review the role quickly.

This actor is built for labor-market research, recruiting intelligence, sales prospecting, and weekly monitoring of persistent hiring demand. It does not require any third-party API key.

### What it does

Job Posting Age Anomaly Detector scans job postings for a selected market and returns:

- Job title, company, location, and URL
- Posting date and posting age in days
- Whether the posting exceeds your age threshold
- A simple hard-to-fill signal
- A plain-English reason for the signal
- Salary range when available
- A short description snippet for quick review

The main signal is intentionally transparent: when a posting remains visible beyond the configured threshold, usually 60 days, it is flagged as an age anomaly.

### Input

Typical input:

```json
{
  "city": "Prague",
  "functionArea": "Software Engineering",
  "keywords": ["backend engineer"],
  "ageThresholdDays": 60,
  "maxResults": 50
}
````

Required fields:

- `city`: target city, for example Prague, Munich, Lisbon, London, or Toronto
- `functionArea`: job family, for example Software Engineering, Sales, Marketing, Customer Success, Finance, or Operations

Optional fields:

- `keywords`: job titles, skills, or phrases to narrow the scan. Keywords are matched against both job titles and descriptions.
- `ageThresholdDays`: number of days after which a posting is treated as unusually old. Default is 60.
- `maxResults`: maximum rows returned after filtering and deduplication. Default is 50.
- `datasetId`: existing Apify dataset to append results to.
- `runId`: external run identifier for workflow chaining.

The actor infers country context for common city names, so users do not need to provide a country for normal runs.

### Output

Each dataset item is one job posting. Operational diagnostics are written to the run summary and logs, not mixed into the result table.

Example output:

```json
{
  "title": "Senior Backend Engineer",
  "company": "Example GmbH",
  "location": "Berlin, Germany",
  "city": "Berlin",
  "functionArea": "Software Engineering",
  "postedAt": "2026-01-18T00:00:00.000Z",
  "postingAgeDays": 102,
  "ageThresholdDays": 60,
  "exceedsAgeThreshold": true,
  "hardToFillSignal": "high",
  "signalReason": "Open for 102 days, above the 60-day threshold.",
  "salaryRange": "EUR 90000-120000",
  "jobUrl": "https://example.com/job",
  "descriptionSnippet": "Short excerpt from the posting...",
  "scrapedAt": "2026-05-03T10:00:00.000Z"
}
```

### How to read the signal

`exceedsAgeThreshold` is the clearest field. It tells you whether the posting has been open longer than your threshold.

`hardToFillSignal` gives a simple label:

- `high`: old posting with strong age evidence
- `medium`: old posting with moderate age evidence
- `low`: recent posting or weak age evidence
- `unknown`: posting age was unavailable

`signalReason` explains the label in plain English so the row can be used directly in reviews, spreadsheets, and downstream workflows.

### Data quality

Job posting dates are useful but imperfect. Some companies refresh postings, keep evergreen roles live, or reuse job URLs. Treat the output as a shortlist for review, not as proof that every old posting is actively hard to fill.

Salary availability depends on the job posting. When compensation is not published, `salaryRange` is empty.

### Use cases

- Find hard-to-fill roles in a target city
- Monitor senior hiring pressure by function area
- Build recruiter or vendor lead lists from persistent hiring signals
- Compare local hiring demand across markets
- Identify stale or evergreen job listings
- Feed clean job-age signals into a wider TroveVault workflow

### API use

Run the actor manually, schedule it, or call it through the Apify API.

```bash
curl -X POST "https://api.apify.com/v2/acts/TroveVault~job-posting-age-anomaly-detector/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"city":"Prague","functionArea":"Software Engineering","keywords":["backend engineer"],"maxResults":50}'
```

The actor writes a `RUN_SUMMARY` key-value-store record with row counts, anomaly count, matching mode, and run status.

# Actor input Schema

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

City to scan for job postings. The actor returns postings that match this local market. Example: Munich, Berlin, London, Lisbon. Use the city name a job seeker would type into a job board.

## `functionArea` (type: `string`):

Job family to scan. The actor expands this into practical search terms and labels every output row with the selected area. Example: Customer Success, Software Engineering, Sales, Marketing. Pick the closest business function.

## `keywords` (type: `array`):

Optional job titles, skills, or phrases to make the scan more precise. Keywords are matched against job titles and descriptions, then combined with the selected function area. Example: backend engineer, client success, growth manager. Leave empty for a broader function-area scan.

## `ageThresholdDays` (type: `integer`):

Number of days after which a job posting is flagged as unusually old. Example: 60 means postings open for 60 days or more are marked as age anomalies. Lower values catch more roles but add noise.

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

Maximum rows to return after filtering and deduplication. Example: 50 for a quick scan, 200 for a broader market check. Higher values take longer.

## `datasetId` (type: `string`):

ID of an existing Apify dataset to append results to, in addition to the default run dataset. Leave blank to use only the default run dataset.

## `runId` (type: `string`):

ID of an existing Apify actor run to associate results with. Used for pipeline chaining and multi-step workflows. Leave blank for standalone runs.

## Actor input object example

```json
{
  "city": "Munich",
  "functionArea": "Software Engineering",
  "ageThresholdDays": 60,
  "maxResults": 50
}
```

# Actor output Schema

## `dataset` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("trovevault/job-posting-age-anomaly-detector").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("trovevault/job-posting-age-anomaly-detector").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 '{}' |
apify call trovevault/job-posting-age-anomaly-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=trovevault/job-posting-age-anomaly-detector",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Job Posting Age Anomaly Detector",
        "description": "Find job postings that have stayed open unusually long in a city and function area. Returns posting age, anomaly flag, hard-to-fill signal, salary when available, and job URL.",
        "version": "0.1",
        "x-build-id": "N4S6Wmb3MoKWan0zg"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/trovevault~job-posting-age-anomaly-detector/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-trovevault-job-posting-age-anomaly-detector",
                "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/trovevault~job-posting-age-anomaly-detector/runs": {
            "post": {
                "operationId": "runs-sync-trovevault-job-posting-age-anomaly-detector",
                "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/trovevault~job-posting-age-anomaly-detector/run-sync": {
            "post": {
                "operationId": "run-sync-trovevault-job-posting-age-anomaly-detector",
                "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",
                "required": [
                    "city",
                    "functionArea"
                ],
                "properties": {
                    "city": {
                        "title": "City",
                        "type": "string",
                        "description": "City to scan for job postings. The actor returns postings that match this local market. Example: Munich, Berlin, London, Lisbon. Use the city name a job seeker would type into a job board.",
                        "default": "Munich"
                    },
                    "functionArea": {
                        "title": "Function Area",
                        "enum": [
                            "Software Engineering",
                            "Data & Analytics",
                            "Product Management",
                            "Design",
                            "Sales",
                            "Marketing",
                            "Customer Success",
                            "Operations",
                            "Finance",
                            "Human Resources",
                            "Legal",
                            "Healthcare",
                            "Education",
                            "Logistics",
                            "Manufacturing",
                            "Other"
                        ],
                        "type": "string",
                        "description": "Job family to scan. The actor expands this into practical search terms and labels every output row with the selected area. Example: Customer Success, Software Engineering, Sales, Marketing. Pick the closest business function.",
                        "default": "Software Engineering"
                    },
                    "keywords": {
                        "title": "Keywords (optional)",
                        "type": "array",
                        "description": "Optional job titles, skills, or phrases to make the scan more precise. Keywords are matched against job titles and descriptions, then combined with the selected function area. Example: backend engineer, client success, growth manager. Leave empty for a broader function-area scan.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "ageThresholdDays": {
                        "title": "Age Threshold Days",
                        "minimum": 1,
                        "maximum": 365,
                        "type": "integer",
                        "description": "Number of days after which a job posting is flagged as unusually old. Example: 60 means postings open for 60 days or more are marked as age anomalies. Lower values catch more roles but add noise.",
                        "default": 60
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum rows to return after filtering and deduplication. Example: 50 for a quick scan, 200 for a broader market check. Higher values take longer.",
                        "default": 50
                    },
                    "datasetId": {
                        "title": "Dataset ID (optional)",
                        "type": "string",
                        "description": "ID of an existing Apify dataset to append results to, in addition to the default run dataset. Leave blank to use only the default run dataset."
                    },
                    "runId": {
                        "title": "Run ID (optional)",
                        "type": "string",
                        "description": "ID of an existing Apify actor run to associate results with. Used for pipeline chaining and multi-step workflows. Leave blank for standalone runs."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
