Piotr VassevPiotr Vassev

How to Monitor New LinkedIn Jobs Without Repeating Old Results

Running the same job search every morning usually produces many of yesterday's rows. The LinkedIn Jobs Monitor remembers reported job IDs and returns newly discovered matches on later runs. I maintain this Actor on Apify.

The example watches RevOps roles in Berlin. You will first establish a baseline, then save a scheduled task and decide when a new row should become an alert.

How to Monitor New LinkedIn Job Postings

Choose the window before the schedule

Each keyword is combined with every location. Two keywords and three locations create six searches. Start with one combination so you can tell whether it finds the right roles. Empty locations mean worldwide searches.

For a daily schedule, give postedWithin more than 24 hours of coverage. The example uses r604800, the past week, to leave room for delayed runs. The Actor suppresses already reported IDs even when the window overlaps.

Use a stable monitorId for this ongoing watch. Without one, memory is tied to the exact keywords, locations, and window, so editing them creates a fresh monitor. Use a different ID for an unrelated watch. The first run has no prior memory: existing jobs in the window are eligible as its baseline.

Budget for the sample

Pricing as of September 6, 2026. On the Free tier, each new listing is $0.004 and each new detailed job is $0.006. The Gold rates are $0.0015 and $0.0025. The Actor-start event is $0.00005 per GB of allocated memory, with a minimum of one event. Listing and detail are alternative result events. Check current Actor pricing and the run charge breakdown; these calculations describe Actor events, and separately billed platform or proxy resources may also apply.

Establish the first monitor run

Open the Actor on Apify. In Input, switch to the JSON editor and paste:

{
  "keywords": [
    "RevOps Manager"
  ],
  "locations": [
    "Berlin, Germany"
  ],
  "postedWithin": "r604800",
  "enrichment": "listing",
  "maxItems": 25,
  "monitorId": "berlin-revops"
}

Click Start, then open the completed run’s output dataset.

maxItems: 25 caps new jobs across the run, not the number of search cards checked. enrichment: "listing" returns the search-card fields. Choose detail later if the alert needs descriptions, salary fields, seniority, or apply type.

After completion, open the dataset and the run's key-value store. Inspect RUN_SUMMARY, including newJobs, jobsChecked, alreadyReportedBefore, truncated, and truncationReason. A successful run with zero new rows is a normal outcome after the baseline.

Read the returned fields

FieldHow to use it
jobIdStable deduplication key
titleRole title
companyNameHiring company
locationPosted location
postedDatePosting date
jobUrlLinkedIn URL

Use jobId as the durable identifier and jobUrl as the review link. A job's postedDate and the time you first discovered it answer different questions, so store both.

Detail data depends on what the posting exposes. A missing salary is not a zero salary, and applicant counts should not be treated as verified completed applications.

Historical linkedin jobs monitor output

Save a daily watch and a recoverable alert queue

Export the first dataset and review the titles and locations. Decide whether to send those baseline jobs or simply archive them. Save the input as an Apify task and attach a daily schedule. Keep the same monitorId when adjusting this watch's titles or window.

For each completed run, copy the dataset into a destination table keyed by jobId. Add first-seen time, source run or dataset ID, and an alert status. Send an alert only for a newly inserted row, then record delivery. This destination check protects against repeated processing of a dataset.

Keep the completed dataset until delivery succeeds. The monitor remembers jobs it has reported to its dataset; that does not mean your email or webhook received them. If an integration fails, retry delivery from the saved dataset instead of expecting the next monitor run to return the same jobs.

Review runs that repeatedly reach 25 new jobs. Overflow can remain eligible for later runs, but only while the postings remain accessible within the lookback window. Increase the cap or schedule frequency if a backlog persists. Do not promise a complete archive from a limited search feed.

Distinguish a quiet day from a broken watch

Zero new jobs with many alreadyReportedBefore entries generally means the deduplication is working. Zero checked jobs deserves a different investigation: check the search on LinkedIn, the location wording, the lookback window, and the run log.

Changing monitorId starts separate memory, so doing that to troubleshoot can replay current matches. Keep test monitors clearly separate from the production alert queue. Also check truncated: a successful status does not by itself prove the whole search was examined.

For saving and processing completed monitor datasets, see the Node.js example. Use the current input fields above if the example differs.

Frequently asked questions

Why does the first run return older jobs?

The first run has no prior memory, so existing matches within the lookback window are eligible as its baseline.

Can a later successful run have no results?

Yes. If every discovered job ID has already been reported, the dataset can contain no new jobs. Inspect RUN_SUMMARY to distinguish this from a failed search.

Will rerunning resend a failed notification?

No. Monitor memory tracks reported jobs, not downstream notification delivery. Retry the notification from the saved dataset.

Piotr Vassev

Piotr Vassev

Founder of FalconScrape. Building production-grade web scraping systems and data automation pipelines for businesses worldwide.

Connect on LinkedIn