# Pinpoint ATS Jobs Scraper (`automation-lab/pinpoint-ats-jobs-scraper`) Actor

Export normalized active vacancies from public Pinpoint ATS employer career feeds for recruiting, aggregation, alerts, and labor-market research.

- **URL**: https://apify.com/automation-lab/pinpoint-ats-jobs-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## Pinpoint ATS Jobs Scraper

Export active public vacancies from employer career sites powered by Pinpoint ATS.

Give the Actor one or more career-site or `jobs.rss` URLs and receive normalized job records with employer, title, job ID, canonical URL, publication date, department, employment type, location, reporting line, compensation, full text, rich HTML, and candidate requirements.

The Actor reads Pinpoint's public RSS output directly over HTTP. It does not use a browser, proxy, login, or candidate/application endpoint.

### What does Pinpoint ATS Jobs Scraper do?

Pinpoint employer career sites publish active vacancies through a standard `/jobs.rss` route.

This Actor turns those feeds into consistent dataset rows that are ready for:

- job aggregation;
- recruiting and sourcing research;
- vacancy alerts;
- labor-market analysis;
- hiring-signal monitoring;
- spreadsheet and database exports;
- text analysis of descriptions and requirements.

Paste either form:

- `https://workwithus.pinpointhq.com/`
- `https://workwithus.pinpointhq.com/jobs.rss`

Career-site URLs are normalized to `/jobs.rss` automatically.

### Who is it for?

#### Job aggregators

Collect public postings from multiple Pinpoint employers in one repeatable run and export JSON, CSV, Excel, XML, or RSS-derived records through the Apify dataset API.

#### Recruiters and talent-intelligence teams

Track the roles, departments, locations, reporting lines, and compensation ranges that selected employers publish.

#### Labor-market analysts

Build time-series snapshots of active vacancies for selected organizations without parsing a different page layout for every role.

#### Agencies and sales teams

Use changes in hiring activity as an account signal, then connect results to a CRM, spreadsheet, or alerting workflow.

#### Data and NLP teams

Use `descriptionText`, `requirementsText`, `fullText`, or `descriptionHtml` for classification, skill extraction, matching, and analysis.

### Why use this Actor?

- **Structured public source:** reads Pinpoint's RSS feed instead of scraping visual page layouts.
- **Full vacancy content:** preserves rich HTML and produces plain-text sections.
- **Batch input:** processes multiple employers in input order.
- **Stable deduplication:** removes repeated jobs by employer host and job ID, falling back to canonical URL.
- **Bounded output:** respects `maxItems` across the complete run.
- **Low overhead:** uses direct HTTP with 256 MB memory and no proxy.
- **Clear validation:** rejects HTML pages, generic RSS feeds, and malformed inputs rather than emitting misleading rows.

This Actor does not discover which employers use Pinpoint. You provide explicit public sources.

### Extracted data

| Field | Meaning |
| --- | --- |
| `employer` | Employer name from the feed channel |
| `employerDescription` | Employer profile text published in the feed |
| `feedUrl` | Normalized `/jobs.rss` source |
| `careersUrl` | Public jobs listing URL declared by the feed |
| `language` | Feed language code when available |
| `jobId` | Job identifier parsed from the canonical URL |
| `title` | Public vacancy title |
| `canonicalUrl` | Canonical public job page |
| `publishedAt` | Publication date normalized to ISO 8601 when parseable |
| `department` | Hiring department |
| `employmentType` | Full time, part time, contract, or source value |
| `location` | Employer-published location |
| `workplaceType` | Remote, hybrid, office, or source value when present |
| `reportingTo` | Reporting line when published |
| `compensation` | Compensation text exactly as published |
| `descriptionText` | Main Description or About the Role section as text |
| `requirementsText` | About You or Requirements section as text |
| `fullText` | All rich vacancy content converted to plain text |
| `descriptionHtml` | Original rich vacancy HTML from the RSS item |
| `scrapedAt` | Timestamp when the Actor parsed the feed |

Fields can be `null` when an employer does not publish the corresponding detail.

### How much does it cost to scrape Pinpoint ATS jobs?

The Actor uses pay-per-event pricing.

A run has one start event and one item event for each unique job saved.

| Event | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| Run started | $0.005 | $0.005 | $0.005 | $0.005 | $0.005 | $0.005 |
| Job saved | $0.000041071 | $0.000035714 | $0.000027857 | $0.000021429 | $0.000014286 | $0.000010000 |

Example FREE-tier Actor charges:

| Workflow | Jobs saved | Actor charge |
| --- | ---: | ---: |
| Quick source check | 10 | $0.0054 |
| Employer export | 100 | $0.0091 |
| Multi-employer monitor | 500 | $0.0255 |
| Large aggregation run | 1,000 | $0.0461 |

The Actor does not add proxy charges because it does not use Apify Proxy.

Normal Apify platform usage rules still apply to compute and storage.

