DEV Community

Automation Helper
Automation Helper

Posted on

How to search Norwegian jobs across Jobbnorge and LinkedIn with one API

Searching for jobs in Norway gets awkward quickly when each source returns a different shape. A title can be formatted differently, location data can be incomplete, and the same vacancy may appear on more than one job board. If your workflow needs structured results rather than browser tabs, the useful unit is not “one source at a time”; it is one normalized, deduplicated job feed.

The Norway Jobs Search API searches Jobbnorge and LinkedIn Jobs in a single run by default. It normalizes the final matches into one schema, applies local filters, keeps source provenance, and conservatively deduplicates cross-source listings. NAV Arbeidsplassen is also available when its separate NAV_JOB_FEED_TOKEN has been configured; it is not silently used by the no-secret default.

1. Start with a bounded search

Create a run with a job query, locations, a freshness limit, and an intentionally small result cap while you test the integration:

{
  "query": "software developer",
  "locations": ["Oslo"],
  "publishedWithinDays": 7,
  "sources": ["jobbnorge", "linkedin"],
  "employmentTypes": ["FULL_TIME"],
  "maxResults": 25,
  "sortBy": "match",
  "mode": "search"
}
Enter fullscreen mode Exit fullscreen mode

maxResults is the number of final canonical vacancies, not the number of raw rows fetched from each source. That matters when one employer has placed the same role on several portals.

2. Use the canonical record, not source-specific HTML

A representative result row has stable job and source fields, plus explainable matching metadata:

{
  "canonicalJobId": "job_2bd71d_example",
  "title": "Software Developer",
  "company": "Example AS",
  "location": {
    "displayName": "Oslo, Norway",
    "city": "Oslo",
    "countryCode": "NO",
    "distanceKm": null
  },
  "publishedAt": "2026-08-30T09:00:00.000Z",
  "employmentType": "FULL_TIME",
  "workArrangement": "HYBRID",
  "applyUrl": "https://jobs.example.invalid/vacancy/123",
  "matchScore": 89,
  "matchReasons": ["Strong title match", "Published 2 days ago"],
  "sourceCount": 2,
  "canonicalSource": "jobbnorge",
  "changeType": "NEW",
  "sources": [
    { "source": "jobbnorge", "sourceId": "example-1", "url": "https://www.jobbnorge.no/..." },
    { "source": "linkedin", "sourceId": "example-2", "url": "https://www.linkedin.com/jobs/view/..." }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The exact fields vary when a source does not expose something. The Actor returns null instead of inventing salary, coordinates, deadlines, or a work arrangement.

3. Choose the integration surface that fits your workflow

In the Apify Console, use the Dataset as your JSON/CSV result set. For an application, call the Actor through Apify’s REST API or client, wait for the run, and read the default Dataset. The relevant part is to treat canonicalJobId as the identity and the nested sources array as audit provenance.

Cost

At publication time, the Actor has a $0.00005 start event and charges $0.0025 for each final normalized, deduplicated job row. Filtered rows and duplicate source listings are not the final result event. Check the Actor pricing page before a production rollout because Store prices can change.

Try it

Start from the existing no-secret Jobbnorge + LinkedIn task: Run the Norway Jobs search Task.

For filtering details and API context, see the Norway Jobs Search API Actor page.

Top comments (0)