# Pre-Configured Portal Providers and Search Queries in Career-Ops' portals.yml

> Explore santifer/career-ops portals.yml for six pre-configured ATS providers like Greenhouse, Ashby, Lever plus custom search queries for job boards and role keywords.

- Repository: [Santiago Fernández de Valderrama/career-ops](https://github.com/santifer/career-ops)
- Tags: how-to-guide
- Published: 2026-06-13

---

**The Career-Ops [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) configuration includes six pre-configured ATS providers (Greenhouse, Ashby, Lever, Workable, SmartRecruiters, and Recruitee) and dozens of customizable search queries targeting specific job boards and role keywords.**

The [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) file (generated from [`templates/portals.example.yml`](https://github.com/santifer/career-ops/blob/main/templates/portals.example.yml)) serves as the central configuration hub for the Career-Ops job-scanning subsystem. It defines both how the scanner retrieves structured data from company Applicant Tracking Systems and where it searches for new opportunities across public job boards. Understanding these pre-configured portal providers and search queries allows you to customize your automated job search without modifying the core source code.

## Pre-Configured Portal Providers

The provider list defines the low-level adapters that `scan.mjs` uses to fetch structured job data from major ATS platforms. These identifiers are auto-loaded from the `providers/` directory and mapped to specific URL patterns.

The six default providers implemented in `santifer/career-ops` are:

- **`greenhouse`** – Targets Greenhouse ATS instances at `job-boards.greenhouse.io/<slug>` or `boards.greenhouse.io/<slug>`.
- **`ashby`** – Handles Ashby ATS careers pages at `jobs.ashbyhq.com/<slug>`.
- **`lever`** – Parses Lever ATS listings from `jobs.lever.co/<slug>`.
- **`workable`** – Connects to Workable career portals at `apply.workable.com/<slug>`.
- **`smartrecruiters`** – Supports SmartRecruiters at `careers.smartrecruiters.com/<slug>` or `jobs.smartrecruiters.com/<slug>`.
- **`recruitee`** – Handles Recruitee-based sites using the pattern `<slug>.recruitee.com`.

When `scan.mjs` processes a `careers_url` entry in your tracked companies list, it auto-detects the correct provider based on these URL patterns before invoking the provider-specific `fetchJobs()` method.

## Search Queries Configuration

The `search_queries` section contains WebSearch definitions that feed the scanner with URLs from public job boards. Each entry in [`templates/portals.example.yml`](https://github.com/santifer/career-ops/blob/main/templates/portals.example.yml) follows a consistent YAML structure with three fields: `name`, `query`, and `enabled`.

A typical search query entry looks like this:

```yaml
- name: Ashby — AI PM
  query: 'site:jobs.ashbyhq.com "AI Product Manager" OR "Senior Product Manager AI" remote'
  enabled: true

```

The full catalogue in the example file spans dozens of boards including Ashby, Greenhouse, Workable, Remotive, WeWorkRemotely, and region-specific aggregators for the EU and Turkey. Each query combines site-specific filters with role keywords to return only relevant positions.

## How scan.mjs Consumes the Configuration

At runtime, `scan.mjs` performs a two-phase discovery process using the [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) configuration:

1. **Provider Detection** – For each company in `tracked_companies`, it matches the `careers_url` against the provider patterns defined in the `providers/` directory (e.g., `providers/greenhouse.mjs`, `providers/ashby.mjs`).

2. **Search Execution** – It iterates through the `search_queries` list and executes only those entries where `enabled: true`, scraping the results to extract new job postings.

According to the Career-Ops source code, the `providers/*.mjs` files implement two critical functions: `detect()` to confirm URL compatibility and `fetchJobs()` to retrieve structured listing data.

## Working with the Configuration Programmatically

You can inspect and manipulate the pre-configured providers and search queries using Node.js before running a scan.

### List Available Providers

To see the built-in provider identifiers programmatically:

```javascript
import fs from 'fs';
import yaml from 'js-yaml';

const portals = yaml.load(fs.readFileSync('templates/portals.example.yml', 'utf8'));

const providers = [
  'greenhouse',
  'ashby',
  'lever',
  'workable',
  'smartrecruiters',
  'recruitee',
];
console.log('Enabled providers:', providers);

```

### Extract Active Search Queries

To filter for only the enabled search definitions:

```javascript
import fs from 'fs';
import yaml from 'js-yaml';

const data = yaml.load(fs.readFileSync('templates/portals.example.yml', 'utf8'));

const enabledQueries = data.search_queries
  .filter(q => q.enabled)
  .map(q => ({ name: q.name, query: q.query }));

console.table(enabledQueries);

```

## Setting Up Your Local portals.yml

Before running your first scan, copy the example configuration to the project root and customize it:

```bash

# Copy the template to create your runtime configuration

cp templates/portals.example.yml portals.yml

# Edit portals.yml to disable unwanted queries or adjust keywords

# Then execute the scanner

node scan.mjs

```

The scanner automatically picks up the provider definitions from `providers/` and respects the `enabled` flags in your [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) file.

## Summary

- **Six Pre-Configured Providers**: The [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) template includes built-in support for Greenhouse, Ashby, Lever, Workable, SmartRecruiters, and Recruitee ATS platforms.
- **Search Query Structure**: Each query contains a human-readable name, a site-filtered query string, and an enabled boolean flag.
- **File Architecture**: [`templates/portals.example.yml`](https://github.com/santifer/career-ops/blob/main/templates/portals.example.yml) serves as the reference configuration, while [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) (created by copying the template) drives the runtime behavior of `scan.mjs`.
- **Provider Implementation**: Actual fetching logic resides in `providers/*.mjs` files, which expose `detect()` and `fetchJobs()` methods used by the scanner.

## Frequently Asked Questions

### What is the difference between portals.example.yml and portals.yml?

[`templates/portals.example.yml`](https://github.com/santifer/career-ops/blob/main/templates/portals.example.yml) is the version-controlled reference file in the `santifer/career-ops` repository that contains all default providers and search queries. You create [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) by copying this template to your project root, then customize it to enable only the queries and companies you want to track. The scanner specifically looks for [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) at runtime, not the template file.

### How do I disable a specific search query?

Open your local [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml) file and locate the query entry under the `search_queries` section. Change the `enabled` field from `true` to `false`. The scanner in `scan.mjs` filters the list using `filter(q => q.enabled)` before execution, so disabled entries are skipped automatically without deleting the configuration.

### Can I add a custom ATS provider that is not in the default list?

Yes, you can extend the system by creating a new file in the `providers/` directory (e.g., `providers/custom.mjs`) that exports `detect()` and `fetchJobs()` functions following the existing provider pattern. However, you must also manually require this provider in `scan.mjs` or modify the auto-loading logic, as the default list only includes the six pre-configured providers.

### Where are the provider implementations located?

The provider logic for each ATS resides in the `providers/` directory at the repository root. Each provider (e.g., `greenhouse.mjs`, `ashby.mjs`, `lever.mjs`) contains the platform-specific parsing logic that handles URL detection and job data extraction. These modules are separate from the YAML configuration but are referenced by `scan.mjs` when processing URLs defined in [`portals.yml`](https://github.com/santifer/career-ops/blob/main/portals.yml).