### Getting started

1. Open the Actor input page.
2. Add at least one public Pinpoint career-site or `jobs.rss` URL.
3. Set `maxItems` to the largest number of unique vacancies you want.
4. Click **Start**.
5. Review the default dataset.
6. Export the dataset or connect it to an integration.

Start with a small limit when checking an unfamiliar employer source.

### Input parameters

#### `startUrls`

Required array of request sources.

Each entry may be:

- a Pinpoint employer homepage;
- a Pinpoint `/jobs` listing URL;
- a direct `/jobs.rss` URL;
- a custom employer domain that exposes the validated Pinpoint RSS format.

Examples:

```json
{
  "startUrls": [
    { "url": "https://workwithus.pinpointhq.com/" },
    { "url": "https://reimaginedcareers.pinpointhq.com/jobs.rss" }
  ]
}
```

The Actor does not crawl arbitrary employer websites to discover feeds.

#### `maxItems`

Maximum unique jobs saved across all sources.

- default: `100`
- minimum: `1`
- maximum: `10000`

Sources are processed in input order and the run stops saving records when the limit is reached.

### Example input

```json
{
  "startUrls": [
    { "url": "https://workwithus.pinpointhq.com/" }
  ],
  "maxItems": 25
}
```

### Example output

This shortened record reflects the current output shape:

```json
{
  "employer": "Pinpoint",
  "feedUrl": "https://workwithus.pinpointhq.com/jobs.rss",
  "careersUrl": "https://workwithus.pinpointhq.com/jobs",
  "language": "en-gb",
  "jobId": "526751",
  "title": "Product Reliability Engineer",
  "canonicalUrl": "https://workwithus.pinpointhq.com/jobs/526751",
  "publishedAt": "2026-06-03T18:30:01.000Z",
  "department": "Engineering",
  "employmentType": "Full Time",
  "location": "Remote",
  "workplaceType": null,
  "reportingTo": "Head of Developer Support",
  "compensation": "£60,000 - £70,000 / year",
  "descriptionText": "Hi ...",
  "requirementsText": "You will ...",
  "fullText": "Product Reliability Engineer Department: Engineering ...",
  "descriptionHtml": "<h1>Product Reliability Engineer</h1>...",
  "scrapedAt": "2026-07-27T04:40:00.000Z"
}
```

Long text is abbreviated above only for readability. Dataset rows preserve the complete source content.

### Scheduling a vacancy monitor

Use an Apify schedule to run the same input daily or weekly.

A typical workflow is:

1. save target employer feeds in one input;
2. schedule a daily run;
3. compare `jobId` values with the previous export;
4. notify a channel or update a database when new IDs appear.

The Actor exports current feed state. It does not maintain cross-run history or label jobs as new, changed, or removed.

Store snapshots externally when historical change detection is required.

### Integration ideas

#### Google Sheets

Send each scheduled dataset to a spreadsheet for recruiting research or editorial review.

#### Slack or Microsoft Teams

Trigger a webhook after a run, fetch dataset rows, compare them with known job IDs, and post only newly observed vacancies.

#### CRM enrichment

Count active roles by employer, department, or location and attach hiring signals to target accounts.

#### Data warehouse

Load the dataset through the Apify API and use `(feedUrl, jobId)` as a stable source key.

#### Search and matching

Index `title`, `descriptionText`, and `requirementsText` in a search engine or vector database.

### API usage with cURL

Start a run and wait for completion:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~pinpoint-ats-jobs-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startUrls": [{"url": "https://workwithus.pinpointhq.com/"}],
    "maxItems": 25
  }'
```

Keep API tokens in environment variables or a secret manager.

### API usage with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/pinpoint-ats-jobs-scraper').call({
    startUrls: [
        { url: 'https://workwithus.pinpointhq.com/' },
        { url: 'https://reimaginedcareers.pinpointhq.com/jobs.rss' },
    ],
    maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map(({ employer, title, canonicalUrl }) => ({ employer, title, canonicalUrl })));
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/pinpoint-ats-jobs-scraper").call(run_input={
    "startUrls": [
        {"url": "https://workwithus.pinpointhq.com/jobs.rss"}
    ],
    "maxItems": 100,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["employer"], item["title"], item["canonicalUrl"])
```

### Use with Apify MCP

Add this Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/pinpoint-ats-jobs-scraper"
```

#### Claude Desktop

Add this server to your Claude Desktop MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/pinpoint-ats-jobs-scraper"
    }
  }
}
```

#### Cursor

Use the same HTTP URL in **Cursor Settings → MCP → Add server** and name it `apify`.

#### VS Code

Add the same HTTP MCP server URL through your VS Code MCP extension or workspace MCP configuration.

Example prompts:

- “Export the first 50 active jobs from this Pinpoint career site.”
- “Collect Pinpoint vacancies from these employer feeds and group them by department.”
- “Run the Pinpoint vacancy Actor and list remote roles that publish compensation.”

### Validation and failure behavior

The Actor fails clearly when:

- `startUrls` is empty;
- a URL is malformed or uses an unsupported protocol;
- the source returns HTTP 4xx or 5xx;
- the response is HTML instead of RSS XML;
- the RSS channel does not match the Pinpoint jobs feed shape;
- a vacancy lacks both a usable title and canonical URL.

Transient HTTP 408, 429, and common 5xx responses are retried up to two times.

An empty but valid Pinpoint feed succeeds with zero records.

A failure in one supplied source currently fails the run instead of silently returning a partial multi-source export.

### Limitations

- Employer discovery is not included.
- Only public active vacancies present in the source feed are returned.
- Candidate profiles, applications, forms, and private recruiting data are out of scope.
- Employers choose which optional metadata to publish, so fields may be null.
- Custom domains are supported only when they expose the same Pinpoint `/jobs.rss` structure.
- Feed wording and rich HTML vary by employer; `fullText` and `descriptionHtml` preserve source content when a named section cannot be identified.
- The source may remove closed jobs without a separate removal event.
- The Actor does not translate content or infer normalized salary currencies.

### Tips for reliable exports

- Prefer direct `/jobs.rss` URLs in long-lived automations.
- Keep source order stable when using a low global `maxItems`.
- Use `jobId` together with the canonical URL host when merging employers.
- Preserve `publishedAt` as source time and `scrapedAt` as observation time.
- Store snapshots if you need to detect removed vacancies.
- Inspect logs after an employer changes domains or disables its feed.

### Responsible use and legality

This Actor accesses public job-advertising feeds only.

You are responsible for:

- complying with applicable website terms and laws;
- using vacancy text and employer information for a lawful purpose;
- respecting copyright and database rights;
- applying appropriate retention and attribution practices;
- avoiding automated interaction with application or candidate systems outside this Actor's scope.

Do not use exported data to discriminate unlawfully or misrepresent an employer's posting.

### Related Automation Labs Actors

- [Greenhouse Jobs Scraper](https://apify.com/automation-lab/greenhouse-jobs-scraper) — public Greenhouse board and job-detail extraction.
- [Personio Jobs Scraper](https://apify.com/automation-lab/personio-jobs-scraper) — public Personio career-page vacancies.
- [Recruitee Jobs Scraper](https://apify.com/automation-lab/recruitee-jobs-scraper) — public Recruitee employer postings.

Use this Actor when the employer's career site is powered by Pinpoint and exposes `/jobs.rss`.

### FAQ

#### Does the Actor need a Pinpoint account?

No. It reads public employer vacancy feeds and does not log in.

#### Does it use a browser or proxy?

No. The current product uses direct HTTP RSS requests only.

#### Can it find every company using Pinpoint?

No. Provide explicit employer career-site or feed URLs.

#### Can I pass a normal career homepage URL?

Yes. The Actor normalizes the supplied host to `/jobs.rss` and validates the response.

#### Why is a generic RSS feed rejected?

The Actor validates Pinpoint-specific channel links and vacancy metadata so unrelated feeds are not mislabeled as Pinpoint jobs.

#### Why are some fields null?

Pinpoint employers control their vacancy content. Optional details such as compensation, workplace type, or reporting line may be absent.

#### What happens when a valid employer has no open jobs?

The Actor succeeds and saves zero records when the source remains a valid empty Pinpoint feed.

#### How do I detect new or closed jobs?

Schedule repeated runs and compare `(feedUrl, jobId)` keys with a stored prior snapshot.

#### Can I scrape applications or candidate information?

No. Candidate and application data are intentionally out of scope.

#### What should I do after an HTTP error?

Confirm the career site still opens publicly, try its direct `/jobs.rss` URL, and inspect the Actor log for the exact source and status code.

# Actor input Schema

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

Pinpoint employer career-site URLs (for example, https://workwithus.pinpointhq.com/) or direct /jobs.rss URLs. Every source must expose a public Pinpoint RSS feed.

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

Maximum number of unique job records saved across all feeds. Sources are processed in input order.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://workwithus.pinpointhq.com/"
    }
  ],
  "maxItems": 10
}
```

# Actor output Schema

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

Normalized jobs in the Pinpoint jobs overview view.

# 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 = {
    "startUrls": [
        {
            "url": "https://workwithus.pinpointhq.com/"
        }
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/pinpoint-ats-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 = {
    "startUrls": [{ "url": "https://workwithus.pinpointhq.com/" }],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/pinpoint-ats-jobs-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 '{
  "startUrls": [
    {
      "url": "https://workwithus.pinpointhq.com/"
    }
  ],
  "maxItems": 10
}' |
apify call automation-lab/pinpoint-ats-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/pinpoint-ats-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/jTmqkj2BuDekJNtbh/builds/DUpL07rgFkjKhGPAc/openapi.json
